引言
Activity啟動(dòng)流程很多文章都已經(jīng)說過了额嘿,這里說一下自己的理解蓝角。
Activity啟動(dòng)流程分兩種:
- 一種是啟動(dòng)正在運(yùn)行的app的Activity肄方,即啟動(dòng)子Activity稚矿。如無特殊聲明默認(rèn)和啟動(dòng)該activity的activity處于同一進(jìn)程掏熬。如果有聲明在一個(gè)新的進(jìn)程中搀崭,則處于兩個(gè)進(jìn)程叨粘。
- 一種是打開新的app,即為L(zhǎng)auncher啟動(dòng)新的Activity瘤睹。
后邊啟動(dòng)Activity的流程是一樣的宣鄙,區(qū)別是前邊判斷進(jìn)程是否存在的那部分。
Activity啟動(dòng)的前提是已經(jīng)開機(jī)默蚌,各項(xiàng)進(jìn)程和AMS等服務(wù)已經(jīng)初始化完成冻晤,在這里也提一下那些內(nèi)容。
Activity啟動(dòng)之前的一些事情
init進(jìn)程:init是所有l(wèi)inux程序的起點(diǎn)绸吸,是Zygote的父進(jìn)程鼻弧。解析init.rc孵化出Zygote進(jìn)程。
Zygote進(jìn)程:Zygote是所有Java進(jìn)程的父進(jìn)程锦茁,所有的App進(jìn)程都是由Zygote進(jìn)程fork生成的攘轩。
SystemServer進(jìn)程:System Server是Zygote孵化的第一個(gè)進(jìn)程。SystemServer負(fù)責(zé)啟動(dòng)和管理整個(gè)Java framework码俩,包含AMS度帮,PMS等服務(wù)。
-
Launcher:Zygote進(jìn)程孵化的第一個(gè)App進(jìn)程是Launcher稿存。
1.init進(jìn)程是什么笨篷?
Android是基于linux系統(tǒng)的,手機(jī)開機(jī)之后瓣履,linux內(nèi)核進(jìn)行加載率翅。加載完成之后會(huì)啟動(dòng)init進(jìn)程。
init進(jìn)程會(huì)啟動(dòng)ServiceManager袖迎,孵化一些守護(hù)進(jìn)程冕臭,并解析init.rc孵化Zygote進(jìn)程。2.Zygote進(jìn)程是什么燕锥?
所有的App進(jìn)程都是由Zygote進(jìn)程fork生成的辜贵,包括SystemServer進(jìn)程。Zygote初始化后归形,會(huì)注冊(cè)一個(gè)等待接受消息的socket托慨,OS層會(huì)采用socket進(jìn)行IPC通信。
3.為什么是Zygote來孵化進(jìn)程连霉,而不是新建進(jìn)程呢榴芳?
每個(gè)應(yīng)用程序都是運(yùn)行在各自的Dalvik虛擬機(jī)中,應(yīng)用程序每次運(yùn)行都要重新初始化和啟動(dòng)虛擬機(jī)跺撼,這個(gè)過程會(huì)耗費(fèi)很長(zhǎng)時(shí)間窟感。Zygote會(huì)把已經(jīng)運(yùn)行的虛擬機(jī)的代碼和內(nèi)存信息共享,起到一個(gè)預(yù)加載資源和類的作用歉井,從而縮短啟動(dòng)時(shí)間柿祈。
Activity啟動(dòng)階段
涉及到的概念
- 進(jìn)程:Android系統(tǒng)為每個(gè)APP分配至少一個(gè)進(jìn)程
- IPC:跨進(jìn)程通信,Android中采用Binder機(jī)制哩至。
涉及到的類
- ActivityStack:Activity在AMS的棧管理躏嚎,用來記錄已經(jīng)啟動(dòng)的Activity的先后關(guān)系,狀態(tài)信息等菩貌。通過ActivityStack決定是否需要啟動(dòng)新的進(jìn)程卢佣。
- ActivitySupervisor:管理 activity 任務(wù)棧
- ActivityThread:ActivityThread 運(yùn)行在UI線程(主線程),App的真正入口箭阶。
- ApplicationThread:用來實(shí)現(xiàn)AMS和ActivityThread之間的交互虚茶。
- ApplicationThreadProxy:ApplicationThread 在服務(wù)端的代理。AMS就是通過該代理與ActivityThread進(jìn)行通信的仇参。
- IActivityManager:繼承與IInterface接口嘹叫,抽象出跨進(jìn)程通信需要實(shí)現(xiàn)的功能
- AMN:運(yùn)行在server端(SystemServer進(jìn)程)。實(shí)現(xiàn)了Binder類诈乒,具體功能由子類AMS實(shí)現(xiàn)罩扇。
- AMS:AMN的子類,負(fù)責(zé)管理四大組件和進(jìn)程怕磨,包括生命周期和狀態(tài)切換喂饥。AMS因?yàn)橐蛈i交互,所以極其復(fù)雜肠鲫,涉及window仰泻。
- AMP:AMS的client端代理(app進(jìn)程)。了解Binder知識(shí)可以比較容易理解server端的stub和client端的proxy滩届。AMP和AMS通過Binder通信集侯。
- Instrumentation:儀表盤,負(fù)責(zé)調(diào)用Activity和Application生命周期帜消。測(cè)試用到這個(gè)類比較多棠枉。
流程圖
這個(gè)圖來源自網(wǎng)上,之前也看過很多類似講流程的文章泡挺,但是大都是片段的辈讶。這個(gè)圖是目前看到的最全的,自己去畫一下也應(yīng)該不會(huì)比這個(gè)全了娄猫,所以在這里直接引用一下贱除,可以去瀏覽器上放大看生闲。
涉及到的進(jìn)程
- Launcher所在的進(jìn)程
- AMS所在的SystemServer進(jìn)程
- 要啟動(dòng)的Activity所在的app進(jìn)程
如果是啟動(dòng)根Activity,就涉及上述三個(gè)進(jìn)程月幌。
如果是啟動(dòng)子Activity碍讯,那么就只涉及AMS進(jìn)程和app所在進(jìn)程。
具體流程
- Launcher:Launcher通知AMS要啟動(dòng)activity扯躺。
- startActivitySafely->startActivity->Instrumentation.execStartActivity()(AMP.startActivity)->AMS.startActivity
- AMS:PMS的resoveIntent驗(yàn)證要啟動(dòng)activity是否匹配捉兴。
- 如果匹配,通過ApplicationThread發(fā)消息給Launcher所在的主線程录语,暫停當(dāng)前Activity(Launcher);
- 暫停完倍啥,在該activity還不可見時(shí),通知AMS澎埠,根據(jù)要啟動(dòng)的Activity配置ActivityStack虽缕。然后判斷要啟動(dòng)的Activity進(jìn)程是否存在?
- 存在:發(fā)送消息LAUNCH_ACTIVITY給需要啟動(dòng)的Activity主線程,執(zhí)行handleLaunchActivity
- 不存在:通過socket向zygote請(qǐng)求創(chuàng)建進(jìn)程蒲稳。進(jìn)程啟動(dòng)后彼宠,ActivityThread.attach
- 判斷Application是否存在,若不存在弟塞,通過LoadApk.makeApplication創(chuàng)建一個(gè)凭峡。在主線程中通過thread.attach方法來關(guān)聯(lián)ApplicationThread。
- 在通過ActivityStackSupervisor來獲取當(dāng)前需要顯示的ActivityStack决记。
- 繼續(xù)通過ApplicationThread來發(fā)送消息給主線程的Handler來啟動(dòng)Activity(handleLaunchActivity)摧冀。
- handleLauchActivity:調(diào)用了performLauchActivity,里邊Instrumentation生成了新的activity對(duì)象系宫,繼續(xù)調(diào)用activity生命周期索昂。
IPC過程:
雙方都是通過對(duì)方的代理對(duì)象來進(jìn)行通信。
1.app和AMS通信:app通過本進(jìn)程的AMP和AMS進(jìn)行Binder通信
2.AMS和新app通信:通過ApplicationThreadProxy來通信扩借,并不直接和ActivityThread通信
參考函數(shù)流程
Activity啟動(dòng)流程(從Launcher開始):
第一階段: Launcher通知AMS要啟動(dòng)新的Activity(在Launcher所在的進(jìn)程執(zhí)行)
- Launcher.startActivitySafely //首先Launcher發(fā)起啟動(dòng)Activity的請(qǐng)求
- Activity.startActivity
- Activity.startActivityForResult
- Instrumentation.execStartActivity //交由Instrumentation代為發(fā)起請(qǐng)求
- ActivityManager.getService().startActivity //通過IActivityManagerSingleton.get()得到一個(gè)AMP代理對(duì)象
- ActivityManagerProxy.startActivity //通過AMP代理通知AMS啟動(dòng)activity
第二階段:AMS先校驗(yàn)一下Activity的正確性椒惨,如果正確的話,會(huì)暫存一下Activity的信息潮罪。然后罐寨,AMS會(huì)通知Launcher程序pause Activity(在AMS所在進(jìn)程執(zhí)行)
- ActivityManagerService.startActivity
- ActivityManagerService.startActivityAsUser
- ActivityStackSupervisor.startActivityMayWait
- ActivityStackSupervisor.startActivityLocked :檢查有沒有在AndroidManifest中注冊(cè)
- ActivityStackSupervisor.startActivityUncheckedLocked
- ActivityStack.startActivityLocked :判斷是否需要?jiǎng)?chuàng)建一個(gè)新的任務(wù)來啟動(dòng)Activity盯滚。
- ActivityStack.resumeTopActivityLocked :獲取棧頂?shù)腶ctivity鳍悠,并通知Launcher應(yīng)該pause掉這個(gè)Activity以便啟動(dòng)新的activity瞎颗。
- ActivityStack.startPausingLocked
- ApplicationThreadProxy.schedulePauseActivity
第三階段: pause Launcher的Activity,并通知AMS已經(jīng)paused(在Launcher所在進(jìn)程執(zhí)行)
- ApplicationThread.schedulePauseActivity
- ActivityThread.queueOrSendMessage
- H.handleMessage
- ActivityThread.handlePauseActivity
- ActivityManagerProxy.activityPaused
第四階段:檢查activity所在進(jìn)程是否存在何恶,如果存在孽锥,就直接通知這個(gè)進(jìn)程,在該進(jìn)程中啟動(dòng)Activity;不存在的話惜辑,會(huì)調(diào)用Process.start創(chuàng)建一個(gè)新進(jìn)程(執(zhí)行在AMS進(jìn)程)
- ActivityManagerService.activityPaused
- ActivityStack.activityPaused
- ActivityStack.completePauseLocked
- ActivityStack.resumeTopActivityLocked
- ActivityStack.startSpecificActivityLocked
- ActivityManagerService.startProcessLocked
- Process.start //在這里創(chuàng)建了新進(jìn)程唬涧,新的進(jìn)程會(huì)導(dǎo)入ActivityThread類,并執(zhí)行它的main函數(shù)
第五階段: 創(chuàng)建ActivityThread實(shí)例盛撑,執(zhí)行一些初始化操作碎节,并綁定Application。如果Application不存在撵彻,會(huì)調(diào)用LoadedApk.makeApplication創(chuàng)建一個(gè)新的Application對(duì)象钓株。之后進(jìn)入Loop循環(huán)实牡。(執(zhí)行在新創(chuàng)建的app進(jìn)程)
- ActivityThread.main
- ActivityThread.attach(false) //聲明不是系統(tǒng)進(jìn)程
- ActivityManagerProxy.attachApplication
第六階段:處理新的應(yīng)用進(jìn)程發(fā)出的創(chuàng)建進(jìn)程完成的通信請(qǐng)求陌僵,并通知新應(yīng)用程序進(jìn)程啟動(dòng)目標(biāo)Activity組件(執(zhí)行在AMS進(jìn)程)
- ActivityManagerService.attachApplication //AMS綁定本地ApplicationThread對(duì)象,后續(xù)通過ApplicationThreadProxy來通信创坞。
- ActivityManagerService.attachApplicationLocked
- ActivityStack.realStartActivityLocked //真正要啟動(dòng)Activity了碗短!
- ApplicationThreadProxy.scheduleLaunchActivity //AMS通過ATP通知app進(jìn)程啟動(dòng)Activity
第七階段: 加載MainActivity類,調(diào)用onCreate聲明周期方法(執(zhí)行在新啟動(dòng)的app進(jìn)程)
- ApplicationThread.scheduleLaunchActivity //ApplicationThread發(fā)消息給AT
- ActivityThread.queueOrSendMessage
- H.handleMessage //AT的Handler來處理接收到的LAUNCH_ACTIVITY的消息
- ActivityThread.handleLaunchActivity
- ActivityThread.performLaunchActivity
- Instrumentation.newActivity //調(diào)用Instrumentation類來新建一個(gè)Activity對(duì)象
- Instrumentation.callActivityOnCreate
- MainActivity.onCreate
- ActivityThread.handleResumeActivity
- AMP.activityResumed
- AMS.activityResumed(AMS進(jìn)程)
參考文章
http://gityuan.com/2016/03/12/start-activity/
https://blog.csdn.net/luoshengyang/article/details/6689748