深入Android 【四】 —— 組件調用

轉載自http://www.cnblogs.com/duguguiyu/archive/2010/02/07/1665544.html

Intent解析

基于組件的架構體系契吉,除了有定義良好的組件,如何把這些組件組裝在一起拇颅,也是一門藝術彰檬。在Android中伸刃,Intent(貌似通常譯作:意圖...)谎砾,就是連接各組件的橋梁。

前段時間看同事們做Symbian平臺的網(wǎng)易掌上郵(真的是做的用心捧颅,NB的一米景图,熱情歡迎所有163郵箱的S60v3用戶,猛點擊之...)碉哑,有個功能是為郵件添加附件挚币,比如你想要通過郵件發(fā)送一副圖片泡mm,可能需要有個很直觀的方式從本地選一副珍藏美圖扣典,抑或是拿相機來個完美自拍忘晤。在Symbian中,這樣的功能激捏,都需要你用底層的API设塔,自己一點點寫。為了讓選圖片體驗更好远舅,可能需要做一個類似于圖片瀏覽器之類的東西闰蛔,為了把拍照做的更為順暢,甚至需要實現(xiàn)從聚焦到調節(jié)亮度之類一整套的相機功能图柏。

而其實呢序六,用戶的手機中可能本身就裝了其他的專業(yè)圖片瀏覽器、相機等應用蚤吹,這些應用已經(jīng)非常出色好用抹缕,而用戶也已然能很純屬使用它們,如果能進行調用尽楔,對郵箱的開發(fā)者和用戶而言盹靴,都會是個更好的選擇。但在Symbian這樣殘敗的系統(tǒng)里二驰,應用和應用之間的結合能力奇弱無比扔罪,想復用,基本比登天還難桶雀,作為開發(fā)者矿酵,只能忍住一次又一次的惡心,為了用戶矗积,做這些重復造輪子吃力不討好的附加工作全肮。

還好還好,在Android中棘捣,一切變得美好多了辜腺,它將開發(fā)者從接口和對象的細節(jié)中解救出來,讓我們有更多精力投入到核心功能的開發(fā)中去。在Android中哪自,如果你需要選個圖拍個片丰包,只需要構造一個描述你此項意愿的Intent,發(fā)送出去壤巷,系統(tǒng)會幫你選擇一個能夠處理該項業(yè)務的組件來滿足你的需求邑彪,而不再需要糾結在具體的接口和實現(xiàn)上,Perfect World胧华,便應如此寄症。

Intent構成

