Activity
Activity是一個(gè)應(yīng)用組件,承擔(dān)了主要的與用戶的交互工作咐扭。它需要依賴WindowManagerService來(lái)完成界面顯示和繪制蜕企,它依賴ActivityManagerService來(lái)完成啟動(dòng)過(guò)程劲厌、生命周期的管理以及Activity任務(wù)盞的管理懊渡。
- Activity有兩個(gè)啟動(dòng)方式,顯式啟動(dòng)和隱式啟動(dòng)军拟,兩種方式AMS都是通過(guò)PackageManagerService的
queryIntentActivities
方法獲取對(duì)應(yīng)組件信息剃执,然后再啟動(dòng)對(duì)應(yīng)的Activity - Activity有四種啟動(dòng)模式:
standard
singleTop
singleTask
singleInstance
這四種啟動(dòng)模式的區(qū)別主要是通過(guò)任務(wù)棧完成,Activity在AMS中對(duì)應(yīng)著一條ActivityRecord懈息,而通常情況下一個(gè)應(yīng)用的ActivityRecord都由同一個(gè)TaskRecord(棧型結(jié)構(gòu))管理肾档,所有的TaskRecord又由ActvityStack管理,我們真正意義上的任務(wù)棧指的就是TaskRecord辫继,不同的啟動(dòng)模式則是對(duì)應(yīng)著對(duì)TaskRecord的不同處理怒见。 - 多進(jìn)程啟動(dòng):在manifest的Activity標(biāo)簽配置android:process即可多線程啟動(dòng).
在AMS的startProcessLocked的方法中會(huì)試圖通過(guò)processName和uid獲取已有的進(jìn)程進(jìn)程記錄并在后續(xù)返回,如果對(duì)應(yīng)的Activity為設(shè)置了不同的process姑宽,則此處會(huì)為null遣耍,最終會(huì)通過(guò)調(diào)用Process.start開(kāi)啟一個(gè)新的進(jìn)程
Service
Service是一個(gè)長(zhǎng)期在后臺(tái)執(zhí)行任務(wù)而不提供界面的組件,但是默認(rèn)情況下Service沒(méi)有提供額外線程能力去處理任務(wù)炮车,Service有兩種形式舵变,一種是綁定在類似Activity的用戶可交互的組件上,協(xié)助完成部分后臺(tái)任務(wù)瘦穆,一種是單獨(dú)啟動(dòng)纪隙,完成任務(wù)后自動(dòng)結(jié)束
startService() 啟動(dòng)服務(wù)
和啟動(dòng)Activity類似,都是先通過(guò)通過(guò)AMS已經(jīng)其輔助的ActiveServices來(lái)創(chuàng)建和獲取Service相關(guān)信息扛或,最終通過(guò)ActivityThread來(lái)創(chuàng)建和啟動(dòng)Service
當(dāng)Service已經(jīng)開(kāi)始運(yùn)行之后绵咱,再次startService時(shí)在AvtiveServices的bringUpServiceLocked中通過(guò)判斷Service 的ProcessRecord和對(duì)應(yīng)的IApplicationThread后,直接通過(guò)scheduleServiceArgs最終調(diào)用Service的onStartCommand熙兔,同時(shí)不會(huì)繼續(xù)進(jìn)行后續(xù)的Service創(chuàng)建過(guò)程悲伶,即重復(fù)調(diào)用startService()也只會(huì)調(diào)用一次onCreate。bindService() 綁定服務(wù)
啟動(dòng)過(guò)程類似StartService黔姜,但不同點(diǎn)是在bind后拢切,ServiceConnection回掉方法中會(huì)返回一個(gè)Service的IBinder對(duì)象,用于控制可能在不同進(jìn)程的Service秆吵。
但是這里存在一個(gè)問(wèn)題淮椰,既然時(shí)跨進(jìn)程通信,那Service如何返回這個(gè)IBinder對(duì)象?這里Android創(chuàng)建了LoadedApk.ServiceDispatcher對(duì)象主穗,并把ServiceConnection和它綁定在了一起泻拦,ServiceDispatcher內(nèi)部有一個(gè)Binder也就是InnerConnection上,然后在調(diào)用AMS綁定Service的同時(shí)把InnerConnection對(duì)象也傳遞了過(guò)去
當(dāng)目標(biāo)Service啟動(dòng)會(huì)忽媒,也會(huì)通過(guò)AMS争拐、通過(guò)InnerConnection把Service的Binder傳遞給Dispatcher最終調(diào)用onServiceConnected完成綁定多進(jìn)程
上面已經(jīng)多次提到Service極有可能是另一個(gè)進(jìn)程的Service,所以Service必然是可以多進(jìn)程的晦雨,方法和Activity一樣即可
BroadcastReceiver
Android中用于發(fā)布或者接受消息的一個(gè)組件架曹,類似發(fā)布訂閱模式,這個(gè)是四大組件中唯一可以不在manifest中注冊(cè)的組件(當(dāng)然注冊(cè)也是可以的)闹瞧。BroadcastReceiver主要包括兩個(gè)部分的內(nèi)容绑雄,一個(gè)是廣播接受者的register和廣播的發(fā)射。
注冊(cè)廣播
廣播可以通過(guò)代碼或者manifest進(jìn)行注冊(cè)奥邮,效果是一樣的万牺,只是manifest中的是PMS在解析后自動(dòng)幫我們注冊(cè)的,同時(shí)和Service類似洽腺,廣播也是跨進(jìn)程的脚粟,則必須要由跨進(jìn)程的機(jī)制,所以Android中有LoadedApk.ReceiverDispatcher對(duì)象蘸朋, 是不是和ServiceDispatcher很像核无,其實(shí)效果也是一樣的,這里BroadcastReceiver扮演了和ServiceConnection一樣的角色藕坯,通過(guò)InnerReceiver這樣一個(gè)Binder對(duì)象來(lái)完成進(jìn)程間的通信厕宗。
廣播的注冊(cè)過(guò)程也是由AMS完成的,AMS中會(huì)接受廣播注冊(cè)是傳遞過(guò)來(lái)的InnerReceiver和IntentFilter堕担,同時(shí)在BroadcastIntentLocked方法中把他們保存了下來(lái)已慢,以便后面接收到廣播后去檢索廣播接受者和回掉其方法。
發(fā)射廣播
我們通過(guò)sendBroadcast發(fā)射的廣播最終也是由AMS來(lái)處理的霹购,它會(huì)分別從PMS中檢索出靜態(tài)注冊(cè)的廣播接受者和我們自己動(dòng)態(tài)注冊(cè)保存在AMS中的廣播接受者佑惠。同時(shí)這里會(huì)對(duì)不同的廣播分別處理和不同方式注冊(cè)的廣播分開(kāi)處理:,
- 有序廣播:按照優(yōu)先級(jí)合并廣播接受者齐疙,統(tǒng)一處理
- 普通廣播(無(wú)序廣播):首先處理動(dòng)態(tài)注冊(cè)的廣播膜楷,因?yàn)閙anifest注冊(cè)的廣播接受者可能還沒(méi)有啟動(dòng),需要先啟動(dòng)對(duì)應(yīng)的組件然后在處理廣播
多進(jìn)程啟動(dòng)方式贞奋?和上面的Activity赌厅、Service類似
ContentProvider
Android用于提供結(jié)構(gòu)化數(shù)據(jù)訪問(wèn)以及對(duì)應(yīng)的安全機(jī)制的一個(gè)組件,我們可以把我們的數(shù)據(jù)通過(guò)ContentProvider提供出去轿塔,然后可以使用 ContentResolver通過(guò)uri獲取對(duì)應(yīng)的操作特愿。因此ContentProvider也分為兩個(gè)部分仲墨,數(shù)據(jù)的提供和數(shù)據(jù)的訪問(wèn)
數(shù)據(jù)的提供
使用ContentProvider提供數(shù)據(jù)只需要繼承ContentProvider,然后實(shí)現(xiàn)其方法同時(shí)創(chuàng)建UriMatcher揍障,在manifest中聲明后即可目养。
數(shù)據(jù)的訪問(wèn)
數(shù)據(jù)的訪問(wèn)需要使用ContentResolver通過(guò)指定的Uri獲取,這個(gè)過(guò)程也是一個(gè)潛在的跨進(jìn)程行為,這個(gè)過(guò)程中如果目標(biāo)的ContentProvider還未啟動(dòng)則會(huì)先通過(guò)AMS先啟動(dòng)目標(biāo)組件毒嫡,而后通過(guò)數(shù)據(jù)共享模型進(jìn)行數(shù)據(jù)獲取癌蚁。
多進(jìn)程啟動(dòng)方式?和上面的Activity兜畸、Service類似
總結(jié)
本想對(duì)四大組件做一個(gè)相對(duì)深入的介紹努释,但是奈何前期積累不足,加上時(shí)間比較緊張咬摇,只能作出個(gè)一個(gè)不倫不類的東西洽洁,特別是ContentProvider遠(yuǎn)比想象中復(fù)雜的多,希望后期能有時(shí)間對(duì)四大組件做一個(gè)更加全面深入的了解