- Application啟動(dòng)流程框架分析
啟動(dòng)方式一:通過Launcher啟動(dòng)app
啟動(dòng)方式二:在某一個(gè)app里啟動(dòng)第二個(gè)app的Activity.
以上兩種方式均可觸發(fā)app進(jìn)程的啟動(dòng)。但無論哪種方式,最終通過通過調(diào)用AMS的startActivity()來啟動(dòng)application的。
??
根據(jù)上圖分析, 要啟動(dòng)一個(gè)Application,需要涉及五個(gè)進(jìn)程,Launcher進(jìn)程,SystemServer進(jìn)程,Zygote進(jìn)程,和要啟動(dòng)的目標(biāo)Application進(jìn)程,最后還有一個(gè)ServiceManager進(jìn)程。通過Launcher進(jìn)程是無法直接啟動(dòng)app的,因?yàn)閱?dòng)是通過AMS或ATMS完成的。
所以第一步,Launcher必須要拿到AMS的Binder,而AMS的Binder(如上圖左側(cè))在Launcher中的代理則是ActivityManagerProxy,它是Launcher從ServiceManager中查詢獲取而得到的,然后基于這個(gè)代理,向SystemServer進(jìn)程中的AMS去請(qǐng)求startActivity().
這個(gè)過程是通過ActivityManagerProxy這個(gè)Binder遠(yuǎn)程調(diào)用了AMS的服務(wù),讓AMS去startActivity. 但是AMS在啟動(dòng)之前肯定要先判斷一下這個(gè)Activity對(duì)應(yīng)的Application進(jìn)程是否已經(jīng)存在。如果進(jìn)程存在, 直接走上面的第五步,這一步的處理過程也是跨進(jìn)程通信的,通過獲取APP進(jìn)程在AMS中的客戶端代理即ApplicationThreadProxy, 通過這個(gè)代理Binder遠(yuǎn)程調(diào)用app進(jìn)程的scheduleLauncherActivity()方法直接啟動(dòng)進(jìn)程中的Activity,這個(gè)流程是基于APP進(jìn)程已經(jīng)存在了,所以走的是第5和6步分支。
但是現(xiàn)在要討論的是APP進(jìn)程不存在的時(shí)候,這個(gè)APP的啟動(dòng)流程,這種啟動(dòng)方式會(huì)覆蓋所有app的啟動(dòng)流程。所以AMS當(dāng)發(fā)現(xiàn)進(jìn)程不存在時(shí),它首先會(huì)走第2步,向Zygote進(jìn)程發(fā)送創(chuàng)建進(jìn)程的請(qǐng)求,這一步采用的是socket通信方式來操作的,zygote收到socket指令后,是通過調(diào)用fork()的方式來啟動(dòng)復(fù)制創(chuàng)建一個(gè)application進(jìn)程的,這個(gè)就是第三步。一旦這個(gè)Application被創(chuàng)建,它不會(huì)立刻運(yùn)行,因?yàn)樗怯葾MS來負(fù)責(zé)的,所以它會(huì)先將自身的Binder代理對(duì)象發(fā)給AMS,這個(gè)是第四步,它是利用ActivityManager在Application的Binder對(duì)象ActivityManagerProxy來遠(yuǎn)程調(diào)用其attach_application()方法來傳遞自身Binder。這樣AMS也就保存了這個(gè)Application的Binder對(duì)象,
然后才是走第5步,在第5步中如上面的分析(app進(jìn)程已經(jīng)存在的情況下),利用Application在AMS的Binder代理即ApplicationThreadProxy進(jìn)行啟動(dòng),最后執(zhí)行到第8步,調(diào)用Activity.onCreate方法。
- Application進(jìn)程啟動(dòng)流程代碼分析
?現(xiàn)在來分析App進(jìn)程的啟動(dòng)流程,這邊分兩塊,一個(gè)是Application的啟動(dòng)流程,一個(gè)是Activity的啟動(dòng),Application的啟動(dòng)是通過Zygote fork()創(chuàng)建啟動(dòng)的,所以它的啟動(dòng)只有一次,但是Activity的啟動(dòng)可以是多次,而且有不同的啟動(dòng)方式,比如通過Launcher啟動(dòng),通過進(jìn)程內(nèi)的ActivityA->AcitityB,或由其它另外一個(gè)進(jìn)程來啟動(dòng)這個(gè)進(jìn)程的Activity,等等。因此我們這邊分析的是最全的覆蓋最大的Activity啟動(dòng)方法,其它啟動(dòng)方式基本類似,按此作為參考。
Application進(jìn)程的啟動(dòng):
進(jìn)程的啟動(dòng)來自AMS或ATMS代碼,由它們觸發(fā),但是先拋開Activity前面的啟動(dòng)代碼,所以我們從上圖中右邊的第2步開始進(jìn)行源碼分析,如上圖所示Application進(jìn)程的啟動(dòng)流程是由ATMS發(fā)起,在啟動(dòng)activity過程中會(huì)經(jīng)歷一個(gè)類ActivityStackSupervisor.java,在這個(gè)類中會(huì)真正的去啟動(dòng)activity, 會(huì)先進(jìn)入startSpecialActivity()這個(gè)函數(shù)如下所示:
ActivityStackSupervisor.java->startSpecialActivity():
-->//這里面會(huì)進(jìn)行app進(jìn)程存在與否的判斷
if(wpc != null && wpc.hasThread() )
//進(jìn)程存在時(shí),直接啟動(dòng)activity
-->realStartActivityLocked(); //這個(gè)與文章中最前面那張圖就對(duì)上了。
...
//下面是進(jìn)程不存在時(shí),需要?jiǎng)?chuàng)建。
//mService是ActivityTaskServiceManager.java對(duì)象
mService.startProcessAsync();//為app啟動(dòng)一個(gè)進(jìn)程。
//ActivityManagerInternal是AMS里的一個(gè)內(nèi)部類:它內(nèi)部包含了AMS的絕大多數(shù)服務(wù)的函數(shù)
-->Message m = PooledLambda.obtainMessage(ActivityManagerInternal::startProcess,...);
mH.sendMessage(m);
這邊過一下ActivityManagerInternal::startProcess這個(gè)函數(shù):
-->它是用于啟動(dòng)進(jìn)程的,啟動(dòng)進(jìn)程是通過socket,向zygote發(fā)送啟動(dòng)進(jìn)程所需要的一些關(guān)鍵參數(shù),
startProcessLocked();
//app進(jìn)程相關(guān)的核心類有兩個(gè):一個(gè)是ProcessRecord類,一個(gè)是ProcessList進(jìn)程的核心類,
//在下面進(jìn)一步描述:AMS通過持有進(jìn)程的ProcessList列表,通過它來管理(start)進(jìn)程
-->mProcessList.startProcessLocked();
-->判斷處理進(jìn)程啟動(dòng)前的各種參數(shù)和內(nèi)容
...
ProcessList.java->startProcessLocked();
-->ProcessList.java->startProcessLocked(app, ApplicationInfo,);//重載的另一個(gè)函數(shù)
-->ProcessList.java->startProcessLocked();//又是重載 的另一個(gè)函數(shù),中間會(huì)經(jīng)歷很多個(gè)重載的函數(shù)
->...
final Process.ProcessStartResult startResult = startProcess();
-->if(usesWebviewZygote())
startWebView();
else if(usesAppZygote())
appZygote.getProcess().start(); //隔離進(jìn)程的啟動(dòng)
else
//Process:只是一個(gè)工具類(很多靜態(tài)函數(shù)),協(xié)助ProcessList或ProcessRecord去管理進(jìn)程
return Process.start(); //正常app的啟動(dòng)。
//ZYGOTE_PROCESS是ZygoteProcess類對(duì)象,也是工具類幫助zygote啟動(dòng)app進(jìn)程
-->return ZYGOTE_PROCESS.start(); //還是屬于SystemServer進(jìn)程
-->ZygoteProcess.java:startViaZygote();
-->//封裝一系列參數(shù)
....
argsForZygote.add(添加參數(shù))
zygoteSendArgsAndGetResult();
-->attempZygoteSendArgsAndGetResult();
-->BufferedWriter usapWriter = new BufferedWrite();
usapWrite.write(msgStr);
usapWrite.flush();//通過socket發(fā)給zygote.zygote進(jìn)程可以接收到并執(zhí)行。
- Zygote進(jìn)程接收到Socket消息處理
分析到這邊,可以切換到zygote進(jìn)程代碼,繼續(xù)分析,大致看一下Zygote進(jìn)程是如何接收與處理消息的,代碼如下:
ZygoteInit.main():
-->...
runSelectLoop();
-->while(true) //死循環(huán)
-->Zygoteconnection connection = peers.get();
Runnable command = connection.processOneCommand();//進(jìn)行進(jìn)程的處理,創(chuàng)建新進(jìn)程
-->args = Zygote.readArgumentList(mSocketReader);//獲取socket命令參數(shù)
ZygoteArguments parsedArgs = new ZygoteArguments();
...各種參數(shù)解析中...
pid = zygote.forkAndSpecialize();//Fork子進(jìn)程,得到一個(gè)新的pid.
-->nativeForkAndSpecialize(); //調(diào)用native層接口去fork
- 關(guān)于兩個(gè)重要的數(shù)據(jù)結(jié)構(gòu)
(1)ProcessRecord數(shù)據(jù)結(jié)構(gòu)(代表進(jìn)程運(yùn)行的各類屬性參數(shù)):
rocessRecord數(shù)據(jù)結(jié)構(gòu)(代表進(jìn)程運(yùn)行的各類屬性參數(shù)):
第一類數(shù)據(jù):描述身份的數(shù)據(jù),描述進(jìn)程在AMS中的一個(gè)存在形式。
內(nèi)部包括ApplicationInfo, 進(jìn)程uid, userId, ProcessName, pid,
IApplicationThread(APP存放在AMS中的客戶端IBinder對(duì)象)等等信息。
IApplicationThread很重要,AMS通過它給apk進(jìn)程發(fā)送異步消息(管理四大組件的消息),
只有這個(gè)對(duì)象不為空時(shí),才代碼apk進(jìn)程可以使用。
第二類數(shù)據(jù):描述進(jìn)程狀態(tài)的數(shù)據(jù)
第三類數(shù)據(jù):內(nèi)存及和運(yùn)行耗時(shí),CPU時(shí)長(zhǎng),交互時(shí)長(zhǎng)等相關(guān)的數(shù)據(jù)
第四類數(shù)據(jù):crash和anr相關(guān)的數(shù)據(jù)。
所以它包含了APP進(jìn)程的所有信息,通過它可以全方位監(jiān)控并記錄app的運(yùn)行情況 。
上面說的ProcessRecord是代表著一個(gè)進(jìn)程的所有數(shù)據(jù)信息,那AMS需要管理系統(tǒng)運(yùn)行的所有
APP的進(jìn)程,尤其是正在運(yùn)行的app進(jìn)程,這就需要使用一個(gè)List容器來進(jìn)行管理 ,這個(gè)數(shù)據(jù)結(jié)構(gòu)就是ProcessList類,
(2)ProcessList文章來源:http://www.zghlxwxcb.cn/news/detail-678717.html
lass ProcessList{
...
private final int[] mOomAdj = new int[]{ //這里邊存放著進(jìn)程配置的相關(guān)優(yōu)先級(jí)
...
}
...
//正在運(yùn)行的應(yīng)用ProcessRecord數(shù)組,根據(jù)最近使用的方式進(jìn)行排序
final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>();
//正在運(yùn)行的isolated(隔離的)進(jìn)程
final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<>();
}
所以AMS通過ProcessList來持有系統(tǒng)上運(yùn)行的所有app的ProcessRecord,但是進(jìn)程也有優(yōu)先級(jí)文章來源地址http://www.zghlxwxcb.cn/news/detail-678717.html
到了這里,關(guān)于android framework之Applicataion啟動(dòng)流程分析的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!