Intent被譯作意圖,其實還是很能傳神的矩动,Intent期望做到的有巧,就是把實現(xiàn)者和調用者完全解耦,調用者專心將意圖描述清晰悲没,發(fā)送出去篮迎,就可以夢想成真,達到目的示姿。當然甜橱,這么說太虛了,庖丁解牛栈戳,什么東西切開來看看岂傲,也許就清晰了。Intentreference/android/content/Intent.html)子檀,在Android中表現(xiàn)成一個類镊掖,發(fā)起一個意圖,你需要構造這樣一個對象褂痰,并為下列幾項中的一些進行賦值:

  1. Action亩进。當日常生活中,描述一個意愿或愿望的時候脐恩,總是有一個動詞在其中镐侯。比如:我想三個俯臥撐侦讨;我要一部x片驶冒;我要一部血淚史,之類云云韵卤。在Intent中骗污,Action就是描述看、做沈条、寫等動作的需忿,當你指明了一個Action,執(zhí)行者就會依照這個動作的指示,接受相關輸入屋厘,表現(xiàn)對應行為涕烧,產(chǎn)生符合的輸出。在Intent類中汗洒,定義了一批量的動作议纯,比如ACTION_VIEWACTION_PICK溢谤,之類的瞻凤,基本涵蓋了常用動作,整一個降龍十八掌全集世杀。當然阀参,你也可以與時俱進,創(chuàng)造新的動作瞻坝,比如lou這樣的蛛壳。與系統(tǒng)預定義的相比,這些自定義動作的流通范圍很是有限所刀,除非做了非常NB的應用炕吸,大家都需要follow你,否則通常都是應用內部流通勉痴。

  2. Data赫模。當然,光有動作還是不夠的蒸矛,還需要有更確切的對象信息瀑罗。比如,同樣是這個動作雏掠,但泡咖啡斩祭,和泡妞,就差之千里了乡话。Data的描述摧玫,在Android中,表現(xiàn)成為一個URI绑青。用在內部通信中诬像,可能描述是Content Provider用的形如content://xxxx這樣的東東,抑或是外部的一個形如tel://xxxx這樣的鏈接闸婴』的樱總而言之,是能夠清楚準確的描述一個數(shù)據(jù)地址的uri邪乍。

  3. Type降狠。說了Data对竣,就必須要提Type,很多時候榜配,會有人誤解否纬,覺著Data和Type的差別,就猶如泡妞泡馬子之間的差別一樣蛋褥,微乎其微烦味。但其實不然,Type信息壁拉,是用MIME來表示的谬俄,比如text/plain,這樣的東西弃理。說到這里溃论,兩者差別就很清晰了,Data就是門牌號痘昌,指明了具體的位置钥勋,具體問題具體分析,而type辆苔,則是強調物以類聚算灸,解決一批量的問題。實際的例子是這樣的驻啤,比如菲驴,從某個應用撥打一個電話,會發(fā)起的是action為ACTION_DIAL且data為tel:xxx這樣的Intent骑冗,對應的人類語言就是撥打xxx的電話赊瞬,很具象。而如果使用type贼涩,就寬泛了許多巧涧,比如瀏覽器收到一個未知的MIME類型的數(shù)據(jù)(比如一個視頻...),就會放出這樣的Intent遥倦,求系統(tǒng)的其他應用來幫助谤绳,表達成自然語言應該就是:查看pdf類文檔,這樣的袒哥。

  4. Category缩筛。通過Action,配合Data或Type统诺,很多時候可以準確的表達出一個完整的意圖了歪脏,但也會有些時候,還需要加一些約束在里面才能夠更精準粮呢。比如,如果你雖然很喜歡做俯臥撐,但一次做三個還只是在特殊的時候才會發(fā)生啄寡,那么你可能表達說:每次吃撐了的時候豪硅,我都想做三個俯臥撐。吃撐了挺物,這就對應著Intent的Category的范疇懒浮,它給所發(fā)生的意圖附加一個約束。在Android中识藤,一個實例是砚著,所有應用主Activity(就是單獨啟動時候,第一個運行的那個Activity...)痴昧,都需要能夠接受一個Category為CATEGORY_LAUNCHER稽穆,Action為ACTION_Main的意圖。

  5. Component赶撰。在此之前舌镶,我們企圖用Action,Data/Type豪娜,Category去描述一個意圖餐胀,這是Android推薦,并期望大家在大多數(shù)時候使用的瘤载,這樣模式在Android中稱做Implicit Intents否灾,通過這種模式,提供一種靈活可擴展的模式鸣奔,給用戶和第三方應用一個選擇權坟冲。比如,還是一個郵箱軟件溃蔫,他大部分功能都好健提,就是選擇圖片的功能做的很土,怎么辦伟叛?如果它采用的是Implicit Intents私痹,那么它就是一個開放的體系了,手機中沒有其他圖片選擇程序的話统刮,可以繼續(xù)使用郵箱默認的紊遵,如果有,你可以任意選擇來替代原有模塊完整這功能侥蒙,一切都自然而然暗膜。但這種模式,也不是沒有成本鞭衩,需要付出的是一些性能上的開銷学搜,因為畢竟有一個檢索過程娃善。于是,Android提供了另一種模式瑞佩,叫做Explicit Intents聚磺,就需要Component的幫助了。Component就是類名炬丸,完整的瘫寝,形如com.xxxxx.xxxx,一旦指明了稠炬,一切都清晰了焕阿,找的到這個類(當然會是一個特定的子類...),成功首启,反之暮屡,失敗。這個好處闽坡,自然是速度栽惶,適合在你明確知道這就是一個內部模塊的時候,使用它疾嗅。

  6. Extras外厂。通過上面的這些項,識別問題代承,基本完美解決了汁蝶,剩下一個重要的問題,就是傳參论悴。Extras是用來做這個事情的掖棉,它是一個Bundle類的對象,有一組可序列化的key/value對組成膀估。每一個Action幔亥,都會有與之對應的key和value類型約定,發(fā)起Intent的時候察纯,需要按照要求把Data不能表示的額外參數(shù)放入Extras中(當然帕棉,如果不需要額外附加參數(shù),就算了...)饼记,否則執(zhí)行者拿到的時候會抓狂的香伴。

  7. Flags。能識別具则,有輸入即纲,整個Intent基本就完整了,但還有一些附件的指令博肋,需要放在Flags中帶過去低斋。顧名思義蜂厅,F(xiàn)lags是一個整形數(shù),有一些列的標志位構成拔稳,這些標志葛峻,是用來指明運行模式的锹雏。比如巴比,你期望這個意圖的執(zhí)行者,和你運行在兩個完全不同的任務中(或說進程也無妨吧...)礁遵,就需要設置FLAG_ACTIVITY_NEW_TASK的標志位轻绞。

