分析流程基于Android8.0源碼
一般情況下我們通過Activity中的startActivity方法啟動一個Activity夭苗。這個流程中涉及一下幾個類:
android.app.Activity
android.app.Instrumentation
com.android.server.am.ActivityManagerService
com.android.server.am.ActivityStarter
com.android.server.am.ActivityStackSupervisor
android.app.ActivityThread
android.app.ActivityThread$ApplicationThread
通過下圖了解一下各個類之間的調用關系
整個流程如上圖所示销斟,多數(shù)代碼直接跟著進就可以看到本姥,這里主要說一下兩次IPC矛市,通過每個類的包名可以間接反映出整個啟動過程是一個C/S結構的跨進程操作豹绪。第一次跨進程是在Instumentation內(nèi)部調用ActivityManagerService的startActivity方法時,代碼如下:
int result = ActivityManager.getService()
.startActivity(whoThread, who.getBasePackageName(), intent,
intent.resolveTypeIfNeeded(who.getContentResolver()),
token, target != null ? target.mEmbeddedID : null,
requestCode, 0, null, options);
看一下ActivityManager:
public static IActivityManager getService() {
return IActivityManagerSingleton.get();
}
private static final Singleton<IActivityManager> IActivityManagerSingleton =
new Singleton<IActivityManager>() {
@Override
protected IActivityManager create() {
final IBinder b = ServiceManager.getService(Context.ACTIVITY_SERVICE);
final IActivityManager am = IActivityManager.Stub.asInterface(b);
return am;
}
};
這里通過ServiceManager.getService(Context.ACTIVITY_SERVICE)返回一個IActivityManager,就是一個ActivityManagerService钦椭,IActivityManager在/frameworks/base/core/java/android/app/目錄下,是一個AIDL文件碑诉,里邊聲明了startActivity方法
interface IActivityManager {
...
int startActivity(...);
...
}
ActivityManagerService繼承了IActivityManager.Stub彪腔,實現(xiàn)StartActivity方法。這個方法的調用是在系統(tǒng)進程进栽,之后的邏輯在系統(tǒng)進程里執(zhí)行德挣。
中間跟蹤的代碼如圖,到ActivityStackSupervisor類中的realStartActivityLocked方法:
final boolean realStartActivityLocked(...) throws RemoteException {
...
app.thread.scheduleLaunchActivity();
...
}
這里app.thread是一個ApplicationThread對象快毛,ApplicationThread是ActivityThread的一個內(nèi)部類格嗅,看一下ApplicationThread的相關代碼:
private class ApplicationThread extends IApplicationThread.Stub {
@Override
public final void scheduleLaunchActivity(...) {
...
}
ApplicationThread繼承了IApplicationThread.Stub,這里也是跨進程的一步唠帝,這個時候就從系統(tǒng)進程回到了應用自己的進程屯掖,然后通過反射獲取Activity實例,實例化Context襟衰,并調用獲取Activity實例的attach方法贴铜,傳入Context。最后調用到Activity的聲明周期的方法。
總結:應用內(nèi)啟動Activity的邏輯主要經(jīng)歷了兩次的跨進程過程绍坝,首先從應用自己進程跨進程到系統(tǒng)進程徘意,處理Activity創(chuàng)建過程中的標志位判斷,Activity所在的ActivityStack判斷轩褐、初始化椎咧,等等,最后跨進程會應用自己進程實例化Activity把介,并調用Activity的生命周期方法邑退。