1、概述
當(dāng)用戶從桌面點(diǎn)擊一個(gè)應(yīng)用圖標(biāo)時(shí)添怔,該應(yīng)用就會(huì)啟動(dòng)并顯示主Activity,即在AndroidManifest中標(biāo)注如下過(guò)濾器的Activity:
里面的category中涉及到LAUNCHER翻翩。這個(gè)其實(shí)和Laucher進(jìn)程有關(guān)戴陡,這是一個(gè)桌面進(jìn)程。所以從桌面點(diǎn)擊圖標(biāo)到應(yīng)用啟動(dòng)顯示的頁(yè)面的過(guò)程命辖,其實(shí)就是從一個(gè)應(yīng)用啟動(dòng)到另一個(gè)應(yīng)用的過(guò)程况毅。
總體流程大致如下圖所示:
① 點(diǎn)擊桌面App圖標(biāo),Launcher進(jìn)程采用Binder IPC向system_server進(jìn)程發(fā)起startActivity請(qǐng)求尔艇。
② system_server進(jìn)程接收到請(qǐng)求后尔许,向zygote進(jìn)程發(fā)送創(chuàng)建進(jìn)程的請(qǐng)求。
③ Zygote進(jìn)程fork出新的子進(jìn)程终娃,即App進(jìn)程味廊。
④ App進(jìn)程,通過(guò)Binder IPC向sytem_server進(jìn)程發(fā)起attachApplication請(qǐng)求。
⑤ system_server進(jìn)程在收到請(qǐng)求后毡们,進(jìn)行一系列準(zhǔn)備工作后迅皇,再通過(guò)binder IPC向App進(jìn)程發(fā)送scheduleLaunchActivity請(qǐng)求。
⑥ App進(jìn)程的binder線程(ApplicationThread)在收到請(qǐng)求后衙熔,通過(guò)handler向主線程發(fā)送LAUNCH_ACTIVITY消息登颓。
⑦ 主線程在收到Message后,通過(guò)發(fā)射機(jī)制創(chuàng)建目標(biāo)Activity红氯,并回調(diào)Activity.onCreate()等方法框咙。
⑧ 到此,App便正式啟動(dòng)痢甘,開(kāi)始進(jìn)入Activity生命周期喇嘱,執(zhí)行完onCreate/onStart/onResume方法,UI渲染結(jié)束后便可以看到App的主界面塞栅。
2者铜、概念介紹
2.1 Launcher
如開(kāi)頭所說(shuō)Launcher本質(zhì)上也是一個(gè)應(yīng)用程序,和我們的App一樣放椰,同時(shí)桌面顯示的頁(yè)面也是一個(gè)Activity:
//packages/apps/Launcher2/src/com/android/launcher2/Launcher.java
public final class Launcher extends Activity
implements View.OnClickListener, OnLongClickListener, LauncherModel.Callbacks,
View.OnTouchListener {
}
Launcher這個(gè)Activity實(shí)現(xiàn)了點(diǎn)擊作烟、長(zhǎng)按等回調(diào)接口,來(lái)接收用戶的輸入砾医。既然是Activity拿撩,那么從Launcher的Activity跳轉(zhuǎn)到我們應(yīng)用的主Activity,和我們平時(shí)從一個(gè)Activity跳轉(zhuǎn)到另一個(gè)Activity的其實(shí)從代碼角度一樣如蚜。即捕捉圖標(biāo)點(diǎn)擊事件压恒,然后startActivity()發(fā)送對(duì)應(yīng)的Intent請(qǐng)求。
2.2 system_server
startActivity()發(fā)送過(guò)來(lái)的請(qǐng)求其實(shí)是發(fā)送給system_server错邦。而SystemServer也是一個(gè)進(jìn)程探赫。所以這一過(guò)程其實(shí)涉及到了進(jìn)程間的通信,這邊的這一過(guò)程是采用Binder的方式來(lái)進(jìn)行的撬呢。system_server這個(gè)進(jìn)程是Android Framework層里面非常重要的一個(gè)進(jìn)程伦吠。系統(tǒng)里面重要的服務(wù)都是在這個(gè)進(jìn)程里面開(kāi)啟的,比如 ActivityManagerService倾芝、PackageManagerService讨勤、WindowManagerService等等箭跳。
而今天重點(diǎn)要涉及到ActivityManagerService這個(gè)服務(wù)晨另,其簡(jiǎn)稱AMS。ActivityManagerService進(jìn)行初始化的時(shí)機(jī)很明確谱姓,就是在SystemServer進(jìn)程開(kāi)啟的時(shí)候借尿,就會(huì)初始化ActivityManagerService。
我們的App通過(guò)調(diào)用startActivity()并不能直接打開(kāi)另外一個(gè)App,這個(gè)方法會(huì)通過(guò)一系列的調(diào)用路翻,最后告訴AMS說(shuō):“我要打開(kāi)這個(gè)App狈癞,我知道他的住址和名字,你幫我打開(kāi)吧茂契!”所以是AMS來(lái)通知zygote進(jìn)程來(lái)fork一個(gè)新進(jìn)程蝶桶,來(lái)開(kāi)啟我們的目標(biāo)App。
除此之外掉冶,其實(shí)所有的Activity的開(kāi)啟真竖、暫停、關(guān)閉都需要AMS來(lái)控制厌小,所以我們說(shuō)恢共,AMS負(fù)責(zé)系統(tǒng)中所有Activity的生命周期。
在Android系統(tǒng)中璧亚,任何一個(gè)Activity的啟動(dòng)都是由AMS和應(yīng)用程序進(jìn)程相互配合來(lái)完成的讨韭。AMS服務(wù)統(tǒng)一調(diào)度系統(tǒng)中所有進(jìn)程的Activity啟動(dòng),而每個(gè)Activity的啟動(dòng)過(guò)程則由其所屬的進(jìn)程具體來(lái)完成癣蟋。
2.3 zygote
如上所說(shuō)透硝,ActivityManagerService收到一個(gè)打開(kāi)一個(gè)應(yīng)用程序的通知后會(huì)發(fā)送創(chuàng)建進(jìn)程的請(qǐng)求給到zygote來(lái)創(chuàng)建一個(gè)app進(jìn)程。
在Android系統(tǒng)里面梢薪,zygote是一個(gè)進(jìn)程的名字蹬铺。Android是基于Linux System的,當(dāng)你的手機(jī)開(kāi)機(jī)的時(shí)候秉撇,Linux的內(nèi)核加載完成之后就會(huì)啟動(dòng)一個(gè)叫“init“的進(jìn)程甜攀。在Linux System里面,所有的進(jìn)程都是由init進(jìn)程fork出來(lái)的琐馆,我們的zygote進(jìn)程也不例外规阀。
我們都知道,每一個(gè)App其實(shí)都是一個(gè)單獨(dú)的dalvik虛擬機(jī)并對(duì)應(yīng)一個(gè)單獨(dú)的進(jìn)程瘦麸。所以當(dāng)系統(tǒng)里面的第一個(gè)zygote進(jìn)程運(yùn)行之后谁撼,在這之后再開(kāi)啟App,就相當(dāng)于開(kāi)啟一個(gè)新的進(jìn)程滋饲。而為了實(shí)現(xiàn)資源共用和更快的啟動(dòng)速度厉碟,Android系統(tǒng)開(kāi)啟新進(jìn)程的方式,是通過(guò)fork第一個(gè)zygote進(jìn)程實(shí)現(xiàn)的屠缭。所以說(shuō)箍鼓,除了第一個(gè)zygote進(jìn)程,其他應(yīng)用所在的進(jìn)程都是zygote的子進(jìn)程呵曹。而zygote的直白翻譯為“受精卵”款咖,也是很形象生動(dòng)了何暮。
而創(chuàng)建的新進(jìn)程的入口就是ActivityThread.main()方法,之后的部分將著重介紹铐殃。
3海洼、應(yīng)用創(chuàng)建到顯示
3.1 啟動(dòng)應(yīng)用程序
Android中,一個(gè)應(yīng)用程序的開(kāi)始可以說(shuō)就是從ActivityThread.java中的main()方法開(kāi)始的富腊。下面是main()比較關(guān)鍵的代碼:
public static void main(String[] args){
...
Looper.prepareMainLooper();
//初始化Looper
...
ActivityThread thread = new ActivityThread();
//實(shí)例化一個(gè)ActivityThread
thread.attach(false);
//這個(gè)方法最后就是為了發(fā)送出創(chuàng)建Application的消息
...
Looper.loop();
//主線程進(jìn)入無(wú)限循環(huán)狀態(tài)坏逢,等待接收消息
}
從源碼中可以看到,main()方法中主要做的事情是赘被,初始化主線程的Looper词疼、主Handler。并使主線程進(jìn)入等待接收Message消息的無(wú)限循環(huán)狀態(tài)帘腹。并在進(jìn)入等待接收消息前實(shí)例化一個(gè)實(shí)例化一個(gè)ActivityThread贰盗,并調(diào)用其attach()方法。從這也可以想象到為什么說(shuō)Android的設(shè)計(jì)是一個(gè)事件驅(qū)動(dòng)的模型了阳欲。
3.2 應(yīng)用程序和AMS關(guān)聯(lián)
我們?cè)诳匆幌聇hread.attach(false)中的關(guān)鍵代碼:
public void attach(boolean system){
...
final IActivityManager mgr = ActivityManagerNative.getDefault();
//獲得IActivityManager實(shí)例
try {
mgr.attachApplication(mAppThread);
} catch (RemoteException ex) {
throw ex.rethrowFromSystemServer();
}
...
}
里面的IActivityManager 是一個(gè)接口舵盈,當(dāng)我們調(diào)用ActivityManagerNative.getDefault()獲得的實(shí)際是一個(gè)代理類的實(shí)例——ActivityManagerProxy,這個(gè)東西實(shí)現(xiàn)了IActivityManager接口球化。打開(kāi)源碼你會(huì)發(fā)現(xiàn)秽晚,ActivityManagerProxy是ActivityManagerNative的一個(gè)內(nèi)部類。既然是一個(gè)代理類它必定有代理的對(duì)象筒愚。查看一下ActivityManagerProxy的構(gòu)造函數(shù):
public ActivityManagerProxy(IBinder remote) {
mRemote = remote;
}
這個(gè)構(gòu)造函數(shù)非常的簡(jiǎn)單赴蝇。首先它需要一個(gè)IBinder參數(shù),然后賦值給mRemote變量巢掺。這個(gè)mRemote顯然是ActivityManagerNative的成員變量句伶。但對(duì)它的操作是由ActivityManagerProxy來(lái)代理間接進(jìn)行的。這樣設(shè)計(jì)的好處是保護(hù)了mRemote陆淀,并且能夠在操作mRemote前執(zhí)行一些別的事務(wù)考余,并且我們是以IActivityManager的身份來(lái)進(jìn)行這些操作。
該構(gòu)造函數(shù)的調(diào)用地點(diǎn):
static public IActivityManager asInterface(IBinder obj) {
if (obj == null) {
return null;
}
IActivityManager in =
(IActivityManager)obj.queryLocalInterface(descriptor);
//先檢查一下有沒(méi)有
if (in != null) {
return in;
}
...
return new ActivityManagerProxy(obj);
//這個(gè)地方調(diào)用了構(gòu)造函數(shù)
}
上面這個(gè)方法是ActivityManagerNative中的一個(gè)靜態(tài)方法轧苫,它會(huì)調(diào)用到ActivityManagerProxy的構(gòu)造方法楚堤。這個(gè)靜態(tài)方法也需要一個(gè)IBinder作為參數(shù)。
查找這個(gè)函數(shù)的調(diào)用地點(diǎn)以及傳入的參數(shù)到底是什么:
private static final SingletongDefault = new Singleton() {
protected IActivityManager create() {
IBinder b = ServiceManager.getService("activity");
//重點(diǎn)昂谩身冬!IBinder實(shí)例就是在這里獲得的。
...
IActivityManager am = asInterface(b);
//調(diào)用了上面的方法岔乔。
...
return am;
}
};
這是ActivityManagerNative的靜態(tài)常量酥筝,它是一個(gè)單例。在其中終于獲得了前面一直在用的IBinder實(shí)例重罪。
IBinder b = ServiceManager.getService("activity");
到這里應(yīng)該已經(jīng)非常清晰了樱哼,IActivityManager 獲取到的就是一個(gè)ActivityManagerService的代理。有了這個(gè)代理之后就可以作為客戶端通過(guò)Binder機(jī)制將app作為客戶端剿配,ActivityManagerService作為服務(wù)端來(lái)進(jìn)行通信了搅幅。具體Binder進(jìn)程間通信機(jī)制請(qǐng)看我之前一篇文章:Binder進(jìn)程間通信機(jī)制。
我們回到前面的thread.attach(false)方法中呼胚,接著往下看在獲得IActivityManager實(shí)例之后茄唐,將會(huì)執(zhí)行它的attachApplication(mAppThread)方法。該方法會(huì)傳入一個(gè)mAppThread參數(shù)蝇更。在ActivityThread這個(gè)類的成員變量中沪编,有這么一行代碼:
final ApplicationThread mAppThread = new ApplicationThread();
ApplicationThread是作為ActivityThread中的一個(gè)常量出現(xiàn)的。這表明系統(tǒng)不希望這個(gè)變量中途被修改年扩,也說(shuō)明其的重要性蚁廓。ApplicationThread類繼承自ApplicationThreadNative。并且ApplicationThread是ActivityThread的一個(gè)內(nèi)部類厨幻。從設(shè)計(jì)角度可以看出相嵌,該類是專門(mén)讓ActivityThread來(lái)使用的一個(gè)類。
看一下ApplicationThread的父類ApplicationThreadNative:
public abstract class ApplicationThreadNative extends Binder
implements IApplicationThread{
...
}
我們從ApplicationThreadNative看到它也是一個(gè)Binder况脆,同時(shí)實(shí)現(xiàn)了IApplicationThread接口饭宾。這個(gè)Binder并不是Binder代理,這個(gè)Binder說(shuō)明了應(yīng)用程序在作為客戶端的同時(shí)格了,也作為了服務(wù)端看铆。而作為服務(wù)端的Binder就是ApplicationThread。而 mgr.attachApplication(mAppThread) 這行代碼就是通過(guò)mgr將ApplicationThread的信息作為數(shù)據(jù)發(fā)送給AMS盛末,方便日后AMS通過(guò)ApplicationThread的代理發(fā)送數(shù)據(jù)給ApplicationThread來(lái)達(dá)到控制app的Activity生命周期等一系列操作弹惦。
幾經(jīng)輾轉(zhuǎn),ApplicationThread的信息終于傳遞到了AMS中悄但,我們可以從AMS的源碼中找到這個(gè)函數(shù):
private final boolean attachApplicationLocked(IApplicationThread thread
, int pid) {
...
thread.bindApplication();
...
}
3.3 創(chuàng)建Application
ApplicationThread以IApplicationThread的身份到了ActivityManagerService中(其實(shí)在ActivityManagerService中的是ApplicationThread的代理)肤频,經(jīng)過(guò)一系列的操作,最終被調(diào)用了自己的bindApplication()方法算墨,發(fā)出初始化Applicationd的消息:
public final void bindApplication(String processName, ApplicationInfo appInfo, Listproviders, ComponentName instrumentationName, ProfilerInfo profilerInfo, Bundle instrumentationArgs, IInstrumentationWatcher instrumentationWatcher, IUiAutomationConnection instrumentationUiConnection, int debugMode, boolean enableBinderTracking, boolean trackAllocation, boolean isRestrictedBackupMode, boolean persistent, Configuration config, CompatibilityInfo compatInfo, Map services,
Bundle coreSettings){
...
sendMessage(H.BIND_APPLICATION, data);
}
bindApplication()函數(shù)就是AMS的ApplicationThread的代理宵荒,通過(guò)Binder進(jìn)程間通信調(diào)用app進(jìn)程的ApplicationThread的bindApplication()方法。該方法里面有一句關(guān)鍵代碼
sendMessage(H.BIND_APPLICATION, data);
還記不記得最開(kāi)始main函數(shù)創(chuàng)建的Looper净嘀。而ActivityThread中還存在一個(gè)該Looper的處理對(duì)象Hander H报咳。從傳送的參數(shù)H.BIND_APPLICATION可以看到,這個(gè)消息就是發(fā)送給這個(gè)H來(lái)處理的挖藏。
一旦H接收到這個(gè)消息就開(kāi)始創(chuàng)建Application了暑刃。這個(gè)過(guò)程是在handleBindApplication()中完成的:
private void handleBindApplication(AppBindData data) {
...
mInstrumentation = (Instrumentation)
cl.loadClass(data.instrumentationName.getClassName())
.newInstance();
//通過(guò)反射初始化一個(gè)Instrumentation儀表。后面會(huì)介紹膜眠。
...
Application app = data.info.makeApplication(data.restrictedBackupMode, null);
//通過(guò)LoadedApp命令創(chuàng)建Application實(shí)例
mInitialApplication = app;
...
mInstrumentation.callApplicationOnCreate(app);
//讓儀器調(diào)用Application的onCreate()方法
...
}
handleBindApplication()中比較關(guān)鍵的是上面幾句代碼岩臣。其中有個(gè)類Instrumentation溜嗜,它在創(chuàng)建Application類之前進(jìn)行實(shí)例化。它能夠允許你監(jiān)視應(yīng)用程序和系統(tǒng)的所有交互架谎。打開(kāi)這個(gè)類你可以發(fā)現(xiàn)炸宵,最終Apllication的創(chuàng)建,Activity的創(chuàng)建谷扣,以及生命周期都會(huì)經(jīng)過(guò)這個(gè)對(duì)象去執(zhí)行土全。簡(jiǎn)單點(diǎn)說(shuō),就是把這些操作包裝了一層会涎。通過(guò)操作Instrumentation進(jìn)而實(shí)現(xiàn)上述的功能裹匙。這里實(shí)例化Instrumentation的方法是反射!而反射的ClassName是來(lái)自于從ActivityManagerService中通過(guò)ApplicationThread的代理傳過(guò)來(lái)的末秃。
接我們著看mInstrumentation調(diào)用的方法callApplicationOnCreate(app):
public void callApplicationOnCreate(Application app) {
app.onCreate();
}
該方法只是回調(diào)了一下Application 的onCreate()概页。這就是為什么它能夠起到監(jiān)控的作用。我們最熟悉的Activity的一些聲明周期的方法onCreate()练慕,onStart()等等也是通過(guò)這樣來(lái)進(jìn)行回調(diào)的绰沥。
再回到
Application app = data.info.makeApplication(data.restrictedBackupMode, null);
看下調(diào)用的方法makeApplication(data.restrictedBackupMode, null):
public Application makeApplication(boolean forceDefaultAppClass,
Instrumentation instrumentation) {
...
String appClass = mApplicationInfo.className;
//Application的類名。明顯是要用反射了贺待。
...
ContextImpl appContext = ContextImpl.createAppContext(mActivityThread
, this);
//留意下Context
app = mActivityThread.mInstrumentation
.newApplication( cl, appClass, appContext);
//通過(guò)儀表創(chuàng)建Application
...
}
這里首先通過(guò)反射找到了Application的類名徽曲。其次創(chuàng)建了Application的ContextImpl ,ContextImpl 其實(shí)Application的Context具體執(zhí)行的類麸塞,我們平時(shí)調(diào)用的Context有關(guān)的方法最后其實(shí)都是調(diào)用了ContextImpl 的對(duì)應(yīng)方法秃臣,這里不展開(kāi)講了。之后就是通過(guò)剛才說(shuō)的mInstrumentation來(lái)調(diào)用newApplication( cl, appClass, appContext)創(chuàng)建Application哪工。具體該方法如下:
static public Application newApplication(Class clazz
, Context context) throws InstantiationException
, IllegalAccessException
, ClassNotFoundException {
Application app = (Application)clazz.newInstance();
//反射創(chuàng)建奥此,簡(jiǎn)單粗暴
app.attach(context);
//關(guān)注下這里,Application被創(chuàng)建后第一個(gè)調(diào)用的方法雁比。
//目的是為了綁定ContextImpl 稚虎。
return app;
}
至此終于將Application創(chuàng)建出來(lái)了。
3.4 創(chuàng)建及啟動(dòng)Activity
還記得之前的Application啟動(dòng)信號(hào)其實(shí)是AMS通過(guò)ApplicationThread的代理調(diào)用bindApplication()發(fā)送過(guò)來(lái)的嗎偎捎?了解Binder通信機(jī)制可以知道蠢终,一旦客戶端調(diào)用遠(yuǎn)程服務(wù)(此時(shí)AMS是客戶端,app是服務(wù)端)茴她,調(diào)用服務(wù)的線程調(diào)用服務(wù)后是會(huì)掛起直到服務(wù)調(diào)用完畢返回結(jié)果的寻拂。這邊創(chuàng)建完Application相當(dāng)于服務(wù)調(diào)用完畢了。此時(shí)AMS的對(duì)應(yīng)線程會(huì)接著往下執(zhí)行代碼以同樣的方法通過(guò)ApplicationThread的代理向ApplicationThread發(fā)起啟動(dòng)主Activity的請(qǐng)求丈牢,并且在ApplicationThread中向H發(fā)送一條LAUNCH_ACTIVITY的消息祭钉。然后H就開(kāi)始了初始化Activity。
收到LAUNCH_ACTIVITY后H會(huì)調(diào)用handleLaunchActivity():
private void handleLaunchActivity(ActivityClientRecord r
, Intent customIntent
, String reason) {
...
Activity a = performLaunchActivity(r, customIntent);
//媽蛋己沛!又封裝到另一個(gè)方法中創(chuàng)建了慌核。
...
if (a != null) {
...
handleResumeActivity(r.token
, false
, r.isForward
,!r.activity.mFinished && !r.startsNotResumed
, r.lastProcessedSeq, reason);
//Activity創(chuàng)建成功就往onResume()走了距境!
...
}
}
繼續(xù)往下看performLaunchActivity(r, customIntent):
private Activity performLaunchActivity(ActivityClientRecord r
, Intent customIntent) {
...
activity = mInstrumentation.newActivity(
cl, component.getClassName(), r.intent);
//通過(guò)mInstrumentation來(lái)創(chuàng)建Activity
...
Application app = r.packageInfo.makeApplication(false
, mInstrumentation);
//獲取Application
...
activity.attach(appContext
, this
, getInstrumentation()
, r.token
,.ident
, app
, r.intent
, r.activityInfo
, title
, r.parent
, r.embeddedID
, r.lastNonConfigurationInstances
, config
,r.referrer
, r.voiceInteractor
, window);
...
if (r.isPersistable()) {
mInstrumentation.callActivityOnCreate(
activity, r.state, r.persistentState);
} else {
mInstrumentation.callActivityOnCreate(activity, r.state);
}
//根據(jù)是否可持久化選擇onCreate()方法。
...
}
注意這句代碼:
activity = mInstrumentation.newActivity(
cl, component.getClassName(), r.intent);
正如前面所說(shuō)垮卓,Activity垫桂、Application的創(chuàng)建及生命周期都被承包給Instrumentation。所以由它來(lái)負(fù)責(zé)扒接。看看newActivity():
public Activity newActivity(ClassLoader cl, String className,
Intent intent)
throws InstantiationException
, IllegalAccessException,
ClassNotFoundException {
return (Activity)cl.loadClass(className).newInstance();
//反射實(shí)例化Activity而已
}
其實(shí)就是通過(guò)反射實(shí)例化了Activity们衙。
回到performLaunchActivity() 創(chuàng)建了Activity后 將之前創(chuàng)建出來(lái)的Application和Activity關(guān)聯(lián)钾怔。
接著我們看performLaunchActivity() 中的這段代碼:
if (r.isPersistable()) {
mInstrumentation.callActivityOnCreate(
activity, r.state, r.persistentState);
} else {
mInstrumentation.callActivityOnCreate(activity, r.state);
}
根據(jù)是否可持久化選擇Activity的onCreate()方法。同樣是通過(guò)Instrumentation儀表來(lái)執(zhí)行onCreate()的蒙挑。它兩分別對(duì)應(yīng)的onCreate()方法為:
onCreate(icicle, persistentState);
//可獲得持久化數(shù)據(jù)
onCreate(icicle);
//平時(shí)重寫(xiě)的最多的宗侦。
至此,成功調(diào)用了Activity的onCreate()方法忆蚀。其實(shí)之后的onStart()矾利,onResume()等生命周期的方法也時(shí)類似這樣調(diào)用的。
4馋袜、總結(jié)
從桌面點(diǎn)擊圖標(biāo)到創(chuàng)建應(yīng)用進(jìn)程男旗,再到創(chuàng)建Application,在到創(chuàng)建主Activity到最后調(diào)用onCreate()的流程大致如上文所述欣鳖。