有了上述這些,一個Intent的形象就躍然紙上了佣耐,如此豐富的內容政勃,決定了它比傳統(tǒng)的模式,都來得強大兼砖。

Intent匹配

上次在moto dev上奸远,聽人做Android的講座,下面有很多聽客都對Intent這個概念表示出了強烈的興趣讽挟,拿出自己熟悉領域的各類概念進行類比懒叛,比如事件、消息之類耽梅。當時我在想薛窥,Intent作為組件間的通信協(xié)定,與一般的簡單的通信方式不同眼姐,首先诅迷,從前面部分可以看到,它的描述是針對需求而不是實現(xiàn)者來進行的众旗。其次罢杉,它的解析是依托第三方而不是兩方直接進行。

這個概念和設計模式中的中介模式(Mediator Pattern)是一脈的贡歧,即所有的外圍組件滩租,都只和系統(tǒng)的核心模塊發(fā)生聯(lián)系,通過它進行中轉艘款,組件之間不直接勾搭持际。

如上圖所示,要想跑通整個流程哗咆,另一個很重要的東西蜘欲,就是Intent Filters,它是用來描述一個Activity或Serveice等組件晌柬,期望能夠響應怎么樣的Intent姥份。如果一個組件郭脂,只希望別的組件通過Explicit Intents(就是指明Component...)的方式來找到它,那么就不需要添加Intent Filters澈歉,反之展鸡,一定需要一個或若干個Intent Filters。Intent Filter的各個項埃难,猶如Intent照鏡子過來的效果莹弊,包括Action,Catagory涡尘,Data忍弛,Type等。Intent Filters可以寫到配置文件中考抄,和那些組件的配置一起(不記得什么是配置文件了细疚,可以看這里...),若干的實例可以在Intent介紹頁面上找到(reference/android/content/Intent.html)川梅。同樣疯兼,Intent Filters可以在代碼中,動態(tài)插拔贫途,這個是和動態(tài)插拔的Broadcast Receiver是配套使用的吧彪。
系統(tǒng)核心的模塊,會負責收集這些Intent Filters潮饱,和它們對應的組件信息来氧。當請求者需要一個組件幫忙,并構造了描述它需求的Intent發(fā)送到系統(tǒng)核心香拉,系統(tǒng)核心會將其與已知的各個Intent Filters進行匹配啦扬,挑選一個符合需求的組件返回。如果有多個符合的凫碌,會嘗試看看有沒有默認執(zhí)行的扑毡,如果沒有默認的,就會構造UI盛险,讓用戶幫助抉擇瞄摊,如是,整個流程就跑通了苦掘。

Intent實現(xiàn)

