Android Activity——啟動過程探索(一)

Activity 系列博客

Activity 生命周期:

activity_lifecycle.png

首先來看一下當Activity啟動時,會回調(diào)哪些生命周期的方法:

  • 不關(guān)閉當前Activity啟動流程:
不關(guān)閉當前Activity啟動流程.jpg
  • 關(guān)閉當前Activity啟動流程:
關(guān)閉當前Activity啟動流程.jpg

對于上面的回調(diào)過程,我想大部分Android開發(fā)者都是知道的,但是對于系統(tǒng)是怎樣一步一步來回調(diào)這些方法的,可能存在不少疑問。下面我們就通過源碼來看看當我們調(diào)用 startActivity()finish() 方法時系統(tǒng)是怎樣一步步來回調(diào)各個方法的。

其實對于每一個生命周期方法的調(diào)用,都可以看做是一小步,所以我們的分析就可以比較簡單的進行分步:

  1. 當前Activity調(diào)用 onPause()
  2. 新的Activity調(diào)用 onCreate()
  3. 新的Activity調(diào)用 onStart()
  4. 新的Activity調(diào)用 onResume()
  5. 當前Activity調(diào)用 onStop()
  6. 當前Activity調(diào)用 onDestory()【前提是調(diào)用了 finish() 方法】

在實際中,除了以上的生命周期方法回調(diào)外,還有一些回調(diào)方法也是比較重要的(比如:attach()、onRestart()等),就不在單獨分析,而是在對應(yīng)的地方一起分析了。

注意:以下分析過程,源碼版本為 Android 10(Api 29),不同Android版本可能有一些差別。

當前Activity調(diào)用 onPause() 過程

Activity 啟動流程-1. 當前Activity流程 onPause().png

根據(jù)上圖查看對應(yīng)的方法:

當我們調(diào)用 startActivity() 之后,系統(tǒng)按如下步驟執(zhí)行:

-> Activity#startActivity()
-> Activity#startActivityForResult()
-> Instrumentation#execStartActivity(activity, mMainThread.getApplicationThread(), mToken, this,intent, requestCode, options)

說明:

  1. mMainThread.getApplicationThread() 返回 ApplicationThread
  2. ApplicationThread 的聲明為 ActivityThread.ApplicationThread extends IApplicationThread.Stub

-> ActivityTaskManagerService#startActivity()

說明:

  1. ActivityTaskManagerService 通過 ActivityTaskManager.getService() 獲取
  2. ActivityTaskManager.getService() 返回 IActivityTaskManager
  3. ActivityTaskManagerService 的聲明為 ActivityTaskManagerService extends IActivityTaskManager.Stub,所以上一步是: ActivityTaskManagerService#startActivity()

-> ActivityTaskManagerService#startActivityAsUser()

說明:

  1. 會多次調(diào)用重載方法,這里就看做一步了,最終走到 下一步

-> ActivityStartController#obtainStarter()

說明:

  1. ActivityStartController 通過 getActivityStartController() 方法獲取
  2. ActivityStartController.obtainStarter() 方法返回的是ActivityStarter對象
  3. 然后設(shè)置數(shù)據(jù),實際調(diào)用的都是 ActivityStarter 中的設(shè)置數(shù)據(jù)方法,最終調(diào)用 ActivityStarter 的 execute() 方法

具體代碼如下:

    getActivityStartController().obtainStarter(intent, "startActivityAsUser")
                .setCaller(caller)
                .setCallingPackage(callingPackage)
                .setResolvedType(resolvedType)
                .setResultTo(resultTo)
                .setResultWho(resultWho)
                .setRequestCode(requestCode)
                .setStartFlags(startFlags)
                .setProfilerInfo(profilerInfo)
                .setActivityOptions(bOptions)
                .setMayWait(userId) // 注意該方法,會將ActivityStarter mRequest.mayWait = true;
                .execute();

-> ActivityStarter#execute()

說明:

  1. 上一步的 setMayWait() 方法 會將 ActivityStarter 中的 mRequest.mayWait 標識置為 true,在 execute() 方法中會通過該標記判斷下一步執(zhí)行的方法

