在 Android 中,打開一個 Activity ,有多少種方式?不過無論是使用什麼方式,最終都沒辦法逃避建立一個 Intent ,而後startActivity()
。程序員
那麼,若是想根據數據來肯定跳轉的頁面呢?後端
須要怎麼作比較好一點。DeepLink 好像是一個不錯的解決方案,在 AndroidManifest.xml 中,定義好 data 字段,標記好 scheme 、 host 等等,而後按照規則進行傳遞,這樣也能夠跳轉到某些頁面。服務器
可是,這樣真的方便嗎?學習
咱們須要在每一個須要跳轉的 Activity 上,設定好data?固然,如今 Github 上也有一些成熟的 Deeplink 的解決方案,只須要在爲某個 Activity 設定 data ,而後全部 deeplink 的連接都跳轉到這個 Activity 上,最後再由這個RouterActivity,去決定向那裏跳轉,並攜帶上參數。3d
那麼還有別的方案嗎?code
直到我發現 Intent 竟然有個 toUri()
的方法,我就以爲有辦法對 Intent 進行簡單的序列化了。cdn
從文檔中能夠看出,toUri()
方法能夠將一個 Intent 轉換成一個 URI ,其中包含了 action、categories、flags 等一些必要的參數。xml
那麼文章開頭的地方,那麼 startActivity ,最終轉換成 URI ,是什麼呢?對象
仔細看,flag、compoent、putExtra 的數據,都被序列化成一個字符串了。blog
獲得的這個 Uri ,如何使用呢?能夠藉助 Intent 的一個靜態方法,parseUri()
將一個 Intent 的 URI ,轉換成實際的 Intent 對象。
這樣的話,其實下面的方式,一樣也會調起TwoActivity,而且帶過去一個 balabala 的 ID 數據。
到這裏,基本上把本篇文章須要講解的內容都講明白了。可是有追求的程序員,咱們仍是要深挖一下,toUri()
到底幹了些什麼?
來看看 toUri()
的具體實現。
從源碼的實現看,其實 toUri()
只是把每一個字段讀取出來,而後按照規則進行序列化,最後 parseUri()
只是按照這個規則進行了反序列化。熟練的話,基本上無需使用 toUri()
這個方法轉換,就能夠盲寫 Intent 的 URI。
咱們使用的 API 都是官方對 Intent 提供的,用起來好像也確實沒有什麼問題。可是真的像看上去那麼美好嗎?
從傳遞參數的方向看,toUriInner()
方法是toUri()
方法中,對傳遞的數據進行序列化的方法。下面看看具體實現。
能夠看到, toUriInner()
方法,它對基本的數據類型,都有對應的類型進行轉換,例如以前S.id=balabala 表示一個 key 爲 id 的 String 類型的值 balabala 。
好像已經涵蓋了全部的類型傳參了,但是並非這麼美好。發現沒有,沒有關於 Bundle 的參數傳遞,難道是看漏了嗎?
代碼也不看了,作個試驗驗證一下。
看看 Log 輸出:
能夠看到,toUri()
這個方法,確實對 Bundle 參數的序列化並無作特殊處理。
獲得的結論,就是雖然 toUri()
和 parseUri()
方法確實很好用,可是也是有缺陷的,Bundle 傳遞的數據無法序列化成 Uri。
實際使用中,就須要咱們對傳遞的參數有嚴格的要求,避免使用 Bundle 去傳遞數據,固然咱們也能夠本身去是實現序列化和反序列化 Bundle 的邏輯。
這樣就能夠簡單的對 Intent 進行傳遞,能夠從後端服務器拿到一個 IntentUri ,這樣就無需給每一個點擊設定好既定的打開頁面了。固然,怎麼用仍是要看實際的使用場景了。
今天在承香墨影公衆號的後臺,回覆『成長』。我會送你一些我整理的學習資料。
點贊或者分享吧~