Android 9.0 Activity啟動流程分析

前言
Activity可以算得上是Android開發(fā)中接觸最早和最多的一個類了首尼,簡單的使用相信大家都很熟悉了,本文主要分析一下Activity的啟動流程,有助于加深我們對于Android知識體系的理解持舆,拓寬我們的視野板驳。

源碼分析

首先強調(diào)一下又跛,本文的分析基于Android 9.0(API Level 28)的源碼,不同版本的源碼可能有些不同若治,大體流程還是差不多的慨蓝。閱讀源碼沒什么可說的,只能一步一步去跟代碼端幼,下面我們就直接開始吧礼烈。
通常我們在啟動一個Activity時只需要調(diào)用如下代碼即可:

Intent intent = new Intent(this, XXActivity.class);
startActivity(intent);

從Activity的startActivity(intent)方法入手,方法的調(diào)用鏈如下:

@Override
public void startActivity(Intent intent) {
    this.startActivity(intent, null);
}

@Override
public void startActivity(Intent intent, @Nullable Bundle options) {
    if (options != null) {
        startActivityForResult(intent, -1, options);
    } else {
        // Note we want to go through this call for compatibility with
        // applications that may have overridden the method.
        startActivityForResult(intent, -1);
    }
}

public void startActivityForResult(@RequiresPermission Intent intent, int requestCode) {
    startActivityForResult(intent, requestCode, null);
}

可以看出startActivity(intent)方法最終會走到startActivityForResult(Intent intent, int requestCode,Bundle options)方法婆跑,也省去了我們再去分析startActivityForResult()方法此熬。
Activity的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);
        // ...
    } else {
        // ...
    }
}

這里我們只需要關(guān)注mParent == null這部分的邏輯,這里的核心代碼是調(diào)用mInstrumentation.execStartActivity()方法。mInstrumentation的類型是Instrumentation犀忱,它會在應(yīng)用程序的任何代碼運行之前被實例化募谎,能夠允許你監(jiān)視應(yīng)用程序和系統(tǒng)的所有交互,Application和Activity的創(chuàng)建以及生命周期都會經(jīng)過這個對象去執(zhí)行阴汇。mMainThread的類型是ActivityThread数冬,應(yīng)用程序的入口就是該類中的main()方法,在該方法中會創(chuàng)建主線程Looper搀庶,開啟消息循環(huán)拐纱,處理任務(wù)。通過mMainThread.getApplicationThread()方法獲取到的是一個ApplicationThread對象哥倔,它是ActivityThread的內(nèi)部類秸架,它的定義如下:

private class ApplicationThread extends IApplicationThread.Stub{
   // ... 
}

可以看出它繼承自IApplicationThread.Stub,如果了解一點Binder的話從名稱就能知道IApplicationThread繼承自IInterface接口未斑,內(nèi)部定義了一些業(yè)務(wù)方法咕宿,IApplicationThread.Stub則是一個Binder對象。接下來我們來看一下Instrumentation的execStartActivity()方法蜡秽。
Instrumentation的execStartActivity方法

public ActivityResult execStartActivity(
        Context who, IBinder contextThread, IBinder token, Activity target,
        Intent intent, int requestCode, Bundle options) {
    // 將contextThread轉(zhuǎn)為IApplicationThread
    // 這里的contextThread是一個ApplicationThread對象府阀,實現(xiàn)了IApplicationThread接口,因此可以這樣轉(zhuǎn)換
    IApplicationThread whoThread = (IApplicationThread) contextThread;
    // ...
    try {
        // ...
        // 核心代碼
        int result = ActivityManager.getService()
                .startActivity(whoThread, who.getBasePackageName(), intent,
                        intent.resolveTypeIfNeeded(who.getContentResolver()),
                        token, target != null ? target.mEmbeddedID : null,
                        requestCode, 0, null, options);
        // 檢查Activity啟動結(jié)果
        checkStartActivityResult(result, intent);
    } catch (RemoteException e) {
        throw new RuntimeException("Failure from system", e);
    }
    return null;
}

這里的核心代碼是ActivityManager.getService().startActivity()芽突,ActivityManager.getService()方法獲取到的是一個ActivityManagerService對象试浙,簡稱AMS,為了簡便寞蚌,下文也都將其統(tǒng)稱為“AMS”诡延。AMS可就厲害了檐迟,它是Android中的核心服務(wù)杉女,負責調(diào)度各應(yīng)用的進程垢啼,管理四大組件。AMS是一個Binder艘刚,實現(xiàn)了IActivityManager接口管宵,因此應(yīng)用進程能通過Binder機制調(diào)用系統(tǒng)服務(wù)。

public static IActivityManager getService() {
    return IActivityManagerSingleton.get();
}

private static final Singleton<IActivityManager> IActivityManagerSingleton =
        new Singleton<IActivityManager>() {
            @Override
            protected IActivityManager create() {
                // 獲取服務(wù)Binder
                final IBinder b = ServiceManager.getService(Context.ACTIVITY_SERVICE);
                // 獲取AMS實例對象
                final IActivityManager am = IActivityManager.Stub.asInterface(b);
                return am;
            }
        };