-> ActivityStarter#startActivityMayWait()
-> ActivityStarter#startActivity()

說明:

  1. 會多次調(diào)用重載 startActivity() 方法,這里就看做一步了,最終走到 下一步

-> ActivityStarter#startActivityUnchecked()
-> RootActivityContainer#resumeFocusedStacksTopActivities()

說明:

  1. 調(diào)用重載無參數(shù)方法,由無參數(shù)方法調(diào)用有參數(shù)方法,參數(shù)都為null,看做一步,走到下一步

-> ActivityStack#resumeTopActivityUncheckedLocked()
-> ActivityStack#resumeTopActivityInnerLocked()
-> ActivityStack#startPausingLocked()

startPausingLocked() 方法中有如下代碼:

mService.getLifecycleManager().scheduleTransaction(prev.app.getThread(),
                    prev.appToken, PauseActivityItem.obtain(prev.finishing, userLeaving,
                            prev.configChangeFlags, pauseImmediately));

說明:

  1. mService.getLifecycleManager() 方法返回的對象是 ClientLifecycleManager,(其中mService 是 ActivityTaskManagerService)
  2. 重點注意方法中的幾個參數(shù):
    1. 第一個參數(shù) prev.app.getThread() 獲取到的是 IApplicationThread(IApplicationThread 的聲明在上面已經(jīng)說明了)
    2. 第三個參數(shù) PauseActivityItem.obtain(),注意PauseActivityItem類: PauseActivityItem extends ActivityLifecycleItem

-> ClientLifecycleManager#scheduleTransaction(IApplicationThread client, IBinder activityToken,ActivityLifecycleItem stateRequest)

注意 scheduleTransaction() 方法的代碼:

final ClientTransaction clientTransaction = transactionWithState(client, activityToken,stateRequest);
scheduleTransaction(clientTransaction);

構(gòu)建了一個 ClientTransaction 對象 clientTransaction 進行傳遞

-> ClientLifecycleManager#scheduleTransaction(ClientTransaction transaction)
-> ClientTransaction#schedule()
-> IApplicationThread#scheduleTransaction()

說明:

  1. IApplicationThread就是ActivityThread.ApplicationThread
  2. 在 ActivityThread.ApplicationThread 中直接調(diào)用了 ActivityThread.this.scheduleTransaction(transaction),所以最終調(diào)用的是 ActivityThread#scheduleTransaction(),但是 ActivityThread 中并沒有這個方法,是在其父類 ClientTransactionHandler 中的方法( ActivityThread extends ClientTransactionHandler)

-> ClientTransactionHandler#sendMessage()

說明:

  1. sendMessage() 方法在 ClientTransactionHandler中定義,由子類 ActivityThread 實現(xiàn)

  2. 在sendMessage()方法中傳遞的 what 是 ActivityThread.H.EXECUTE_TRANSACTION

  3. 在ActivityThread中的handler消息都是由 ActivityThread 內(nèi)部類 H 負責處理,所以查看 H 類中 handleMessage() 方法對應(yīng)的處理邏輯

     case EXECUTE_TRANSACTION:
         final ClientTransaction transaction = (ClientTransaction) msg.obj;
         mTransactionExecutor.execute(transaction);
         if (isSystem()) {
             transaction.recycle();
         }
         break;
    
  4. mTransactionExecutor 對象是 TransactionExecutor

-> TransactionExecutor#execute(transaction)

說明:

  1. 參數(shù) transaction 就是上面構(gòu)建的 ClientTransaction 對象

-> TransactionExecutor#executeLifecycleState(transaction)

final ActivityLifecycleItem lifecycleItem = transaction.getLifecycleStateRequest();
lifecycleItem.execute(mTransactionHandler, token, mPendingActions);

說明:

  1. transaction.getLifecycleStateRequest() 獲取到 ActivityLifecycleItem 對象,在這里實際上獲取到的就是 PauseActivityItem 對象,上面我們在 ActivityStack#startPausingLocked() 中已經(jīng)說到了

-> PauseActivityItem#execute()
-> ClientTransactionHandler#handlePauseActivity()

