Intent 解析

l_serein發表於2013-04-24
基於元件的架構體系,除了有定義良好的元件,如何把這些元件組裝在一起,也是一門藝術。在Android中,Intent (貌似通常譯作:意圖 ...),就是連線各元件的橋樑。
前段時間看同事們做Symbian平臺的網易掌上郵 (真 的是做的用心,NB的一米,熱情歡迎所有163郵箱的S60v3使用者,猛點選之...),有個功能是為郵件新增附件,比如你想要通過郵件傳送一副圖片泡 mm,可能需要有個很直觀的方式從本地選一副珍藏美圖,抑或是拿相機來個完美自拍。在Symbian中,這樣的功能,都需要你用底層的API,自己一點點 寫。為了讓選圖片體驗更好,可能需要做一個類似於圖片瀏覽器之類的東西,為了把拍照做的更為順暢,甚至需要實現從聚焦到調節亮度之類一整套的相機功能。
而其實呢,使用者的手機中可能本身就裝了其他的專 業圖片瀏覽器、相機等應用,這些應用已經非常出色好用,而使用者也已然能很純屬使用它們,如果能進行呼叫,對郵箱的開發者和使用者而言,都會是個更好的選擇。 但在Symbian這樣殘敗的系統裡,應用和應用之間的結合能力奇弱無比,想複用,基本比登天還難,作為開發者,只能忍住一次又一次的噁心,為了使用者,做 這些重複造輪子吃力不討好的附加工作。
還好還好,在Android中,一切變得美好多 了,它將開發者從介面和物件的細節中解救出來,讓我們有更多精力投入到核心功能的開發中去。在Android中,如果你需要選個圖拍個片,只需要構造一個 描述你此項意願的Intent,傳送出去,系統會幫你選擇一個能夠處理該項業務的元件來滿足你的需求,而不再需要糾結在具體的介面和實現 上,Perfect World,便應如此。

Intent構成

Intent被譯作意圖,其實還是很能傳神的,Intent期望做到的,就是把實現者和呼叫者完全解耦,呼叫者專心將以意圖描述清晰,傳送出去,就可以夢想成真,達到目的。
當然,這麼說太虛了,庖丁解牛,什麼東西切開來看看,也許就清晰了。Intentreference/android/content/Intent.html ),在Android中表現成一個類,發起一個意圖,你需要構造這樣一個物件,併為下列幾項中的一些進行賦值:

  1. Action 。當日常生活中,描述一個意願或願望的時候,總是有一個動詞在其中。比如:我想 三個俯臥撐;我要 一部x片;我要 一部血淚史,之類云云。在Intent中,Action就是描述看、做、寫等動作的,當你指明瞭一個Action,執行者就會依照這個動作的指示,接受相關輸入,表現對應行為,產生符合的輸出。在Intent類中,定義了一批量的動作,比如ACTION_VIEW ,ACTION_PICK ,之類的,基本涵蓋了常用動作,整一個降龍十八掌全集。當然,你也可以與時俱進,創造新的動作,比如lou這樣的。與系統預定義的相比,這些自定義動作的流通範圍很是有限,除非做了非常NB的應用,大家都需要follow你,否則通常都是應用內部流通。
  2. Data 。當然,光有動作還是不夠的,還需要有更確切的物件資訊。比如,同樣是 這個動作,但泡咖啡 ,和泡妞 ,就差之千里了。Data的描述,在Android中,表現成為一個URI 。用在內部通訊中,可能描述是Content Provider用的形如content://xxxx 這樣的東東,抑或是外部的一個形如tel://xxxx 這樣的連結。總而言之,是能夠清楚準確的描述一個資料地址的uri。
  3. Type 。說了 Data,就必須要提Type,很多時候,會有人誤解,覺著Data和Type的差別,就猶如泡妞 和泡馬子 之間的差別一樣,微乎其微。但其實不然,Type資訊,是用MIME 來表示的,比如text/plain , 這樣的東西。說到這裡,兩者差別就很清晰了,Data就是門牌號,指明瞭具體的位置,具體問題具體分析,而type,則是強調物以類聚,解決一批量的問 題。實際的例子是這樣的,比如,從某個應用撥打一個電話,會發起的是action為ACTION_DIAL且data為tel:xxx這樣的 Intent,對應的人類語言就是撥打xxx的電話 ,很具象。而如果使用type,就寬泛了許多,比如瀏覽器收到一個未知的MIME型別的資料(比如一個視訊...),就會放出這樣的Intent,求系統的其他應用來幫助,表達成自然語言應該就是:檢視 pdf類文件 ,這樣的。
  4. Category 。通過Action,配合Data或Type,很多時候可以準確的表達出一個完整的意圖了,但也會有些時候,還需要加一些約束在裡面才能夠更精準。比如,如果你雖然很喜歡做俯臥撐,但一次做三個還只是在特殊的時候才會發生,那麼你可能表達說:每次吃撐了的時候 , 我都想做三個俯臥撐。吃撐了,這就對應著Intent的Category的範疇,它給所發生的意圖附加一個約束。在Android中,一個例項是,所有應 用主Activity(就是單獨啟動時候,第一個執行的那個Activity...),都需要能夠接受一個Category為 CATEGORY_LAUNCHER,Action為ACTION_Main的意圖。
  5. Component 。在此之前,我們企圖用Action,Data/Type,Category去描述一個意圖,這是Android推薦,並期望大家在大多數時候使用的,這樣模式在Android中稱做Implicit Intents , 通過這種模式,提供一種靈活可擴充套件的模式,給使用者和第三方應用一個選擇權。比如,還是一個郵箱軟體,他大部分功能都好,就是選擇圖片的功能做的很土,怎麼 辦?如果它採用的是Implicit Intents,那麼它就是一個開放的體系了,手機中沒有其他圖片選擇程式的話,可以繼續使用郵箱預設的,如果有,你可以任意選擇來替代原有模組完整這功 能,一切都自然而然。但這種模式,也不是沒有成本,需要付出的是一些效能上的開銷,因為畢竟有一個檢索過程。於是,Android提供了另一種模式,叫做Explicit Intents ,就需要Component的幫助了。Component就是類名 ,完整的,形如com.xxxxx.xxxx ,一旦指明瞭,一切都清晰了,找的到這個類(當然會是一個特定的子類...),成功,反之,失敗。這個好處,自然是速度,適合在你明確知道這就是一個內部模組的時候,使用它。
  6. Extras 。通過上面的這些項,識別問題,基本完美解決了,剩下一個重要的問題,就是傳參。Extras是用來做這個事情的,它是一個Bundle 類的物件,有一組可序列化的key/value對 組成。每一個Action,都會有與之對應的key和value型別約定,發起Intent的時候,需要按照要求把Data不能表示的額外引數放入Extras中(當然,如果不需要額外附加引數,就算了...),否則執行者拿到的時候會抓狂的。
  7. Flags 。 能識別,有輸入,整個Intent基本就完整了,但還有一些附件的指令,需要放在Flags中帶過去。顧名思義,Flags是一個整形數,有一些列的標誌 位構成,這些標誌,是用來指明執行模式的。比如,你期望這個意圖的執行者,和你執行在兩個完全不同的任務中(或說程式也無妨吧...),就需要設定FLAG_ACTIVITY_NEW_TASK 的標誌位。

有了上述這些,一個Intent的形象就躍然紙上了,如此豐富的內容,決定了它比傳統的模式,都來得強大。

相關文章