值得一提的是ServiceManager管理著所有的系統(tǒng)服務(wù)攀甚,可以將其類比于DNS域名服務(wù)器箩朴,通過服務(wù)名稱可以從ServiceManager中獲取到相應(yīng)的服務(wù)Binder對象。checkStartActivityResult()方法的作用是檢查Activity的啟動結(jié)果秋度,參數(shù)傳入了startActivity()方法的返回值炸庞,根據(jù)返回值判斷Activity是否啟動成功,如果啟動失敗會拋出異常荚斯,常見的Unable to find explicit activity class; have you declared this activity in your AndroidManifest.xml異常就是這里拋出的埠居。
接下來我們來看AMS對象的startActivity()方法:
ActivityManagerService的startActivity方法

@Override
public final int startActivity(IApplicationThread caller, String callingPackage,
                               Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
                               int startFlags, ProfilerInfo profilerInfo, Bundle bOptions) {
    return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
            resultWho, requestCode, startFlags, profilerInfo, bOptions,
            UserHandle.getCallingUserId());
}

@Override
public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
                                     Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
                                     int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
    return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
            resultWho, requestCode, startFlags, profilerInfo, bOptions, userId,
            true /*validateIncomingUser*/);
}

public final 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) {
    enforceNotIsolatedCaller("startActivity");

    userId = mActivityStartController.checkTargetUser(userId, validateIncomingUser,
            Binder.getCallingPid(), Binder.getCallingUid(), "startActivityAsUser");

    return mActivityStartController.obtainStarter(intent, "startActivityAsUser")
            .setCaller(caller)
            .setCallingPackage(callingPackage)
            .setResolvedType(resolvedType)
            .setResultTo(resultTo)
            .setResultWho(resultWho)
            .setRequestCode(requestCode)
            .setStartFlags(startFlags)
            .setProfilerInfo(profilerInfo)
            .setActivityOptions(bOptions)
            .setMayWait(userId)
            .execute();

}

可以看出AMS的startActivity()方法最終會走到startActivityAsUser()方法中查牌,方法內(nèi)部是一個挺長的鏈式調(diào)用,第一行的mActivityStartController.obtainStarter()返回的是一個ActivityStarter對象拐格,之后的一系列調(diào)用可以看做是對ActivityStarter的配置僧免,我們直接來看最后調(diào)用的execute()方法。
ActivityStarter的execute方法

int execute() {
    try {
        // for transactional diffs and preprocessing.
        if (mRequest.mayWait) {
            return startActivityMayWait(mRequest.caller, mRequest.callingUid,
                    mRequest.callingPackage, mRequest.intent, mRequest.resolvedType,
                    mRequest.voiceSession, mRequest.voiceInteractor, mRequest.resultTo,
                    mRequest.resultWho, mRequest.requestCode, mRequest.startFlags,
                    mRequest.profilerInfo, mRequest.waitResult, mRequest.globalConfig,
                    mRequest.activityOptions, mRequest.ignoreTargetSecurity, mRequest.userId,
                    mRequest.inTask, mRequest.reason,
                    mRequest.allowPendingRemoteAnimationRegistryLookup);
        } else {
            return startActivity(mRequest.caller, mRequest.intent, mRequest.ephemeralIntent,
                    mRequest.resolvedType, mRequest.activityInfo, mRequest.resolveInfo,
                    mRequest.voiceSession, mRequest.voiceInteractor, mRequest.resultTo,
                    mRequest.resultWho, mRequest.requestCode, mRequest.callingPid,
                    mRequest.callingUid, mRequest.callingPackage, mRequest.realCallingPid,
                    mRequest.realCallingUid, mRequest.startFlags, mRequest.activityOptions,
                    mRequest.ignoreTargetSecurity, mRequest.componentSpecified,
                    mRequest.outActivity, mRequest.inTask, mRequest.reason,
                    mRequest.allowPendingRemoteAnimationRegistryLookup);
        }
    } finally {
        onExecutionComplete();
    }
}

這里有一個判斷捏浊,我們可以不用去了解它的意義,直接來看startActivityMayWait()方法:

private int startActivityMayWait(IApplicationThread caller, int callingUid,
                                 String callingPackage, Intent intent, String resolvedType,
                                 IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
                                 IBinder resultTo, String resultWho, int requestCode, int startFlags,
                                 ProfilerInfo profilerInfo, WaitResult outResult,
                                 Configuration globalConfig, SafeActivityOptions options, boolean ignoreTargetSecurity,
                                 int userId, TaskRecord inTask, String reason,
                                 boolean allowPendingRemoteAnimationRegistryLookup) {
    // ...
    // 調(diào)用startActivity方法
    int res = startActivity(caller, intent, ephemeralIntent, resolvedType, aInfo, rInfo,
            voiceSession, voiceInteractor, resultTo, resultWho, requestCode, callingPid,
            callingUid, callingPackage, realCallingPid, realCallingUid, startFlags, options,
            ignoreTargetSecurity, componentSpecified, outRecord, inTask, reason,
            allowPendingRemoteAnimationRegistryLookup);
    // ...
    return res;
}

這里省略了大量代碼撞叨,可以看到startActivityMayWait()方法最終也是調(diào)用了startActivity()方法金踪,因此我們不需要搞清楚上面判斷的意義,因為最終執(zhí)行的方法是一樣的牵敷。接下來來看ActivityStarter的startActivity()方法:

// 1
private int startActivity(IApplicationThread caller, Intent intent, Intent ephemeralIntent,
                          String resolvedType, ActivityInfo aInfo, ResolveInfo rInfo,
                          IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
                          IBinder resultTo, String resultWho, int requestCode, int callingPid, int callingUid,
                          String callingPackage, int realCallingPid, int realCallingUid, int startFlags,
                          SafeActivityOptions options, boolean ignoreTargetSecurity, boolean componentSpecified,
                          ActivityRecord[] outActivity, TaskRecord inTask, String reason,
                          boolean allowPendingRemoteAnimationRegistryLookup) {

    // ...
    mLastStartActivityResult = startActivity(caller, intent, ephemeralIntent, resolvedType,
            aInfo, rInfo, voiceSession, voiceInteractor, resultTo, resultWho, requestCode,
            callingPid, callingUid, callingPackage, realCallingPid, realCallingUid, startFlags,
            options, ignoreTargetSecurity, componentSpecified, mLastStartActivityRecord,
            inTask, allowPendingRemoteAnimationRegistryLookup);
    // ...
    return getExternalResult(mLastStartActivityResult);
}

// 2
private int startActivity(IApplicationThread caller, Intent intent, Intent ephemeralIntent,
                          String resolvedType, ActivityInfo aInfo, ResolveInfo rInfo,
                          IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
                          IBinder resultTo, String resultWho, int requestCode, int callingPid, int callingUid,
                          String callingPackage, int realCallingPid, int realCallingUid, int startFlags,
                          SafeActivityOptions options,
                          boolean ignoreTargetSecurity, boolean componentSpecified, ActivityRecord[] outActivity,
                          TaskRecord inTask, boolean allowPendingRemoteAnimationRegistryLookup) {
    // ...
    return startActivity(r, sourceRecord, voiceSession, voiceInteractor, startFlags,
            true /* doResume */, checkedOptions, inTask, outActivity);
}

// 3
private int startActivity(final ActivityRecord r, ActivityRecord sourceRecord,
                          IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
                          int startFlags, boolean doResume, ActivityOptions options, TaskRecord inTask,
                          ActivityRecord[] outActivity) {

    // ...
    result = startActivityUnchecked(r, sourceRecord, voiceSession, voiceInteractor,
                startFlags, doResume, options, inTask, outActivity);
    // ...
    return result;
}

// 4
private int startActivity(final ActivityRecord r, ActivityRecord sourceRecord,
                          IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
                          int startFlags, boolean doResume, ActivityOptions options, TaskRecord inTask,
                          ActivityRecord[] outActivity) {
    // ...
    mSupervisor.resumeFocusedStackTopActivityLocked(mTargetStack,mStartActivity,
            mOptions);
    // ...
    return START_SUCCESS;
}

可以看到經(jīng)過一系列調(diào)用(省略了大量代碼)最終走到了mSupervisor.resumeFocusedStackTopActivityLocked()方法胡岔,mSupervisor的類型是ActivityStackSupervisor,我們接著來看ActivityStackSupervisor的resumeFocusedStackTopActivityLocked()方法:
ActivityStackSupervisor的resumeFocusedStackTopActivityLocked方法

boolean resumeFocusedStackTopActivityLocked(
        ActivityStack targetStack, ActivityRecord target, ActivityOptions targetOptions) {
    // ...
    return targetStack.resumeTopActivityUncheckedLocked(target, targetOptions);
    // ...
}

方法內(nèi)部調(diào)用了targetStack.resumeTopActivityUncheckedLocked()方法枷餐,targetStack的類型是ActivityStack靶瘸,我們來看它的resumeTopActivityUncheckedLocked()方法:
ActivityStack的resumeTopActivityUncheckedLocked方法

boolean resumeTopActivityUncheckedLocked(ActivityRecord prev, ActivityOptions options) {
    // ...
    result = resumeTopActivityInnerLocked(prev, options);
    // ...
    return result;
}

private boolean resumeTopActivityInnerLocked(ActivityRecord prev, ActivityOptions options) {
    // ...
    mStackSupervisor.startSpecificActivityLocked(next, true, false);
    // ...
    return true;
}

最后又回到了ActivityStackSupervisor的startSpecificActivityLocked()方法。
ActivityStackSupervisor的startSpecificActivityLocked方法

void startSpecificActivityLocked(ActivityRecord r,
                                 boolean andResume, boolean checkConfig) {
    // 獲取應(yīng)用進程
    ProcessRecord app = mService.getProcessRecordLocked(r.processName,
            r.info.applicationInfo.uid, true);

    getLaunchTimeTracker().setLaunchTime(r);
    
    if (app != null && app.thread != null) {
         // 進程已創(chuàng)建
        try {
            // ...
            // 核心代碼
            realStartActivityLocked(r, app, andResume, checkConfig);
            return;
        } catch (RemoteException e) {
            Slog.w(TAG, "Exception when starting activity "
                    + r.intent.getComponent().flattenToShortString(), e);
        }

        // If a dead object exception was thrown -- fall through to
        // restart the application.
    }
    
    // 進程不存在則創(chuàng)建應(yīng)用進程
    mService.startProcessLocked(r.processName, r.info.applicationInfo, true, 0,
            "activity", r.intent.getComponent(), false, false, true);
}