說明:

  1. handlePauseActivity() 方法在 ClientTransactionHandler中定義,由子類 ActivityThread 實現(xiàn),所以查看 ActivityThread 的 handlePauseActivity()

-> ActivityThread#performPauseActivity()
-> ActivityThread#performPauseActivityIfNeeded()
-> Instrumentation#callActivityOnPause()
-> Activity#performPause()
-> Activity#onPause()

通過以上過程,最終調(diào)用了Activity 的 onPause() 回調(diào)方法,到此為止,我們啟動Activity的第一步,當前Activity的onPause()回調(diào)執(zhí)行過程就完成了。接下來,查看第二步創(chuàng)建新的Activity實例,并執(zhí)行 onCreate() 回調(diào)。

新的Activity調(diào)用 onCreate()

Activity 啟動流程-2. 新的Activity流程 attach()、onCreate().png

根據(jù)上圖查看對應(yīng)的方法:

當我們調(diào)用 startActivity() 之后,系統(tǒng)按如下步驟執(zhí)行:

-> Activity#startActivity()
-> Activity#startActivityForResult()
-> Instrumentation#execStartActivity(activity, mMainThread.getApplicationThread(), mToken, this,intent, requestCode, options)

說明:

  1. mMainThread.getApplicationThread() 返回 ApplicationThread
  2. ApplicationThread 的聲明為 ActivityThread.ApplicationThread extends IApplicationThread.Stub

-> ActivityTaskManagerService#startActivity()

說明:

  1. ActivityTaskManagerService 通過 ActivityTaskManager.getService() 獲取
  2. ActivityTaskManager.getService() 返回 IActivityTaskManager
  3. ActivityTaskManagerService 的聲明為 ActivityTaskManagerService extends IActivityTaskManager.Stub,所以上一步是: ActivityTaskManagerService#startActivity()

-> ActivityTaskManagerService#startActivityAsUser()

說明:

  1. 會多次調(diào)用重載方法,這里就看做一步了,最終走到 下一步

-> ActivityStartController#obtainStarter()

說明:

  1. ActivityStartController 通過 getActivityStartController() 方法獲取
  2. ActivityStartController.obtainStarter() 方法返回的是ActivityStarter對象
  3. 然后設(shè)置數(shù)據(jù),實際調(diào)用的都是 ActivityStarter 中的設(shè)置數(shù)據(jù)方法,最終調(diào)用 ActivityStarter 的 execute() 方法

具體代碼如下:

    getActivityStartController().obtainStarter(intent, "startActivityAsUser")
                .setCaller(caller)
                .setCallingPackage(callingPackage)
                .setResolvedType(resolvedType)
                .setResultTo(resultTo)
                .setResultWho(resultWho)
                .setRequestCode(requestCode)
                .setStartFlags(startFlags)
                .setProfilerInfo(profilerInfo)
                .setActivityOptions(bOptions)
                .setMayWait(userId) // 注意該方法,會將ActivityStarter mRequest.mayWait = true;
                .execute();

-> ActivityStarter#execute()

說明:

  1. 上一步的 setMayWait() 方法 會將 ActivityStarter 中的 mRequest.mayWait 標識置為 true,在 execute() 方法中會通過該標記判斷下一步執(zhí)行的方法

-> ActivityStarter#startActivityMayWait()
-> ActivityStarter#startActivity()

說明:

  1. 會多次調(diào)用重載 startActivity() 方法,這里就看做一步了,最終走到 下一步

-> ActivityStarter#startActivityUnchecked()
-> RootActivityContainer#resumeFocusedStacksTopActivities()

說明:

  1. 調(diào)用重載無參數(shù)方法,由無參數(shù)方法調(diào)用有參數(shù)方法,參數(shù)都為null,看做一步,走到下一步

-> ActivityStack#resumeTopActivityUncheckedLocked()
-> ActivityStack#resumeTopActivityInnerLocked()
-> ActivityStackSupervisor#startSpecificActivityLocked()
-> ActivityStackSupervisor#realStartActivityLocked()

realStartActivityLocked() 方法中有如下代碼:

