tips:部分讀者可能對此文會(huì)引起不適,若有此感,敬請?zhí)^。
“我就知道你還會(huì)再來的,說吧,這次想學(xué)習(xí)什么?”,還沒等我出聲,Story大神就開口了,“上一次我進(jìn)來是學(xué)到了不少知識(shí),而且app啟動(dòng)也優(yōu)化了不少,但是這些都是表面的知識(shí),我在優(yōu)化的過程中突然就想到了,我點(diǎn)擊圖標(biāo)的時(shí)候,app是怎么啟動(dòng)起來的?”我充滿疑問的問道,“哈哈,我就知道你是孺子可教也,你確定要深入虎穴嗎?這可是比較燒腦的環(huán)節(jié)哦!”,“確定!”,我想都沒想就回答了,為了追求未知的知識(shí),我還是比較堅(jiān)定的。
虎穴,打開!
就在這時(shí),一堆代碼仿佛像掙脫了韁繩的馬一樣飛奔而來,并且整齊的列好隊(duì)排列在我眼前。“請大家自我介紹一下”,Story大神對它們說道。
“你好,我是 Zygote,我是Android系統(tǒng)創(chuàng)造出來的,而我的作用就是為Android系統(tǒng)生孩子。
“我叫 ActivityManager,一聽我的名字就知道我是一個(gè)Activity管理層(不單單是Activity的管理,更是其他三大組件的管理者),無論是創(chuàng)建還是跳轉(zhuǎn),都要經(jīng)過我的審判,才能繼續(xù)下去,也就是說我掌握著Activity的生死大權(quán)。還有,你看到站在我身邊的都是我的手下,我左邊的這個(gè)是 IActivityManager,它就是對我的命令進(jìn)行了封裝裝飾,我右手邊的是 ActivityManagerProxy ,它就是對封裝裝飾好的命令進(jìn)行下傳的,而我后面的那位是 ActivityManagerService ,它就是要對命令執(zhí)行的人了,別看我衣著光鮮,其實(shí)還是挺累的,一個(gè)個(gè) 代理 著我的命令進(jìn)行傳遞?!?/p>
“大家好,我叫 ActivityThread , 我的職責(zé)是管理應(yīng)用進(jìn)程的主線程的執(zhí)行,比如快速處理UI界面的變化,還有一些需要在主線程上調(diào)度都是我的管轄范圍。”
“我是 Process ,想要進(jìn)程,就來我這里申領(lǐng)吧?!?/p>
聽著它們講了一大堆,我一直在點(diǎn)頭,其實(shí)我內(nèi)心是懵逼的,這是什么跟什么啊。貌似Story大神看出了我的疑問,就對我說了,“是不是沒聽懂它們在說什么?”,我點(diǎn)點(diǎn)頭,“哈哈,來吧,走進(jìn)它們的世界看一下你就會(huì)了如指掌的了,過來吧,”我還是心懷疑慮的走了過去。
簡直是走進(jìn)了Android系統(tǒng)的五章六腑,各個(gè)部門配合緊密,處理速度之迅猛。“到了”,Story大神帶我走進(jìn)了一個(gè)類似車間的一個(gè)工作室,眼前的那一幕是我從所未見的,當(dāng)然,自從進(jìn)來這里之后,每次都會(huì)刷新我的世界觀和人生觀!
剛剛還在自我介紹的它們,現(xiàn)在已經(jīng)在認(rèn)真地工作中了,Zygote 正在分裂復(fù)制著(fork),真的像它剛剛介紹的那樣,在生孩子,所有的應(yīng)用程序的進(jìn)程都是又它生出來的。這時(shí)候從中間浮出一段文字。
應(yīng)用程序的運(yùn)行,都是基于 Android的虛擬機(jī),而且每次啟動(dòng)都會(huì)帶來很大的開銷,而 Zygote 的生產(chǎn)方式則能夠提升不小的效率。在這個(gè)生產(chǎn)的過程中,采用了Linux 的 寫時(shí)拷貝技術(shù) Copy-on-Write 的方式,重復(fù)利用了 Zygote 上的資源,達(dá)到了最大的效率。
首先, Zygote 會(huì)開啟一個(gè)Socket:registerZygoteSocket(socketName),也就是Zygote Socket,這個(gè)Socket就是去監(jiān)聽?wèi)?yīng)用程序的請求的,當(dāng)有請求的話就會(huì)立刻通知 Zygote 進(jìn)行生產(chǎn),同時(shí)還啟動(dòng)了 SystemServer 。
SystemServer ?這又是什么來的?“剛剛因?yàn)樗α耍詻]出來跟你打招呼,現(xiàn)在跟你介紹一下它吧”。
SystemServer ,是 Zygote 的大兒子,在生產(chǎn)過程中扮演中無比重要的角色,正如其名,系統(tǒng)中的所有服務(wù)都與它有著密切的關(guān)系,而且整個(gè)Android中的核心Service都在其中,比如剛剛跟你介紹的 ActivityManagerService , Zygote 統(tǒng)管著后宮大權(quán)(生孩子),而 SystemServer 則是名副其實(shí)的一人之上萬人之下的統(tǒng)治者了!
緊接著, ActivityManager 出現(xiàn)了,只見最上層的編碼者(就是我了),點(diǎn)擊了app,這時(shí), ActivityManager 開發(fā)工作了,發(fā)出 startActivity(intent) 的命令,app啟動(dòng)了,而在系統(tǒng)中,又多了一個(gè)進(jìn)程出來,而系統(tǒng)又是一個(gè)進(jìn)程,那么這個(gè)命令就由中間的管理服務(wù)者
ActivityManagerService來調(diào)度了,而這是屬于兩個(gè)進(jìn)程間的通信,又設(shè)計(jì)到了跨進(jìn)程通信了(IPC)。
掌權(quán)者 ActivityManager 是所有人都能看得到權(quán)力所有者,對接著所有的程序員,下發(fā)了命令之后通過 IActivityManager 的修飾封裝,比如 startActivity 、finishActivity等命令,通過 ActivityManagerProxy 把命令傳遞到執(zhí)行者 ActivityManagerService 手中,再進(jìn)行相應(yīng)的處理。
還不明白嗎?我們從上至下再詳細(xì)講解下這個(gè)流程吧。
當(dāng)我們點(diǎn)擊App時(shí),調(diào)用了Activity的startActivity,接著調(diào)用了startActivityForResult。
@Override
public void startActivity(Intent intent) {
this.startActivity(intent, null); // <------調(diào)用
}
@Override
public void startActivity(Intent intent, @Nullable Bundle options) {
if (options != null) {
startActivityForResult(intent, -1, options); // <------調(diào)用
} else {
startActivityForResult(intent, -1);
}
}
public void startActivityForResult(@RequiresPermission Intent intent, int requestCode,
@Nullable Bundle options) {
if (mParent == null) {
options = transferSpringboardActivityOptions(options);
Instrumentation.ActivityResult ar =
mInstrumentation.execStartActivity(
this, mMainThread.getApplicationThread(), mToken, this,
intent, requestCode, options);// <------調(diào)用 來到這里: mInstrumentation.execStartActivity?。?!
if (ar != null) {
mMainThread.sendActivityResult(
mToken, mEmbeddedID, requestCode, ar.getResultCode(),
ar.getResultData());
}
if (requestCode >= 0) {
mStartedActivity = true;
}
cancelInputsAndStartExitTransition(options);
} else {
if (options != null) {
mParent.startActivityFromChild(this, intent, requestCode, options);
} else {
mParent.startActivityFromChild(this, intent, requestCode);
}
}
}
看到代碼,會(huì)調(diào)用startActivityForResult中的 mInstrumentation.execStartActivity,那這個(gè)Instrumentation又是有什么作用的呢?一環(huán)套著一環(huán)!
遠(yuǎn)處慢慢飄來Instrumentation的介紹。
Base class for implementing application instrumentation code. When running with instrumentation turned on, this class will be instantiated for you before any of the application code, allowing you to monitor all of the interaction the system has with the application. An Instrumentation implementation is described to the system through an AndroidManifest.xml's <instrumentation> tag.
這個(gè)是Android系統(tǒng)對它的一個(gè)定義,說了什么呢?我們來翻譯一下,現(xiàn)在知道英語好的重要性了嗎?
用于實(shí)現(xiàn)應(yīng)用程序代碼的基類。當(dāng)使用Instrumentation進(jìn)行運(yùn)行時(shí),該類將在任何應(yīng)用程序代碼之前為您實(shí)例化,允許您監(jiān)視系統(tǒng)與應(yīng)用程序之間的所有交互。Instrumentation實(shí)現(xiàn)了系統(tǒng)通過AndroidManifest. xml的<instrumentation>標(biāo)簽。
簡單來說 Instrumentation ,它擁有強(qiáng)大的跟蹤Application以及Activity生命周期的功能,而且一個(gè)應(yīng)用有且僅有一個(gè) Instrumentation,并且每個(gè)Activity都有一個(gè) Instrumentation 的引用。ActivityThread 要?jiǎng)?chuàng)建或暫停某個(gè)Activity時(shí),都需要通過 Instrumentation 來進(jìn)行具體的操作。
public ActivityResult execStartActivity(
Context who, IBinder contextThread, IBinder token, Activity target,
Intent intent, int requestCode, Bundle options) {
IApplicationThread whoThread = (IApplicationThread) contextThread;
// 自動(dòng)屏蔽一些不重要的代碼,易于查看重點(diǎn)內(nèi)容??!
try {
intent.migrateExtraStreamToClipData();
intent.prepareToLeaveProcess(who);
int result = ActivityManagerNative.getDefault()
.startActivity(whoThread, who.getBasePackageName(), intent,
intent.resolveTypeIfNeeded(who.getContentResolver()),
token, target != null ? target.mEmbeddedID : null,
requestCode, 0, null, options);
checkStartActivityResult(result, intent);
} catch (RemoteException e) {
}
return null;
}
我們又發(fā)現(xiàn)了 startActivity 這個(gè)方法,剛剛我們說到了, Instrumentation 擁有強(qiáng)大的跟蹤Application以及Activity生命周期的功能,那么說吧,它就是完成對Application以及Activity初始化和管理生命周期的一個(gè)大管家,我就舉幾個(gè)例子給你看看,什么叫證據(jù)!
public void callActivityOnStart(Activity activity) {
activity.onStart();
}
public void callActivityOnRestart(Activity activity) {
activity.onRestart();
}
public void callActivityOnResume(Activity activity) {
activity.mResumed = true;
activity.onResume();
if (mActivityMonitors != null) {
synchronized (mSync) {
final int N = mActivityMonitors.size();
for (int i=0; i<N; i++) {
final ActivityMonitor am = mActivityMonitors.get(i);
am.match(activity, activity, activity.getIntent());
}
}
}
}
這些方法都是Acitivity生命周期的方法吧?所以說,Instrumentation 是非常重要的,但是,你會(huì)發(fā)現(xiàn),這個(gè) Instrumentation 非常重要,你在編程的時(shí)候有用到這個(gè)東西嗎?并沒有,可見它只是在背后默默地做出自己的奉獻(xiàn)!
介紹完 Instrumentation ,我們再回到 execStartActivity 這個(gè)方法,出現(xiàn)了一個(gè)新面孔 ActivityManagerNative ,直接來看下它的代碼實(shí)現(xiàn)吧。
public abstract class ActivityManagerNative extends Binder implements IActivityManager
{
/**
* 將綁定對象插入活動(dòng)管理器接口,如果需要生成代理。
*/
static public IActivityManager asInterface(IBinder obj) {
if (obj == null) {
return null;
}
IActivityManager in =
(IActivityManager)obj.queryLocalInterface(descriptor);
if (in != null) {
return in;
}
return new ActivityManagerProxy(obj); // <------獲取到了一個(gè)ActivityManagerProxy對象,而且傳遞了一個(gè)IBinder進(jìn)去,這個(gè)IBidder就是用來進(jìn)行IPC通信的。
}
/**
* 檢索系統(tǒng)的默認(rèn)/全局活動(dòng)管理器。
*/
static public IActivityManager getDefault() {
return gDefault.get();
}
private static final Singleton<IActivityManager> gDefault = new Singleton<IActivityManager>() {
protected IActivityManager create() {
IBinder b = ServiceManager.getService("activity");
if (false) {
Log.v("ActivityManager", "default service binder = " + b);
}
IActivityManager am = asInterface(b);
if (false) {
Log.v("ActivityManager", "default service = " + am);
}
return am;
}
};
從上面的代碼我們可以了解到 ActivityManagerNative 是 Binder的一個(gè)子類,并且實(shí)現(xiàn)了IActivityManager 這個(gè)接口,得到 ActivityManagerProxy 這個(gè)對象,正如上面我們所說的:
下發(fā)了命令之后通過 IActivityManager 的修飾封裝, startActivity 這個(gè)命令,通過 ActivityManagerProxy 把命令傳遞到執(zhí)行者 ActivityManagerService 手中,再進(jìn)行相應(yīng)的處理。
我們已經(jīng)到達(dá)了命令封裝,然后叫給傳達(dá)者 ActivityManagerProxy 這一步,接下來就是看傳達(dá)者 ActivityManagerProxy 如何將命令交給執(zhí)行者 ActivityManagerService 了。
我們走近一步,來瞧一瞧 ActivityManagerProxy 中的startActivity()方法是如何編寫的。
public int startActivity(IApplicationThread caller, String callingPackage, Intent intent,
String resolvedType, IBinder resultTo, String resultWho, int requestCode,
int startFlags, ProfilerInfo profilerInfo, Bundle options) throws RemoteException {
Parcel data = Parcel.obtain();
Parcel reply = Parcel.obtain();
data.writeInterfaceToken(IActivityManager.descriptor);
data.writeStrongBinder(caller != null ? caller.asBinder() : null);
data.writeString(callingPackage);
intent.writeToParcel(data, 0);
data.writeString(resolvedType);
data.writeStrongBinder(resultTo);
data.writeString(resultWho);
data.writeInt(requestCode);
data.writeInt(startFlags);
if (profilerInfo != null) {
data.writeInt(1);
profilerInfo.writeToParcel(data, Parcelable.PARCELABLE_WRITE_RETURN_VALUE);
} else {
data.writeInt(0);
}
if (options != null) {
data.writeInt(1);
options.writeToParcel(data, 0);
} else {
data.writeInt(0);
}
mRemote.transact(START_ACTIVITY_TRANSACTION, data, reply, 0);
reply.readException();
int result = reply.readInt();
reply.recycle();
data.recycle();
return result;
}
相信你也可以看到,通過傳到 ActivityManagerProxy 的IBinder,利用這個(gè)對象,調(diào)用了transact()方法,把所有參數(shù)封裝成了Parcel對象,這樣就向 ActivityManagerService 發(fā)射信號彈,進(jìn)行通信了,執(zhí)行者 ActivityManagerService 收到指令后立馬進(jìn)行了處理。
我深吸一口氣,什么 Proxy 、ActivityManagerService 等等一直在我腦海里回旋,突然想起了一個(gè)設(shè)計(jì)模式好像就是這樣的啊,就是那個(gè)叫代理模式的。
代理:為其他對象提供一種代理以控制對這個(gè)對象的訪問。在某些情況下,一個(gè)對象不適合或者不能直接引用另一個(gè)對象,而代理對象可以在客戶端和目標(biāo)對象之間起到中介的作用。
對,就是這樣的,看來今天的知識(shí)要好好消化一下了。
“等等,先別想其他的,你以為到這一步就結(jié)束了嗎?剛剛才到執(zhí)行者這邊呢,還有一段路要走啊,我們接著看吧”,還有啊...我當(dāng)時(shí)的內(nèi)心是崩潰的,還以為就這樣結(jié)束了。
當(dāng) ActivityManagerService 接收到指令之后,正式開始啟動(dòng)Activity,這時(shí),ActivityManagerService 要作出嚴(yán)格的審核過程。只見它把指令轉(zhuǎn)換為了 ResolveInfo 。
ResolveInfo:從一個(gè)intent對應(yīng)的IntentFilter所解析獲取的信息。這部分地對應(yīng)于從AndroidManifest .xml的<intent>標(biāo)簽。
然后 ActivityManagerService 調(diào)用 startActivityLocked() 方法進(jìn)行下一步,再來到startSpecificActivityLocked() 方法,這時(shí)候就需要判斷是否需要?jiǎng)?chuàng)建一個(gè)全新的進(jìn)程,如果需要?jiǎng)t調(diào)用startProcessLocked() 方法進(jìn)行創(chuàng)建,而在這個(gè)方法的內(nèi)部有一個(gè)Process.start的方法,這個(gè)時(shí)候正式到了我們的 ActivityThread 的工作,還記得在介紹 Zygote 時(shí),它會(huì)打開一個(gè)Socket來監(jiān)聽需要?jiǎng)?chuàng)建 Process 的請求嗎? Zygote 會(huì)不斷取出建立的連接,再進(jìn)行 fork 進(jìn)程,這就是我們的應(yīng)用進(jìn)程了,而且返回了每個(gè)進(jìn)程所對應(yīng)的 process id,這時(shí)就回到了 ActivityThread ,眾所周知的UI線程,進(jìn)行處理頁面的顯示,它將和 ActivityManagerService 配合,一起完成接下來的工作,比如activity的管理。到此,整個(gè)應(yīng)用啟動(dòng)完畢,所有的工作就告一段落了。
贈(zèng)一個(gè)高清大圖!

虎穴,關(guān)閉!
“好了,本章的學(xué)習(xí)就要結(jié)束了,回去好好回味一下吧,老規(guī)矩,我還是要提一個(gè)問題給你,不過這個(gè)問題你可以回去好好想想的,不用著急回答我”。
既然,我們從底層去學(xué)習(xí)了整個(gè)app的啟動(dòng)過程,那對于上一章所講到的優(yōu)化啟動(dòng)時(shí)間有什么作用呢?
我?guī)е麄€(gè)問題回到了現(xiàn)實(shí),只是,這一次回來之后感覺頭腦一片模糊,知識(shí)量對于我這種新手來說確實(shí)是大了些,只能在以后的編程路上不斷去琢磨了。
為了進(jìn)步,只能不斷地學(xué)習(xí)和總結(jié)!