1. 前言
由于系統(tǒng)極強的封裝特性瘪校,我們在啟動 Activity 時并不知道系統(tǒng)內(nèi)部都是如何完成整個的啟動流程的车伞?如何創(chuàng)建一個 Activity 對象崎溃?什么時候調(diào)用 onCreate() 方法的侦厚?
本文中所有源碼都是基于 Android API 29哑梳。
2. Activity 的啟動方式
Activity 的啟動可以通過 startActivity()
或者 startActivityForResult()
劲阎,兩者的區(qū)別在于是否要接收來自被啟動 Activity 的返回結(jié)果。
Intent intent = new Intent(activity, CaptureActivity.class);
activity.startActivity(intent); //不接收來自 CaptureActivity 的返回結(jié)果
Intent intent = new Intent(activity, CaptureActivity.class); //接收來自 CaptureActivity 的返回結(jié)果
activity.startActivityForResult(intent, REQUEST_CAPTURE);
3. 源碼解析
3.1 啟動 Activity
無論我們是通過 startActivity() 各種重載的方法還是通過 startActivityForResult() 方法啟動 Activity鸠真,最后都會調(diào)用 Activity 的 startActivityForResult(Intent intent, int requestCode, Bundle options)悯仙。Context 是一個抽象類龄毡,有抽象方法 startActivity,ContextWrapper 繼承自 Context 锡垄,是 Context 的代理類沦零,實現(xiàn)了 startActivity;Activity 繼承自 ContextWrapperTheme货岭,ContextWrapperTheme 繼承自 ContextWrapper路操,所以最終在 Activity 中實現(xiàn)的 startActivity 實際上是抽象類 Context 中的 startActivity 方法。
-
startActivityForResult()
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);
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);
}
}
}
1)mParent千贯,是一個 Activity 對象屯仗,表示當(dāng)前 Activity 的父 Activity,判斷 mParent 是否為空搔谴,為空直接執(zhí)行步驟4祭钉,不為空執(zhí)行2,3己沛;
2)mInstrumentation.execStartActivity,調(diào)用了 Instrumentation 的 execStartActivity 方法距境;
3)mMainThread.sendActivityResult申尼,如果步驟2中返回結(jié)果不為空,調(diào)用ActivityThread 的 sendActivityResult 方法垫桂;
4)mParent 為空师幕,調(diào)用父 Activity 的 startActivityFromChild 方法;
先來看看步驟2中 Instrumentation 的 execStartActivity 方法诬滩,在這里利用了 Binder 機制霹粥,跨進(jìn)程調(diào)用了 ATMS(ActivityTaskManagerService)的 startActivity 方法,ATMS 運行在系統(tǒng)服務(wù)進(jìn)程中疼鸟。
public ActivityResult execStartActivity(
Context who, IBinder contextThread, IBinder token, Activity target,
Intent intent, int requestCode, Bundle options) {
IApplicationThread whoThread = (IApplicationThread) contextThread;
...
try {
intent.migrateExtraStreamToClipData();
intent.prepareToLeaveProcess(who);
int result = ActivityTaskManager.getService()
.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) {
throw new RuntimeException("Failure from system", e);
}
return null;
}
1)ActivityTaskManager.getService().startActivity 即是調(diào)用了 ATMS 的 startActivity 方法后控;
2)checkStartActivityResult(),檢查啟動 Activity 的結(jié)果空镜。
先來看 checkStartActivityResult 方法浩淘,主要是檢查啟動 Activity 的結(jié)果,有異常則拋出吴攒。例如下面代碼中是一個典型的未找到啟動 Activity 的異常张抄,因為我們沒有在 AndroidManifest 文件中聲明我們的 Activity。
public static void checkStartActivityResult(int res, Object intent) {
if (!ActivityManager.isStartResultFatalError(res)) {
return;
}
switch (res) {
case ActivityManager.START_INTENT_NOT_RESOLVED:
case ActivityManager.START_CLASS_NOT_FOUND:
if (intent instanceof Intent && ((Intent)intent).getComponent() != null)
throw new ActivityNotFoundException(
"Unable to find explicit activity class "
+ ((Intent)intent).getComponent().toShortString()
+ "; have you declared this activity in your AndroidManifest.xml?");
throw new ActivityNotFoundException(
"No Activity found to handle " + intent);
...
}
}
接著來看 ActivityTaskManager 的 getService 方法:
-
ActivityTaskManager
public static IActivityTaskManager getService() {
return IActivityTaskManagerSingleton.get();
}
private static final Singleton<IActivityTaskManager> IActivityTaskManagerSingleton =
new Singleton<IActivityTaskManager>() {
@Override
protected IActivityTaskManager create() {
final IBinder b = ServiceManager.getService(Context.ACTIVITY_TASK_SERVICE);
return IActivityTaskManager.Stub.asInterface(b);
}
};
這里是通過 Singleton 返回了一個 IActivityTaskManager 對象洼怔,Singleton 是一個單例的封裝類署惯,第一次調(diào)用它的get 方法時它會通過 create 方法來初始化一個 IActivityTaskManager,IActivityTaskManager 其實是一個 Binder 對象镣隶,負(fù)責(zé)應(yīng)用和 ActivityTaskManagerService (以下簡稱 ATMS)直接的通信极谊。
ATMS 運行在服務(wù)進(jìn)程(system_server)中诡右,Instrumentation 實現(xiàn)了應(yīng)用和 ATMS 之間的通信,Activity 的啟動就轉(zhuǎn)移到了 ATMS 中:
-
ActivityTaskManagerService
ATMS 中 startActivity 方法調(diào)用了 startActivityAsUser 方法怀酷,startActivityAsUser 調(diào)用了 ActivityStarter 的 execute 方法稻爬。
int startActivityAsUser(IApplicationThread caller, String callingPackage,
Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId,
boolean validateIncomingUser) {
userId = getActivityStartController().checkTargetUser(userId, validateIncomingUser,
Binder.getCallingPid(), Binder.getCallingUid(), "startActivityAsUser");
return getActivityStartController().obtainStarter(intent, "startActivityAsUser")
.setCaller(caller)
.setCallingPackage(callingPackage)
.setResolvedType(resolvedType)
.setResultTo(resultTo)
.setResultWho(resultWho)
.setRequestCode(requestCode)
.setStartFlags(startFlags)
.setProfilerInfo(profilerInfo)
.setActivityOptions(bOptions)
.setMayWait(userId)
.execute();
}
getActivityStartController() 獲取到 ActivityStarController 對象,調(diào)用 ActivityStarController 的 obtainStarter() 獲取 ActivityStarter 對象蜕依,ActivityStart 設(shè)置一些需要傳給應(yīng)用進(jìn)程的信息桅锄,然后調(diào)用了 ececute 方法。
-
ActivityStarter
execute 方法根據(jù)啟動請求調(diào)用 startActivityMayWait 方法或者 startActivity 方法样眠,直接來看 startActivity 方法友瘤,startActivity 方法調(diào)用了 startActivityUnchecked 方法,startActivityUnchecked 調(diào)用了 ActivityTask 的 sendActivityResultLocked 方法檐束。
//ActivityStarter
int execute() {
try {
if (mRequest.mayWait) {
return startActivityMayWait(...);
} else {
return startActivity(...);
}
} finally {
onExecutionComplete();
}
}
private ActivityStack mTargetStack;
//ActivityStarter#startActivityUnchecked()
mTargetStack.startActivityResultLocked(mStartActivity, topFocused, newTask, mKeepCurTransition,
mOptions);
-
ActivityTask
sendActivityResultLocked 方法通過 ActivityTaskManagerService 調(diào)用了 ClientLifecycleManager
的 scheduleTransaction 方法
void scheduleTransaction(ClientTransaction transaction) throws RemoteException {
final IApplicationThread client = transaction.getClient();
transaction.schedule();
if (!(client instanceof Binder)) {
transaction.recycle();
}
}
scheduleTransaction 方法通過 ClientTransaction 的 schedule 方法調(diào)用了 IApplicationThread
的 scheduleTransaction 方法辫秧。
private IApplicationThread mClient;
public void schedule() throws RemoteException {
mClient.scheduleTransaction(this);
}
-
IApplicationThread 和 ApplicationThread
IApplicationThread 繼承了 IInterface 接口,它是一個 Binder 類型的接口被丧,IApplicationThread 的最終實現(xiàn)類是 ActivityThread 的內(nèi)部類 ApplicationThread
盟戏。ApplicationThread 繼承自 ApplicationThreadNative
,ApplicationThreadNative 繼承自 Binder 并實現(xiàn)來 IApplicationThread 接口甥桂。ApplicationThreadNative 的作用和使用 AIDL 時系統(tǒng)生成的類是一樣柿究,它的內(nèi)部有一個 ApplicationThreadProxy 類,這個類也就是 AIDL 文件的代理類黄选。綜上所述蝇摸,IApplicationThread 的實現(xiàn)類就是 ApplicationThreadNative,而 ApplicationThreadNative 被定義為了抽象類办陷,那最終實現(xiàn)者就是 ApplicationThread貌夕。
-
ActivityThread
ApplicationThread 的 scheduleTransaction 方法調(diào)用了 ActivityThread 的 scheduleTransaction 方法,ActivityThread 繼承自 ClientTransactionHandler
民镜,ClientTransactionHandler 是抽象類啡专,它的 scheduleTransaction 方法中調(diào)用 sendMessage 方法發(fā)送了一條 EXECUTE_TRANSACTION 類型的消息,sendMessage 是抽象方法殃恒,ActivityThread 實現(xiàn)了該方法植旧,ActivityThread 的 sendMessage
方法中將要發(fā)送的消息封裝在 Message 中,通過 ActivityThread 的 H
對象 mH 執(zhí)行了消息的發(fā)送离唐,H 是 ActivityThread 的靜態(tài)內(nèi)部類病附,繼承自 Handler,用于接收并處理來自其他線程的消息亥鬓。
//ClientTransactionHandler
void scheduleTransaction(ClientTransaction transaction) {
transaction.preExecute(this);
sendMessage(ActivityThread.H.EXECUTE_TRANSACTION, transaction);
}
abstract void sendMessage(int what, Object obj);
//ActivityThread
private void sendMessage(int what, Object obj, int arg1, int arg2, boolean async) {
...
Message msg = Message.obtain();
msg.what = what;
msg.obj = obj;
msg.arg1 = arg1;
msg.arg2 = arg2;
if (async) {
msg.setAsynchronous(true);
}
mH.sendMessage(msg);
}
ActivityThread 中完沪,H
收到 EXECUTE_TRANSACTION 類型的消息,調(diào)用 TransactionExecutor
的 execute 方法,execute 方法調(diào)用了 executeCallbacks 方法覆积,executeCallbacks 中調(diào)用 LaunchActivityItem
的 execute 方法听皿,LaunchActivityItem 繼承自 ClientTransactionItem 并實現(xiàn)了 execute 方法,execute 方法調(diào)用了 ClientTransactionHandler
的 handleLaunchActivity 方法宽档,ActivityThread 繼承自 ClientTransactionHandler 尉姨,并實現(xiàn)了 handleLaunchActivity 方法,這里又回到了 ActivityThread
中的 handleLaunchActivity 方法內(nèi)吗冤,handleLaunchActivity 方法調(diào)用了 performLaunchActivity 方法又厉。
-
performLaunchActivity 方法:
1)從 ActivityClientRecord
中獲取待啟動 Activity 的啟動信息;
2)調(diào)用 createBaseContextForActivity 方法創(chuàng)建 ContextImpl
對象椎瘟,該方法中調(diào)用 ContextImpl 的 createActivityContext 方法創(chuàng)建 ContextImpl 對象覆致;
ContextImpl appContext = createBaseContextForActivity(r);
private ContextImpl createBaseContextForActivity(ActivityClientRecord r) {
...
ContextImpl appContext = ContextImpl.createActivityContext(
this, r.packageInfo, r.activityInfo, r.token, displayId, r.overrideConfig);
...
return appContext;
}
3)調(diào)用 Instrumentation
的 newActivity 方法新建并加載 Activity,newActivity 方法中調(diào)用 AppComponentFactory 的 instantiateActivity方法肺蔚,instantiateActivity 方法通過在 performLaunchActivity 方法中新建的 ClassLoader
加載新建的 Activity 類煌妈;
activity = mInstrumentation.newActivity(cl,component.getClassName(),r.intent);
//Instrumentation
public Activity newActivity(ClassLoader cl, String className,
Intent intent)
throws InstantiationException, IllegalAccessException,
ClassNotFoundException {
String pkg = intent != null && intent.getComponent() != null
? intent.getComponent().getPackageName() : null;
return getFactory(pkg).instantiateActivity(cl, className, intent);
}
//AppComponentFactory
public @NonNull Activity instantiateActivity(@NonNull ClassLoader cl, @NonNull String className,
@Nullable Intent intent)
throws InstantiationException, IllegalAccessException, ClassNotFoundException {
return (Activity) cl.loadClass(className).newInstance();
}
4)通過 LoadApk
的 makeApplication 方法創(chuàng)建一個 Application 對象;
Application app = r.packageInfo.makeApplication(false, mInstrumentation);
//r.packageInfo 就是 ActivityClientRecord 中存的 LoadApk 對象
5)調(diào)用 Activity 的 attach
方法宣羊,ContextImpl 通過 Activity 的 attach 方法來和 Activity 建立關(guān)聯(lián)璧诵,除此之外,attach 方法還完成了 Window 的創(chuàng)建并建立自己和 Window 的關(guān)聯(lián)仇冯,這樣當(dāng) Window 接收到外部輸入事件后就可以將事件傳遞給 Activity腮猖;
activity.attach(appContext, this, getInstrumentation(), r.token,
r.ident, app, r.intent, r.activityInfo, title, r.parent,
r.embeddedID, r.lastNonConfigurationInstances, config,
r.referrer, r.voiceInteractor, window, r.configCallback,
r.assistToken);
//Activity的attatch
//將創(chuàng)建的 Activity 和 ContextImpl
attachBaseContext(context); 建立關(guān)聯(lián)
//為新建的 Activity 創(chuàng)建 Window,用于接收到外部輸入事件后將事件傳給Activity
mWindow = new PhoneWindow(this, window, activityConfigCallback);
mWindow.setWindowControllerCallback(this);
mWindow.setCallback(this);
mWindow.setOnWindowDismissedCallback(this);
mWindow.getLayoutInflater().setPrivateFactory(this);
6)調(diào)用 Instrumentation
的 callActivityOnCreate 方法赞枕,callActivityOnCreate 方法調(diào)用 Activity
的 performCreate 方法,performCreate 調(diào)用 onCreate
方法坪创。
mInstrumentation.callActivityOnCreate(activity, r.state);
//Instrumentation
public void callActivityOnCreate(Activity activity, Bundle icicle) {
prePerformCreate(activity);
activity.performCreate(icicle);
postPerformCreate(activity);
}
//Activity
final void performCreate(Bundle icicle, PersistableBundle persistentState) {
...
if (persistentState != null) {
onCreate(icicle, persistentState);
} else {
onCreate(icicle);
}
...
}
至此走完了從發(fā)起啟動 Activity 的請求炕婶、Activity 的創(chuàng)建、Activity 的加載到最后調(diào)用 onCreate 方法的整個流程莱预。這里只是分析整個的流程大概柠掂,涉及到啟動模式等的細(xì)節(jié)沒有去探討。
4. 總結(jié)
4.1 重要類
- Instrumentation:管理應(yīng)用進(jìn)程和系統(tǒng)進(jìn)程之間的通信依沮;
- ActivityTaskManager:實現(xiàn)應(yīng)用進(jìn)程和運行在系統(tǒng)進(jìn)程的 ActivityTaskManagerService 的通信涯贞;
- ActivityTaskManagerService:負(fù)責(zé)管理activity;
- ActivityStarter:負(fù)責(zé)啟動模式危喉,啟動Flag相關(guān)處理宋渔;
- ActivityStack:負(fù)責(zé)管理單獨棧的 Activity 和其狀態(tài),即具體啟動的執(zhí)行等辜限;
- ApplicationThread(IApplicationThread):繼承自 IApplicationThread皇拣,會在 ActivityTask 中調(diào)用,處理 Activity、Service氧急、Broadcast 的創(chuàng)建等操作颗胡;
- ActivityThread(ClientTransactionHandler):繼承自 ClientTransactionHandler,管理應(yīng)用進(jìn)程中主線程吩坝,執(zhí)行和調(diào)度 Activity毒姨、廣播,處理來自 Activity 的任務(wù)請求钉寝;
- ActivityClientRecord:保存和 Activity 相關(guān)的參數(shù)信息弧呐,還保存了和 Activity 關(guān)聯(lián)的 Window 的信息;
4.2 完整流程圖
5. 參考
- Activity 啟動流程分析
- 深入研究源碼:Activity 啟動流程分析
- 《Android 開發(fā)藝術(shù)探索》