// Create activity launch transaction.
final ClientTransaction clientTransaction = ClientTransaction.obtain(
        proc.getThread(), r.appToken);

final DisplayContent dc = r.getDisplay().mDisplayContent;
clientTransaction.addCallback(LaunchActivityItem.obtain(new Intent(r.intent),
        System.identityHashCode(r), r.info,
        mergedConfiguration.getGlobalConfiguration(),
        mergedConfiguration.getOverrideConfiguration(), r.compat,
        r.launchedFromPackage, task.voiceInteractor, proc.getReportedProcState(),
        r.icicle, r.persistentState, results, newIntents,
        dc.isNextTransitionForward(), proc.createProfilerInfoIfNeeded(),r.assistToken));

mService.getLifecycleManager().scheduleTransaction(clientTransaction);

說明:

  1. mService.getLifecycleManager() 方法返回的對象是 ClientLifecycleManager,(其中mService 是 ActivityTaskManagerService)
  2. 創(chuàng)建 ClientTransaction 對象后,調(diào)用了它的 addCallback() 方法,增加了 LaunchActivityItem 對象(LaunchActivityItem extends ClientTransactionItem)

-> ClientLifecycleManager#scheduleTransaction(ClientTransaction transaction)
-> ClientTransaction#schedule()
-> IApplicationThread#scheduleTransaction()

說明:

  1. IApplicationThread就是ActivityThread.ApplicationThread
  2. 在 ActivityThread.ApplicationThread 中直接調(diào)用了 ActivityThread.this.scheduleTransaction(transaction),所以最終調(diào)用的是 ActivityThread#scheduleTransaction(),但是 ActivityThread 中并沒有這個方法,是在其父類 ClientTransactionHandler 中的方法( ActivityThread extends ClientTransactionHandler)

-> ClientTransactionHandler#sendMessage()

說明:

  1. sendMessage() 方法在 ClientTransactionHandler中定義,由子類 ActivityThread 實現(xiàn)

  2. 在sendMessage()方法中傳遞的 what 是 ActivityThread.H.EXECUTE_TRANSACTION

  3. 在ActivityThread中的handler消息都是由 ActivityThread 內(nèi)部類 H 負責處理,所以查看 H 類中 handleMessage() 方法對應(yīng)的處理邏輯

     case EXECUTE_TRANSACTION:
         final ClientTransaction transaction = (ClientTransaction) msg.obj;
         mTransactionExecutor.execute(transaction);
         if (isSystem()) {
             transaction.recycle();
         }
         break;
    
  4. mTransactionExecutor 對象是 TransactionExecutor

-> TransactionExecutor#execute(transaction)

說明:

  1. 參數(shù) transaction 就是上面 realStartActivityLocked() 方法中傳遞的對象

-> TransactionExecutor#executeCallbacks(transaction)

final ClientTransactionItem item = callbacks.get(i);
item.execute(mTransactionHandler, token, mPendingActions);

說明:

  1. callbacks.get(i) 獲取到 ClientTransactionItem 對象,在這里實際上獲取到的就是 LaunchActivityItem 對象,是在 realStartActivityLocked() 方法中通過 ClientTransaction 對象的 addCallback() 方法增加的

-> LaunchActivityItem#execute()
-> ClientTransactionHandler#handleLaunchActivity()

說明:

  1. handleLaunchActivity() 方法在 ClientTransactionHandler中定義,由子類 ActivityThread 實現(xiàn),所以查看 ActivityThread 的 handleLaunchActivity()

-> ActivityThread#performLaunchActivity()

// 通過反射創(chuàng)建Activity對象
java.lang.ClassLoader cl = appContext.getClassLoader();
activity = mInstrumentation.newActivity(cl, component.getClassName(), r.intent);

// Instrumentation.newActivity 方法
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);
}

// getFactory() 返回 AppComponentFactory 對象
// AppComponentFactory.instantiateActivity() 方法通過反射完成類實例對象的創(chuàng)建
public @NonNull Activity instantiateActivity(@NonNull ClassLoader cl, @NonNull String className,
        @Nullable Intent intent)
        throws InstantiationException, IllegalAccessException, ClassNotFoundException {
    return (Activity) cl.loadClass(className).newInstance();
}