上圖换帜,是請求一個Activity組件的簡單實現(xiàn)流程圖,算是用的最多的Intent解析實例鹤啡。流程從調用Context.startActivity(Intent)開始惯驼,調用者傳入構造好的Intent對象,然后流程會讓實際的執(zhí)行者,是Instrumentation對象來完成祟牲。它是整個應用激活的Activity管理者隙畜,集中負責該應用內所有Activity的起承轉合生離死別。它有一個隱藏的方法execStartActivity方法说贝,就是負責根據(jù)Intent啟動Activity的议惰。去掉一些細節(jié),它做得最重要的事情乡恕,就是將此調用言询,通過RPC的方式,傳遞到ActivityManagerService几颜。前面一直再說倍试,系統(tǒng)核心層讯屈,其實這里所謂的系統(tǒng)核心層蛋哭,就是負責Android一些關鍵事務的一組服務。它們同樣運行在虛擬機上涮母,和普通的Service實現(xiàn)機理是一致的谆趾,只不過它們不拋頭露臉只是默默的在下層服務,故謂之核心嘛叛本。AcitivityManagerService沪蓬,是負責Activity調度的服務,也許日后提及調度細節(jié)的時候還會有涉及来候。在這里跷叉,AcitivityManagerService會分兩個步驟完成相關操作,首先把Intent遞交給另一個服務PackageManagerService营搅,此服務掌握整個軟件包及其各組件的信息云挟,它會將傳遞過來的Intent,與已知的所有Intent Filters進行匹配(如果帶有Component信息转质,就不用比了...)园欣,找到了,就把相關Component的信息通知回AcitivityManagerService休蟹,在這里沸枯,會完成啟動Activity這個很多細節(jié)的事情。

由此可知赂弓,啟動Activity绑榴,要經(jīng)過多個服務的處理,并不是非常輕量的過程盈魁,在Android隨機文檔介紹性能的一節(jié)中翔怎,對此有一個評估。但這樣的操作不是會放在循環(huán)里反復折磨的那種备埃,因此整體效果與其付出的性能代價相比姓惑,覺得是物超所值的褐奴。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市于毙,隨后出現(xiàn)的幾起案子敦冬,更是在濱河造成了極大的恐慌,老刑警劉巖唯沮,帶你破解...
    沈念sama閱讀 216,692評論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件脖旱,死亡現(xiàn)場離奇詭異,居然都是意外死亡介蛉,警方通過查閱死者的電腦和手機萌庆,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,482評論 3 392
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來币旧,“玉大人践险,你說我怎么就攤上這事〈盗猓” “怎么了巍虫?”我有些...
    開封第一講書人閱讀 162,995評論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長鳍刷。 經(jīng)常有香客問我占遥,道長,這世上最難降的妖魔是什么输瓜? 我笑而不...
    開封第一講書人閱讀 58,223評論 1 292
  • 正文 為了忘掉前任瓦胎,我火速辦了婚禮,結果婚禮上尤揣,老公的妹妹穿的比我還像新娘搔啊。我一直安慰自己,他們只是感情好芹缔,可當我...
    茶點故事閱讀 67,245評論 6 388
  • 文/花漫 我一把揭開白布坯癣。 她就那樣靜靜地躺著,像睡著了一般最欠。 火紅的嫁衣襯著肌膚如雪示罗。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,208評論 1 299
  • 那天芝硬,我揣著相機與錄音蚜点,去河邊找鬼。 笑死拌阴,一個胖子當著我的面吹牛绍绘,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 40,091評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼陪拘,長吁一口氣:“原來是場噩夢啊……” “哼厂镇!你這毒婦竟也來了?” 一聲冷哼從身側響起左刽,我...
    開封第一講書人閱讀 38,929評論 0 274
  • 序言:老撾萬榮一對情侶失蹤捺信,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后欠痴,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體迄靠,經(jīng)...
    沈念sama閱讀 45,346評論 1 311
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 37,570評論 2 333
  • 正文 我和宋清朗相戀三年喇辽,在試婚紗的時候發(fā)現(xiàn)自己被綠了掌挚。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,739評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡菩咨,死狀恐怖吠式,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情旦委,我是刑警寧澤奇徒,帶...
    沈念sama閱讀 35,437評論 5 344
  • 正文 年R本政府宣布,位于F島的核電站缨硝,受9級特大地震影響,放射性物質發(fā)生泄漏罢低。R本人自食惡果不足惜查辩,卻給世界環(huán)境...
    茶點故事閱讀 41,037評論 3 326
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望网持。 院中可真熱鬧宜岛,春花似錦、人聲如沸功舀。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,677評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽辟汰。三九已至列敲,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間帖汞,已是汗流浹背戴而。 一陣腳步聲響...
    開封第一講書人閱讀 32,833評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留翩蘸,地道東北人所意。 一個月前我還...
    沈念sama閱讀 47,760評論 2 369
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親扶踊。 傳聞我的和親對象是個殘疾皇子泄鹏,可洞房花燭夜當晚...
    茶點故事閱讀 44,647評論 2 354

推薦閱讀更多精彩內容