好記性不如爛筆桿弄慰。所以還是有必要給這些都記下來闹蒜,隔段時(shí)間再看的時(shí)候也不至于一片茫然沪蓬。
順帶提一下目前自己閱讀源碼的三種途徑:1.在線閱讀,類似的網(wǎng)站有androidxref等斑胜;2.使用工具如Source Insight 4.0導(dǎo)入源碼進(jìn)行閱讀控淡;3.使用as加載修改過的android.jar包來進(jìn)行閱讀。這三種更喜歡as的方式止潘,函數(shù)的跳轉(zhuǎn)和變量的顏色區(qū)分的最好掺炭,Source Insight可能用的不熟練,總感覺比as差點(diǎn)事覆山,但是Source Insight好處就是占用內(nèi)存資源少竹伸,而網(wǎng)站更適合查找部分代碼,比如各個(gè)版本代碼的不同部分簇宽。
好了勋篓,開始正題。startActivity在最近的幾個(gè)安卓版本中部分代碼做了改動(dòng)魏割,雖然整體還是一樣的架構(gòu)譬嚣,比如;7.0之前是binder來實(shí)現(xiàn)進(jìn)程間通信的钞它,8.0之后改為aidl去實(shí)現(xiàn)了拜银,雖然本質(zhì)上實(shí)現(xiàn)還是binder,aidl只是又做了一層封裝遭垛;又比如9.0在啟動(dòng)activity上與之前的啟動(dòng)方式相比尼桶,由函數(shù)直接調(diào)用改為類似事物的方式去啟動(dòng)了。但是锯仪,整體的架構(gòu)還是一樣的泵督,ams仍然是那個(gè)最重要的中間者,而啟動(dòng)的最后仍然會(huì)回到activityThread中去處理庶喜。
在activity中調(diào)用startActivity小腊,首先會(huì)調(diào)用Activity類中的startActivity方法,以前的老版本這一步是調(diào)用context的startActivity方法久窟;
此方法會(huì)調(diào)用
此處傳入startActivity方法的第二個(gè)參數(shù)為null秩冈,因此我們直接跟進(jìn)else里面的方法startActivityForResult(intent, -1);
在此方法中我們又看到了熟悉的類Instrumentation,在Instrumentation類中調(diào)用了execStartActivity斥扛,需要注意的是這是個(gè)重載方法入问,我們只找我們參數(shù)對(duì)應(yīng)的方法即可,下面是這個(gè)方法的關(guān)鍵代碼
此處開始進(jìn)程切換稀颁。ActivityManager.getService().startActivity這段代碼其實(shí)是跨進(jìn)程調(diào)用了ActivityManagerService里面的方法startActivity队他,關(guān)于ActivityManagerService這個(gè)服務(wù)(以下簡稱AMS)的作用此處不做講解。下面來看下ActivityManager.getService()這個(gè)方法的具體實(shí)現(xiàn)
可以看到getService方式內(nèi)部調(diào)用了IActivityManagerSingleton.get()峻村,IActivityManagerSingleton其實(shí)是一個(gè)泛型單例類麸折,核心實(shí)現(xiàn)是重寫的create方法,此方法內(nèi)部通過調(diào)用ServiceManager.getService(Context.ACTIVITY_SERVICE)得到一個(gè)java層的binder粘昨,ServiceManager是系統(tǒng)Service服務(wù)的管家垢啼,內(nèi)部維護(hù)了一個(gè)map來存儲(chǔ)各個(gè)Service對(duì)象窜锯,ACTIVITY_SERVICE就是AMS在map的key值。IActivityManager.Stub.asInterface(b)這行代碼就屬于aidl的范疇了芭析,asInterface方法據(jù)說內(nèi)部調(diào)用了native方法通過binder驅(qū)動(dòng)锚扎,然后經(jīng)過映射找到另一個(gè)進(jìn)程的binder,然后層層返回馁启,最后到j(luò)ava層驾孔,這樣我們就拿到了可以和另一個(gè)進(jìn)程進(jìn)行通信的鑰匙。
8.0之前這一部分沒有使用aidl惯疙,而是直接使用binder實(shí)現(xiàn)的翠勉,具體的代碼在ActivityManagerNative這個(gè)類里面。替換為binder之后代碼更為精簡了霉颠,便于閱讀对碌,對(duì)于初學(xué)者也更為友好,不用在ActivityManagerNative和代理類之間繞來繞去的蒿偎,而機(jī)器生成的代碼比人寫的代碼也更為安全朽们。
接下來繼續(xù)startActivity的流程,代碼在系統(tǒng)進(jìn)程AMS的startActivity處開始
此處留意第一個(gè)參數(shù)IApplicationThread caller诉位,后續(xù)有用
第二個(gè)startActivityAsUser方法也是和之前不一樣的地方骑脱,obtainStarter方法通過工廠模式生成了一個(gè)ActivityStarter對(duì)象。真正的代碼跑到了ActivityStarter的execute方法里面:
這樣啟動(dòng)activity的主要流程就跑到ActivityStarter類里面了苍糠,接下來看startActivity方法
此方法里面又調(diào)用了一個(gè)startActivity方法叁丧,而這個(gè)startActivity方法代碼就比較多了,主要對(duì)activity啟動(dòng)的權(quán)限和調(diào)用者等做了校驗(yàn)椿息,不關(guān)注這個(gè)直接走到方法底部還是一個(gè)startActivity方法,下面貼上這個(gè)startActivity方法的代碼
startActivityUnchecked方法坷衍,此方法也比較長寝优,主要對(duì)activity的啟動(dòng)模式和activity棧做了處理,onNewIntent就是在這觸發(fā)的
接下來又跳轉(zhuǎn)到了ActivityStackSupervisor的resumeFocusedStackTopActivityLocked方法
ActivityStack類的resumeTopActivityUncheckedLocked方法枫耳,這個(gè)方法也比較長乏矾,只關(guān)注最后面的startSpecificActivityLocked方法
ActivityStackSupervisor類startSpecificActivityLocked方法:
startSpecificActivityLocked方法里面對(duì)是應(yīng)用內(nèi)打開activity還是從桌面打開activity做了判斷,如果從桌面打開activity迁杨,此時(shí)應(yīng)用還沒有主進(jìn)程钻心,就會(huì)調(diào)用mService.startProcessLocked方法創(chuàng)建新的進(jìn)程,然后再走startActivity的流程铅协。此處我們關(guān)注realStartActivityLocked方法捷沸,帶上real就證明離真相很近了。
此處是9.0與8.0最大的區(qū)別狐史,改用事物的方式去啟動(dòng)activity了痒给,接下來看事物的提交scheduleTransaction方法
調(diào)用的是ClientTransaction類的schedule方法说墨,接下來看schedule方法
調(diào)用了mClient對(duì)象的方法,mClient是一個(gè)繼承了IApplicationThread接口的實(shí)現(xiàn)類苍柏,是不是很眼熟尼斧,和前面的caller類型一樣,而IApplicationThread的實(shí)現(xiàn)類是ApplicationThread试吁,ActivityThread的內(nèi)部類
好的棺棵,又調(diào)用了ActivityThread類的scheduleTransaction方法,搜索了一下ActivityThread類里面并沒有這個(gè)方法熄捍,這個(gè)時(shí)候不要慌烛恤,看下ActivityThread的父類ClientTransactionHandler,發(fā)現(xiàn)原來這個(gè)方法在父類里面實(shí)現(xiàn)了
又給ActivityThread發(fā)送了一個(gè)消息治唤,接下來看處理這個(gè)消息的代碼
這個(gè)事務(wù)在這又被mTransactionExecutor的方法execute給執(zhí)行了棒动。。宾添。
接下來看TransactionExecutor類的execute方法
在這個(gè)方法里面主要執(zhí)行了兩個(gè)方法船惨,根據(jù)名字判斷executeLifecycleState可能只是改變狀態(tài)而executeCallbacks方法可能更有料,接下來看executeCallbacks方法的代碼
然后繼續(xù)跟item.execute這行代碼缕陕,可以看到item是ClientTransactionItem類的對(duì)象粱锐,那么這個(gè)對(duì)象在哪被復(fù)制的,回到事務(wù)最初創(chuàng)建的地方扛邑,ActivityStackSupervisor類的realStartActivityLocked方法
可以看到此處的clientTransaction調(diào)用了addCallback方法怜浅,而剛才的executeCallbacks方法中出現(xiàn)了clientTransaction.getCallbacks方法,因此這個(gè)LaunchActivityItem就是item蔬崩,接下來看LaunchActivityItem類中的execute方法
可以看到client.handleLaunchActivity這段代碼就是之前8.0中的代碼恶座,兜兜轉(zhuǎn)轉(zhuǎn)這么久,終于回到了這里沥阳,而這個(gè)client就是前面繼承了ClientTransactionHandler的ActivityThread類跨琳,接下來看handleLaunchActivity代碼的實(shí)現(xiàn)
其中的關(guān)鍵方法performLaunchActivity,其中完成了activity實(shí)例的創(chuàng)建桐罕,Application的實(shí)例化脉让,window的依附等操作,activity的生命周期也開始啟動(dòng)功炮,至此activity的創(chuàng)建就算告一段落了溅潜。