-> Instrumentation#newActivity()
-> Activity#attach()
-> Instrumentation#callActivityOnCreate
-> Activity#performCreate()
-> Activity#onCreate()

通過以上過程,最終調(diào)用了Activity 的 attach() 和 onCreate() 回調(diào)方法,到此為止,我們需要啟動的Activity已經(jīng)完成了對象的創(chuàng)建,并且回調(diào)了對應(yīng)的聲明周期方法。到此為止,我們的Activity已經(jīng)算是正式啟動了,只是還需要繼續(xù)回調(diào)其他的聲明周期方法以完成對用戶可見和可操作的過程。

相關(guān)擴展:

ContextImpl的創(chuàng)建

在 ActivityThread#performLaunchActivity() 方法中,Instrumentation.newActivity() 之前通過 createBaseContextForActivity() 方法創(chuàng)建了 ContextImpl 對象

ContextImpl appContext = ContextImpl.createActivityContext(
            this, r.packageInfo, r.activityInfo, r.token, displayId, r.overrideConfig);

// ContextImpl.createActivityContext()
ContextImpl context = new ContextImpl(null, mainThread, packageInfo, activityInfo.splitName,
            activityToken, null, 0, classLoader, null);

Application的創(chuàng)建

在 ActivityThread#performLaunchActivity() 方法中,Instrumentation.newActivity() 創(chuàng)建完 Activity 的實例之后,通過 LoadedApk#makeApplication() 返回了 Application

// LoadedApk.makeApplication()
public Application makeApplication(boolean forceDefaultAppClass,
        Instrumentation instrumentation) {
    if (mApplication != null) {
        return mApplication;
    }

    Application app = null;

    String appClass = mApplicationInfo.className;
    if (forceDefaultAppClass || (appClass == null)) {
        appClass = "android.app.Application";
    }

    try {
        java.lang.ClassLoader cl = getClassLoader();
        if (!mPackageName.equals("android")) {
            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER,
                    "initializeJavaContextClassLoader");
            initializeJavaContextClassLoader();
            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
        }
        ContextImpl appContext = ContextImpl.createAppContext(mActivityThread, this);
        app = mActivityThread.mInstrumentation.newApplication(
                cl, appClass, appContext);
        appContext.setOuterContext(app);
    } catch (Exception e) {
        
    }
    mActivityThread.mAllApplications.add(app);
    mApplication = app;

    if (instrumentation != null) {
        try {
            instrumentation.callApplicationOnCreate(app);
        } catch (Exception e) {
         
        }
    }
    return app;
}

以上代碼,先判斷 mApplication 是否為null,如果不為null就直接返回,如果為null,表示我們創(chuàng)建的Activity的LaunchActivity(啟動Activity),那么就需要創(chuàng)建Application對象,查看 Instrumentation 的 newApplication() 代碼中 Application 的創(chuàng)建過程

// Instrumentation.newApplication()
public Application newApplication(ClassLoader cl, String className, Context context)
        throws InstantiationException, IllegalAccessException, 
        ClassNotFoundException {
    Application app = getFactory(context.getPackageName())
            .instantiateApplication(cl, className);
    app.attach(context);
    return app;
}

// getFactory() 返回 AppComponentFactory 對象
// AppComponentFactory.instantiateApplication() 方法通過反射完成類實例對象的創(chuàng)建
public @NonNull Application instantiateApplication(@NonNull ClassLoader cl,
        @NonNull String className)
        throws InstantiationException, IllegalAccessException, ClassNotFoundException {
    return (Application) cl.loadClass(className).newInstance();
}

通過以上代碼,我們看到了Application創(chuàng)建完成之后就馬上調(diào)用了它的attach(context)方法。

最后通過 Instrumentation.callApplicationOnCreate() 調(diào)用 Application 的 onCreate() 方法:

if (instrumentation != null) {
    try {
        instrumentation.callApplicationOnCreate(app);
    } catch (Exception e) {
     
    }
}

public void callApplicationOnCreate(Application app) {
    app.onCreate();
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容