方法內(nèi)部首先判斷了應(yīng)用程序進程是否存在毛肋,如果進程已創(chuàng)建就調(diào)用realStartActivityLocked() 方法怨咪,否則執(zhí)行mService.startProcessLocked()方法常見應(yīng)用進程,mService就是ActivityManagerService對象润匙。本文只討論Activity的啟動流程诗眨,因此默認進程已創(chuàng)建,關(guān)于進程未創(chuàng)建的情況孕讳,對應(yīng)于點擊應(yīng)用圖標啟動App的過程匠楚,之后我會再利用一篇筆記進行分析。接下來我們來看一下realStartActivityLocked()方法:

final boolean realStartActivityLocked(ActivityRecord r, ProcessRecord app,
                                      boolean andResume, boolean checkConfig) throws RemoteException {

    // ...
    // 創(chuàng)建Activity啟動事務(wù)
    final ClientTransaction clientTransaction = ClientTransaction.obtain(app.thread,
            r.appToken);
    clientTransaction.addCallback(LaunchActivityItem.obtain(new Intent(r.intent),
            System.identityHashCode(r), r.info,
            mergedConfiguration.getGlobalConfiguration(),
            mergedConfiguration.getOverrideConfiguration(), r.compat,
            r.launchedFromPackage, task.voiceInteractor, app.repProcState, r.icicle,
            r.persistentState, results, newIntents, mService.isNextTransitionForward(),
            profilerInfo));

    // Set desired final state.
    final ActivityLifecycleItem lifecycleItem;
    if (andResume) {
        lifecycleItem = ResumeActivityItem.obtain(mService.isNextTransitionForward());
    } else {
        lifecycleItem = PauseActivityItem.obtain();
    }
    clientTransaction.setLifecycleStateRequest(lifecycleItem);
  
    // 執(zhí)行事務(wù)
    mService.getLifecycleManager().scheduleTransaction(clientTransaction);
    // ...
}

mService.getLifecycleManager()方法獲取到的是一個ClientLifecycleManager對象厂财,用來管理Activity的生命周期芋簿,可以看到realStartActivityLocked()方法內(nèi)創(chuàng)建了一個ClientTransaction,表示Activity的啟動事務(wù)璃饱,最后調(diào)用ClientLifecycleManager的scheduleTransaction()方法執(zhí)行該事務(wù)与斤。接下來我們來看ClientLifecycleManager的scheduleTransaction()方法:
ClientLifecycleManager的scheduleTransaction方法

void scheduleTransaction(ClientTransaction transaction) throws RemoteException {
    final IApplicationThread client = transaction.getClient();
    transaction.schedule();
    if (!(client instanceof Binder)) {
        // If client is not an instance of Binder - it's a remote call and at this point it is
        // safe to recycle the object. All objects used for local calls will be recycled after
        // the transaction is executed on client in ActivityThread.
        transaction.recycle();
    }
}

接著調(diào)用了ClientTransaction的schedule()方法:

ClientTransaction的schedule方法

public void schedule() throws RemoteException {
    mClient.scheduleTransaction(this);
}

mClient的類型是IApplicationThread,最開始也提到過帜平,ApplicationThread實現(xiàn)了IApplicationThread接口幽告,再回過頭看上面的逐級調(diào)用,不難發(fā)現(xiàn)這里的mClient就是最開始傳入的ApplicationThread對象裆甩,因此我們直接來看ApplicationThread的scheduleTransaction()方法:
ApplicationThread的scheduleTransaction方法

@Override
public void scheduleTransaction(ClientTransaction transaction) throws RemoteException {
    ActivityThread.this.scheduleTransaction(transaction);
}

這里又調(diào)用了ActivityThread的scheduleTransaction()方法冗锁,ActivityThread中沒有定義這個方法,它定義在ActivityThread的父類ClientTransactionHandler中嗤栓。
ClientTransactionHandler的scheduleTransaction方法

void scheduleTransaction(ClientTransaction transaction) {
    transaction.preExecute(this);
    sendMessage(ActivityThread.H.EXECUTE_TRANSACTION, transaction);
}

方法內(nèi)部調(diào)用了sendMessage()方法冻河,該方法是一個抽象方法箍邮,它的實現(xiàn)在ActivityThread中。
ActivityThread的sendMessage方法

void sendMessage(int what, Object obj) {
    sendMessage(what, obj, 0, 0, false);
}

private void sendMessage(int what, Object obj, int arg1) {
    sendMessage(what, obj, arg1, 0, false);
}

private void sendMessage(int what, Object obj, int arg1, int arg2) {
    sendMessage(what, obj, arg1, arg2, false);
}

private void sendMessage(int what, Object obj, int arg1, int arg2, boolean async) {
    if (DEBUG_MESSAGES) Slog.v(
            TAG, "SCHEDULE " + what + " " + mH.codeToString(what)
                    + ": " + arg1 + " / " + obj);
    Message msg = Message.obtain();
    msg.what = what;
    msg.obj = obj;
    msg.arg1 = arg1;
    msg.arg2 = arg2;
    if (async) {
        msg.setAsynchronous(true);
    }
    mH.sendMessage(msg);
}

mH的類型是H叨叙,是ActivityThread內(nèi)部定義的一個Handler類锭弊,sendMessage()方法所做的就是創(chuàng)建并向Handler發(fā)送一個消息,這個消息的what值為EXECUTE_TRANSACTION擂错。值得一提的是味滞,在Android 9.0以下版本中,H中定義了LAUNCH_ACTIVITY钮呀、PAUSE_ACTIVITY剑鞍、RESUME_ACTIVITY這些生命周期相關(guān)的消息,而在Android 9.0中已經(jīng)去掉了這些消息爽醋,取而代之的就是EXECUTE_TRANSACTION這個消息蚁署。下面我們就來看H的handleMessage()方法,找到對EXECUTE_TRANSACTION這個消息的處理蚂四。

public void handleMessage(Message msg) {
    // ...
    switch (msg.what) {
        // ...
        case EXECUTE_TRANSACTION:
            final ClientTransaction transaction = (ClientTransaction) msg.obj;
            // 核心代碼
            mTransactionExecutor.execute(transaction);
            if (isSystem()) {
                // Client transactions inside system process are recycled on the client side
                // instead of ClientLifecycleManager to avoid being cleared before this
                // message is handled.
                transaction.recycle();
            }
            // TODO(lifecycler): Recycle locally scheduled transactions.
            break;
        // ...
    }
    // ...
}

這里的核心代碼是mTransactionExecutor.execute(transaction)光戈,mTransactionExecutor的類型是TransactionExecutor,我們來看TransactionExecutor的execute()方法:
TransactionExecutor的execute方法

public void execute(ClientTransaction transaction) {
    final IBinder token = transaction.getActivityToken();
    log("Start resolving transaction for client: " + mTransactionHandler + ", token: " + token);

    executeCallbacks(transaction);

    executeLifecycleState(transaction);
    mPendingActions.clear();
    log("End resolving transaction");
}

public void executeCallbacks(ClientTransaction transaction) {
    // 這里的callbacks是上面調(diào)用ActivityStackSupervisor中realStartActivityLocked方法時賦值的
    // ClientTransactionItem的實際類型為LaunchActivityItem
    final List<ClientTransactionItem> callbacks = transaction.getCallbacks();

    // ...
    for (int i = 0; i < size; ++i) {
        final ClientTransactionItem item = callbacks.get(i);
        final int postExecutionState = item.getPostExecutionState();
        final int closestPreExecutionState = mHelper.getClosestPreExecutionState(r,
                item.getPostExecutionState());
        // ...
        // 核心代碼
        item.execute(mTransactionHandler, token, mPendingActions);
        item.postExecute(mTransactionHandler, token, mPendingActions);
        // ...
    }
}

execute()方法中調(diào)用了兩個方法:executeCallbacks(transaction)executeLifecycleState(transaction)遂赠。我們先不去管executeLifecycleState()方法久妆,直接來看executeCallbacks()方法,方法內(nèi)部首先獲取了ClientTransaction中的callbacks解愤,這里的callbacks是上面調(diào)用ActivityStackSupervisor中realStartActivityLocked()方法時賦值的镇饺,類型為LaunchActivityItem,之后會調(diào)用LaunchActivityItem的execute()方法送讲。
LaunchActivityItem的execute方法

public void execute(ClientTransactionHandler client, IBinder token,
                    PendingTransactionActions pendingActions) {
    // ...
    // 核心代碼
    client.handleLaunchActivity(r, pendingActions, null /* customIntent */);
    // ...
}

方法內(nèi)部調(diào)用了ClientTransactionHandler的handleLaunchActivity()方法奸笤,前面也提到過ActivityThread繼承自ClientTransactionHandler,因次這里實際上調(diào)用的是ActivityThread的handleLaunchActivity()方法哼鬓,終于回到了我們熟悉的類中监右。
ActivityThread的handleLaunchActivity方法

public Activity handleLaunchActivity(ActivityClientRecord r,
                                     PendingTransactionActions pendingActions, Intent customIntent) {
    // ...
    // 核心代碼
    final Activity a = performLaunchActivity(r, customIntent);
    // ...
    return a;
}

handleLaunchActivity()方法中又調(diào)用了performLaunchActivity()方法:

private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
    // ...
  
    java.lang.ClassLoader cl = appContext.getClassLoader();
    // 1.創(chuàng)建Activity對象
    activity = mInstrumentation.newActivity(
            cl, component.getClassName(), r.intent);
    // ...
  
    // 2.創(chuàng)建Application對象,如果已經(jīng)創(chuàng)建則不會重復(fù)創(chuàng)建
    Application app = r.packageInfo.makeApplication(false, mInstrumentation);
    // ...
  
    if (activity != null) {
        // ...
        Window window = null;
        if (r.mPendingRemoveWindow != null && r.mPreserveWindow) {
            window = r.mPendingRemoveWindow;
            r.mPendingRemoveWindow = null;
            r.mPendingRemoveWindowManager = null;
        }
        appContext.setOuterContext(activity);
        // 3.創(chuàng)建PhoneWindow
        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);

        // ...
        // 4.調(diào)用onCreate()方法
        if (r.isPersistable()) {
            mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);
        } else {
            mInstrumentation.callActivityOnCreate(activity, r.state);
        }
        // ...
        r.activity = activity;
    }
    // ...
    return activity;
}

performLaunchActivity()方法內(nèi)部主要做了一下幾件事:

  • 調(diào)用Instrumentation的newActivity方法創(chuàng)建Activity對象
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的instantiateActivity方法
public Activity instantiateActivity(ClassLoader cl, String className,
                                    Intent intent)
        throws InstantiationException, IllegalAccessException, ClassNotFoundException {
    return (Activity) cl.loadClass(className).newInstance();
}

可以看出Instrumentation的newActivity方法內(nèi)部就是通過類加載器來創(chuàng)建Activity對象异希。

  • 調(diào)用r.packageInfo.makeApplication()方法創(chuàng)建Application對象
public Application makeApplication(boolean forceDefaultAppClass,
                                   Instrumentation instrumentation) {
  // 判斷Application對象是否已創(chuàng)建健盒,如果已創(chuàng)建就直接返回
  if (mApplication != null) {
        return mApplication;
    }

    // ...

    Application app = null;

    String appClass = mApplicationInfo.className;
    if (forceDefaultAppClass || (appClass == null)) {
        appClass = "android.app.Application";
    }
    
    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);
    // 核心代碼
    // 通過類加載器創(chuàng)建Application對象
    app = mActivityThread.mInstrumentation.newApplication(
            cl, appClass, appContext);
    appContext.setOuterContext(app);

    mActivityThread.mAllApplications.add(app);
    mApplication = app;

    // ...

    return app;
}

這里的r.packageInfo類型為LoadedApkmakeApplication()方法內(nèi)部首先判斷了Application對象是否已創(chuàng)建称簿,保證了只有一個Application對象扣癣。Application對象是通過調(diào)用Instrumentation的newApplication()方法來創(chuàng)建的,方法內(nèi)部同樣使用了類加載器憨降,這里就不展示了父虑。

  • 調(diào)用Activity的attach()方法
final void attach(Context context, ActivityThread aThread,
                  Instrumentation instr, IBinder token, int ident,
                  Application application, Intent intent, ActivityInfo info,
                  CharSequence title, Activity parent, String id,
                  NonConfigurationInstances lastNonConfigurationInstances,
                  Configuration config, String referrer, IVoiceInteractor voiceInteractor,
                  Window window, ActivityConfigCallback activityConfigCallback) {
    // ...

    // 創(chuàng)建PhoneWindow
    mWindow = new PhoneWindow(this, window, activityConfigCallback);

    // ...

    mWindow.setWindowManager(
            (WindowManager)context.getSystemService(Context.WINDOW_SERVICE),
            mToken, mComponent.flattenToString(),
            (info.flags & ActivityInfo.FLAG_HARDWARE_ACCELERATED) != 0);
    if (mParent != null) {
        mWindow.setContainer(mParent.getWindow());
    }
    mWindowManager = mWindow.getWindowManager();
    // ...
}

attach()方法主要做了兩件事:創(chuàng)建Window對象,類型為PhotoWindow授药;為Window對象關(guān)聯(lián)WindowManager士嚎,這屬于View繪制的研究范疇呜魄,本文中就不具體研究了。

  • 調(diào)用Instrumentation的callActivityOnCreate()方法
public void callActivityOnCreate(Activity activity, Bundle icicle) {
    prePerformCreate(activity);
    activity.performCreate(icicle);
    postPerformCreate(activity);
}

public void callActivityOnCreate(Activity activity, Bundle icicle,
                                 PersistableBundle persistentState) {
    prePerformCreate(activity);
    activity.performCreate(icicle, persistentState);
    postPerformCreate(activity);
}

方法內(nèi)部調(diào)用了Activity的performCreate()方法莱衩。
Activity的performCreate方法

final void performCreate(Bundle icicle) {
    performCreate(icicle, null);
}

final void performCreate(Bundle icicle, PersistableBundle persistentState) {
    // ...
    // 調(diào)用Activity的onCreate()方法
    if (persistentState != null) {
        onCreate(icicle, persistentState);
    } else {
        onCreate(icicle);
    }
    // ...
}

方法內(nèi)部調(diào)用了我們最熟悉的Activity生命周期onCreate()方法爵嗅,到這里Activity的啟動流程基本上就分析得差不多了。不過你可能還會有個疑惑笨蚁,onCreate()之后的onStart()onResume()是在哪里調(diào)用的呢睹晒,我在這里也是繞了好久,我看到網(wǎng)上的一些源碼分析中有一些是在performLaunchActivity()方法最后調(diào)用了Activity的performStart()方法括细,進而回調(diào)了onStart()方法册招,可能是由于版本不同,我這里并沒有調(diào)用該方法勒极。還記得上面的分析中在TransactionExecutor的execute()方法中調(diào)用的executeLifecycleState()嗎,是時候來看一下這個方法了虑鼎。
TransactionExecutor的executeLifecycleState方法

private void executeLifecycleState(ClientTransaction transaction) {
    // lifecycleItem的類型為ResumeActivityItem
    final ActivityLifecycleItem lifecycleItem = transaction.getLifecycleStateRequest();
    if (lifecycleItem == null) {
        // No lifecycle request, return early.
        return;
    }

    // ...

    // Cycle to the state right before the final requested state.
    cycleToPath(r, lifecycleItem.getTargetState(), true /* excludeLastState */);

    // Execute the final transition with proper parameters.
    lifecycleItem.execute(mTransactionHandler, token, mPendingActions);
    lifecycleItem.postExecute(mTransactionHandler, token, mPendingActions);
}

這里transaction.getLifecycleStateRequest()獲取到的ActivityLifecycleItem同樣是在之前調(diào)用ActivityStackSupervisor中的realStartActivityLocked()方法時賦值的辱匿,類型為ResumeActivityItem,之后調(diào)用了cycleToPath()方法炫彩。

private void cycleToPath(ActivityClientRecord r, int finish,
                         boolean excludeLastState) {
    final int start = r.getLifecycleState();
    log("Cycle from: " + start + " to: " + finish + " excludeLastState:" + excludeLastState);
    final IntArray path = mHelper.getLifecyclePath(start, finish, excludeLastState);
    performLifecycleSequence(r, path);
}

cycleToPath()方法內(nèi)部會調(diào)用TransactionExecutorHelpergetLifecyclePath()方法匾七,該方法的作用是根據(jù)傳入的起始生命周期狀態(tài)和最終生命周期狀態(tài)生成一個數(shù)組,比如當前生命周期狀態(tài)為為ON_CREATE江兢,而finish狀態(tài)為lifecycleItem.getTargetState()昨忆,也就是ResumeActivityItem.getTargetState()ON_RESUME,中間間隔了一個生命周期狀態(tài)ON_START杉允,因此這里生成的數(shù)組包含一個元素ON_START邑贴。Activity生命周期對應(yīng)的狀態(tài)值如下:

public static final int ON_CREATE = 1;
public static final int ON_START = 2;
public static final int ON_RESUME = 3;
public static final int ON_PAUSE = 4;
public static final int ON_STOP = 5;
public static final int ON_DESTROY = 6;
public static final int ON_RESTART = 7;

接下來會調(diào)用performLifecycleSequence()方法:

private void performLifecycleSequence(ActivityClientRecord r, IntArray path) {
    final int size = path.size();
    for (int i = 0, state; i < size; i++) {
        state = path.get(i);
        log("Transitioning to state: " + state);
        switch (state) {
            case ON_CREATE:
                mTransactionHandler.handleLaunchActivity(r, mPendingActions,
                        null /* customIntent */);
                break;
            case ON_START:
                mTransactionHandler.handleStartActivity(r, mPendingActions);
                break;
            case ON_RESUME:
                mTransactionHandler.handleResumeActivity(r.token, false /* finalStateRequest */,
                        r.isForward, "LIFECYCLER_RESUME_ACTIVITY");
                break;
            case ON_PAUSE:
                mTransactionHandler.handlePauseActivity(r.token, false /* finished */,
                        false /* userLeaving */, 0 /* configChanges */, mPendingActions,
                        "LIFECYCLER_PAUSE_ACTIVITY");
                break;
            case ON_STOP:
                mTransactionHandler.handleStopActivity(r.token, false /* show */,
                        0 /* configChanges */, mPendingActions, false /* finalStateRequest */,
                        "LIFECYCLER_STOP_ACTIVITY");
                break;
            case ON_DESTROY:
                mTransactionHandler.handleDestroyActivity(r.token, false /* finishing */,
                        0 /* configChanges */, false /* getNonConfigInstance */,
                        "performLifecycleSequence. cycling to:" + path.get(size - 1));
                break;
            case ON_RESTART:
                mTransactionHandler.performRestartActivity(r.token, false /* start */);
                break;
            default:
                throw new IllegalArgumentException("Unexpected lifecycle state: " + state);
        }
    }
}

可以看出這里會根據(jù)上一步生成的數(shù)組依次執(zhí)行相應(yīng)的生命周期相關(guān)方法,由于這里的數(shù)組只包含一個元素ON_START叔磷,因此會執(zhí)行mTransactionHandler.handleStartActivity()方法拢驾,之后的步驟就和onCreate()的執(zhí)行過程很相似了,即調(diào)用ActivityThread的handleStartActivity()方法改基,方法內(nèi)部調(diào)用Activity的performStart()方法繁疤,繼而回調(diào)生命周期onStart()方法,這里就不具體展示源碼分析了秕狰。
接下來我們回到executeLifecycleState()方法中稠腊,在執(zhí)行cycleToPath()方法后調(diào)用了lifecycleItem.execute()方法,由于這里的lifecycleItem是ResumeActivityItem鸣哀,因此我們來看ResumeActivityItem的execute()方法:
ResumeActivityItem的execute方法

@Override
public void execute(ClientTransactionHandler client, IBinder token,
                    PendingTransactionActions pendingActions) {
    Trace.traceBegin(TRACE_TAG_ACTIVITY_MANAGER, "activityResume");
    // 核心代碼
    client.handleResumeActivity(token, true /* finalStateRequest */, mIsForward,
            "RESUME_ACTIVITY");
    Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER);
}

可以看到和此前的兩個生命周期方法調(diào)用類似架忌,同樣是先調(diào)用了ActivityThread的handleResumeActivity()方法,之后調(diào)用performResumeActivity()诺舔,最后會調(diào)用onResume()生命周期方法鳖昌。
上述的流程只是我的簡單分析备畦,實際過程肯定要更復(fù)雜,個人水平比較有限许昨,因此只能這樣簡單地分析一下(PS:加斷點調(diào)試把我搞得有點蒙懂盐,實際執(zhí)行的流程其實并不是像我分析得這樣,有的方法會執(zhí)行多次)糕档,不正確的地方歡迎指出莉恼。
到這里整個Activity的啟動流程就分析得差不多了,實際的流程要比分析的復(fù)雜得多速那,也會涉及到很多其他的知識點俐银,包括View的繪制和進程的創(chuàng)建等等,由于水平有限很多地方只能淺嘗輒止端仰,太過深入源碼容易迷失方向捶惜。上一張流程圖總結(jié)一下吧:

Activity啟動流程

從分析和圖中我們也能發(fā)現(xiàn)在Activity的啟動流程中有幾個類起到了至關(guān)重要的作用:

  • Instrumentation

最開始調(diào)用AMS方法,最后創(chuàng)建Activity和Application對象都是通過它來實現(xiàn)的荔烧。

  • ActivityManagerService

Android中的核心服務(wù)吱七,應(yīng)用進程通過Binder機制可以調(diào)用系統(tǒng)服務(wù)。

  • ActivityThread

應(yīng)用程序的入口鹤竭,Activity各個生命周期的調(diào)用都是通過ActivityThread內(nèi)部的Handler接收和處理消息來實現(xiàn)的踊餐。

上面的流程圖我已經(jīng)上傳到了github,如果不清晰的話可以查看原圖

總結(jié)

本文是針對Android 9.0(API Level 28)的源碼進行分析的臀稚,與其他版本會有一些不同吝岭,但是大體流程不會差太多,主要差別就是在調(diào)用realStartActivityLocked()方法之后Handler的消息處理吧寺,有興趣的話可以自行查看源碼窜管。由于個人水平不足,很多地方可能分析得不準確撮执,也不夠全面微峰,希望大佬們可以指出。
最后總結(jié)一下我的一些心得抒钱,對于目前的我來說分析源碼實在是一件枯燥痛苦的事蜓肆,需要了解的知識點有很多,文章前前后后寫了很久谋币,中間中斷了好多次仗扬,也借鑒了很多大佬的成果,終于算是寫完了蕾额。但是拋開過程中的痛苦早芭,當真正把一個流程理順之后還是會覺得心情舒暢,雖然文章中的一些分析可能一段時間后還是會遺忘诅蝶,但是我收獲更多的是源碼閱讀和分析能力的提高退个,而且自己真正從頭分析了一遍之后再復(fù)習(xí)起來就會容易的多募壕。希望今后能夠更多地閱讀一些系統(tǒng)或者優(yōu)秀第三方庫的源碼,不斷提高自己语盈。

參考資料

死磕Android_App 啟動過程(含 Activity 啟動過程)
Android9.0 Activity啟動流程分析(三)
《Android開發(fā)藝術(shù)探索》

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末舱馅,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子刀荒,更是在濱河造成了極大的恐慌代嗤,老刑警劉巖,帶你破解...
    沈念sama閱讀 221,548評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件缠借,死亡現(xiàn)場離奇詭異干毅,居然都是意外死亡,警方通過查閱死者的電腦和手機泼返,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,497評論 3 399
  • 文/潘曉璐 我一進店門硝逢,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人绅喉,你說我怎么就攤上這事趴捅。” “怎么了霹疫?”我有些...
    開封第一講書人閱讀 167,990評論 0 360
  • 文/不壞的土叔 我叫張陵,是天一觀的道長综芥。 經(jīng)常有香客問我丽蝎,道長,這世上最難降的妖魔是什么膀藐? 我笑而不...
    開封第一講書人閱讀 59,618評論 1 296
  • 正文 為了忘掉前任屠阻,我火速辦了婚禮,結(jié)果婚禮上额各,老公的妹妹穿的比我還像新娘国觉。我一直安慰自己,他們只是感情好虾啦,可當我...
    茶點故事閱讀 68,618評論 6 397
  • 文/花漫 我一把揭開白布麻诀。 她就那樣靜靜地躺著,像睡著了一般傲醉。 火紅的嫁衣襯著肌膚如雪蝇闭。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 52,246評論 1 308
  • 那天硬毕,我揣著相機與錄音呻引,去河邊找鬼。 笑死吐咳,一個胖子當著我的面吹牛逻悠,可吹牛的內(nèi)容都是我干的元践。 我是一名探鬼主播,決...
    沈念sama閱讀 40,819評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼童谒,長吁一口氣:“原來是場噩夢啊……” “哼单旁!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起惠啄,我...
    開封第一講書人閱讀 39,725評論 0 276
  • 序言:老撾萬榮一對情侶失蹤慎恒,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后撵渡,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體融柬,經(jīng)...
    沈念sama閱讀 46,268評論 1 320
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,356評論 3 340
  • 正文 我和宋清朗相戀三年趋距,在試婚紗的時候發(fā)現(xiàn)自己被綠了粒氧。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,488評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡节腐,死狀恐怖外盯,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情翼雀,我是刑警寧澤饱苟,帶...
    沈念sama閱讀 36,181評論 5 350
  • 正文 年R本政府宣布,位于F島的核電站狼渊,受9級特大地震影響箱熬,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜狈邑,卻給世界環(huán)境...
    茶點故事閱讀 41,862評論 3 333
  • 文/蒙蒙 一城须、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧米苹,春花似錦糕伐、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,331評論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至训唱,卻和暖如春莺褒,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背雪情。 一陣腳步聲響...
    開封第一講書人閱讀 33,445評論 1 272
  • 我被黑心中介騙來泰國打工遵岩, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 48,897評論 3 376
  • 正文 我出身青樓尘执,卻偏偏與公主長得像舍哄,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子誊锭,可洞房花燭夜當晚...
    茶點故事閱讀 45,500評論 2 359