將 Intent 序列化,像 Uri 一樣傳遞 Intent!!!


tips

一、真的需要new一個Intent嗎?

在 Android 中,打開一個 Activity ,有多少種方式?不過不管是使用什么方式,最終都沒辦法逃避創建一個 Intent ,然后startActivity()

startActivity

那么,如果想根據數據來確定跳轉的頁面呢?

需要怎么做比較好一點。DeepLink 好像是一個不錯的解決方案,在 AndroidManifest.xml 中,定義好 data 字段,標記好 scheme 、 host 等等,然后按照規則進行傳遞,這樣也可以跳轉到某些頁面。

Deeplink

但是,這樣真的方便嗎?

我們需要在每個需要跳轉的 Activity 上,設定好data?當然,現在 Github 上也有一些成熟的 Deeplink 的解決方案,只需要在為某個 Activity 設定 data ,然后所有 deeplink 的鏈接都跳轉到這個 Activity 上,最后再由這個RouterActivity,去決定向那里跳轉,並攜帶上參數。

那么還有別的方案嗎?

二、Intent的toUri()

直到我發現 Intent 居然有個 toUri() 的方法,我就覺得有辦法對 Intent 進行簡單的序列化了。

method

從文檔中可以看出,toUri() 方法可以將一個 Intent 轉換成一個 URI ,其中包含了 action、categories、flags 等一些必要的參數。

那么文章開頭的地方,那么 startActivity ,最終轉換成 URI ,是什么呢?

uri_string

仔細看,flag、compoent、putExtra 的數據,都被序列化成一個字符串了。

得到的這個 Uri ,如何使用呢?可以借助 Intent 的一個靜態方法,parseUri() 將一個 Intent 的 URI ,轉換成實際的 Intent 對象。

parseUri

這樣的話,其實下面的方式,同樣也會調起TwoActivity,並且帶過去一個 balabala 的 ID 數據。

start_uri

到這里,基本上把本篇文章需要講解的內容都講明白了。但是有追求的程序員,我們還是要深挖一下,toUri() 到底干了些什么?

三、toUri()到底干了什么?

來看看 toUri() 的具體實現。

to_uri_shixian

從源碼的實現看,其實 toUri() 只是把每個字段讀取出來,然后按照規則進行序列化,最后 parseUri() 只是按照這個規則進行了反序列化。熟練的話,基本上無需使用 toUri() 這個方法轉換,就可以盲寫 Intent 的 URI。

四、會有什么隱患嗎?

我們使用的 API 都是官方對 Intent 提供的,用起來好像也確實沒有什么問題。但是真的像看上去那么美好嗎?

從傳遞參數的方向看,toUriInner() 方法是toUri() 方法中,對傳遞的數據進行序列化的方法。下面看看具體實現。

toUriInner

可以看到, toUriInner() 方法,它對基本的數據類型,都有對應的類型進行轉換,例如之前S.id=balabala 表示一個 key 為 id 的 String 類型的值 balabala 。

好像已經涵蓋了所有的類型傳參了,可是並不是這么美好。發現沒有,沒有關於 Bundle 的參數傳遞,難道是看漏了嗎?

代碼也不看了,做個試驗驗證一下。

start_bundler3

看看 Log 輸出:

uri_string2

可以看到,toUri() 這個方法,確實對 Bundle 參數的序列化並沒有做特殊處理。

得到的結論,就是雖然 toUri()parseUri() 方法確實很好用,但是也是有缺陷的,Bundle 傳遞的數據沒法序列化成 Uri。

實際使用中,就需要我們對傳遞的參數有嚴格的要求,避免使用 Bundle 去傳遞數據,當然我們也可以自己去是實現序列化和反序列化 Bundle 的邏輯。

五、結語

這樣就可以簡單的對 Intent 進行傳遞,可以從后端服務器拿到一個 IntentUri ,這樣就無需給每個點擊設定好既定的打開頁面了。當然,怎么用還是要看實際的使用場景了。

今天在承香墨影公眾號的后台,回復『成長』。我會送你一些我整理的學習資料。

點贊或者分享吧~


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM