Android开发

在Android 10.0中Activity的启动流程

本文主要是介绍在Android 10.0中Activity的启动流程,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

摘要

Google将Android的版本更新到10.0版本(SDK-29)之后,我发现Acitivity的启动流程相比之前的版本发生了些变化,首先最大的变化是我们常见的用来管理Activity的AMS,在之后变成了ATMS(ActivityTaskManagerService)。 本文试图通过一张图来聊聊在Android 10.0版本中,一个Activity的启动流程究竟是怎样的。

Android 9.0和Android 10.0的一些区别

下面展示的是SDK-28和SDK-29两个版本在远程调用“AMS”的区别。他们都是通过调用远程服务来实现的,只是在SDK-29之后,抛弃了曾经的ActivityManagerService,改用ActivityTaskManagerService。

在这里解释一下ActivityManager和ActivityManagerService是什么关系,因为负责管理的Acitivity的服务和Activity不在一个进程,所以不能直接调用ActivityManagerService,而是通过Binder跨进程通信。Binder的工作原理不是本文的重点,在这里只要认为调用ActivityManager.getService().xxx()等于调用了另一个进程的ActivityManagerService.xxx()。

// frameworks/base/core/java/android/app/Instrumentation.java
// SDK-28
int result = ActivityManager.getService()
                .startActivity(whoThread, who.getBasePackageName(), intent,
                        intent.resolveTypeIfNeeded(who.getContentResolver()),
                        token, target != null ? target.mEmbeddedID : null,
                        requestCode, 0, null, options);
// SDK-29
int result = ActivityTaskManager.getService()
                .startActivity(whoThread, who.getBasePackageName(), intent,
                        intent.resolveTypeIfNeeded(who.getContentResolver()),
                        token, target != null ? target.mEmbeddedID : null,
                        requestCode, 0, null, options);
复制代码

请求启动一个Activity

// frameworks\base\core\java\android\app\Activity.java

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

public void startActivity(Intent intent, @Nullable Bundle options) {
    if (options != null) {
        startActivityForResult(intent, -1, options);
    } else {
        startActivityForResult(intent, -1);
    }
}

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

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);
            }
    }
}

public void startActivityFromChild(@NonNull Activity child, @RequiresPermission Intent intent,
        int requestCode) {
    startActivityFromChild(child, intent, requestCode, null);
}

public void startActivityFromChild(@NonNull Activity child, @RequiresPermission Intent intent,
        int requestCode, @Nullable Bundle options) {
    options = transferSpringboardActivityOptions(options);
    Instrumentation.ActivityResult ar =
        mInstrumentation.execStartActivity(
            this, mMainThread.getApplicationThread(), mToken, child,
            intent, requestCode, options);
    if (ar != null) {
        mMainThread.sendActivityResult(
            mToken, child.mEmbeddedID, requestCode,
            ar.getResultCode(), ar.getResultData());
    }
    cancelInputsAndStartExitTransition(options);
}
复制代码

调用startActivity动Activity最终都会调用到startActivityForResult无论mParent是不是空,最终也都会调用Instrumentation#execStartActivity。

// frameworks\base\core\java\android\app\Instrumentation.java

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;
}
复制代码

来到Instrumentation#execStartActivity,ActivityTaskManager.getService()返回的是IActivityTaskManager接口,这是远程调用的接口,执行IActivityTaskManager#startActivity之后相当于当前线程将启动Activity的消息发送出去了。

// frameworks\base\services\core\java\com\android\server\wm\ActivityTaskManagerService.java

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());
}

public 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*/);
}

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("startActivityAsUser");

    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) // Ⅰ 注意这个方法,在这个方法里有一句 mRequest.mayWait = true;
            .execute();
}
复制代码

ActivityTaskManagerService所在的进程接受到了消息后,就开始执行startActivity方法,接着调用的是startActivityAsUser方法,在这里我们构造ActivityStarter来继续完成Activity的启动,我们接着来看ActivityStarter#execute

frameworks\base\services\core\java\com\android\server\wm\ActivityStarter.java

int execute() {
    try {
        if (mRequest.mayWait) {
            return startActivityMayWait(mRequest.caller, mRequest.callingUid,
                    mRequest.callingPackage, mRequest.realCallingPid, mRequest.realCallingUid,
                    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,
                    mRequest.originatingPendingIntent, mRequest.allowBackgroundActivityStart);
        } 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,
                    mRequest.originatingPendingIntent, mRequest.allowBackgroundActivityStart);
        }
    } finally {
        onExecutionComplete();
    }
}

private int startActivityMayWait(IApplicationThread caller, int callingUid,
        String callingPackage, int requestRealCallingPid, int requestRealCallingUid,
        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,
        PendingIntentRecord originatingPendingIntent, boolean allowBackgroundActivityStart) {

        // ......
        final ActivityRecord[] outRecord = new ActivityRecord[1];
        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, originatingPendingIntent,
                allowBackgroundActivityStart);

        Binder.restoreCallingIdentity(origId);
        // ......
        return res;
    }
}

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,
        PendingIntentRecord originatingPendingIntent, boolean allowBackgroundActivityStart) {
	// ......

    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, originatingPendingIntent,
        allowBackgroundActivityStart);

    if (outActivity != null) {
        // mLastStartActivityRecord[0] is set in the call to startActivity above.
        outActivity[0] = mLastStartActivityRecord[0];
    }

    return getExternalResult(mLastStartActivityResult);
}


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,
        PendingIntentRecord originatingPendingIntent, boolean allowBackgroundActivityStart) {
    mSupervisor.getActivityMetricsLogger().notifyActivityLaunching(intent);
    // ......
    
    final int res = startActivity(r, sourceRecord, voiceSession, voiceInteractor, startFlags,
            true /* doResume */, checkedOptions, inTask, outActivity, restrictedBgActivity);
    mSupervisor.getActivityMetricsLogger().notifyActivityLaunched(res, outActivity[0]);
    return res;
}

private int startActivity(final ActivityRecord r, ActivityRecord sourceRecord,
            IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
            int startFlags, boolean doResume, ActivityOptions options, TaskRecord inTask,
            ActivityRecord[] outActivity, boolean restrictedBgActivity) {
    int result = START_CANCELED;
    final ActivityStack startedActivityStack;
    try {
        mService.mWindowManager.deferSurfaceLayout();
        result = startActivityUnchecked(r, sourceRecord, voiceSession, voiceInteractor,
                startFlags, doResume, options, inTask, outActivity, restrictedBgActivity);
    } finally {
        // ......
        mService.mWindowManager.continueSurfaceLayout();
    }

    postStartActivityProcessing(r, result, startedActivityStack);

    return result;
}

private int startActivityUnchecked(final ActivityRecord r, ActivityRecord sourceRecord,
        IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
        int startFlags, boolean doResume, ActivityOptions options, TaskRecord inTask,
        ActivityRecord[] outActivity, boolean restrictedBgActivity) {
    setInitialState(r, options, inTask, doResume, startFlags, sourceRecord, voiceSession,
            voiceInteractor, restrictedBgActivity);
    // ......
    mRootActivityContainer.sendPowerHintForLaunchStartIfNeeded(
            false /* forceSend */, mStartActivity);

    mTargetStack.startActivityLocked(mStartActivity, topFocused, newTask, mKeepCurTransition,
            mOptions);
    if (mDoResume) {
        final ActivityRecord topTaskActivity =
                mStartActivity.getTaskRecord().topRunningActivityLocked();
        if (!mTargetStack.isFocusable()
                || (topTaskActivity != null && topTaskActivity.mTaskOverlay
                && mStartActivity != topTaskActivity)) {
            mTargetStack.getDisplay().mDisplayContent.executeAppTransition();
        } else {
            if (mTargetStack.isFocusable()
                    && !mRootActivityContainer.isTopDisplayFocusedStack(mTargetStack)) {
                mTargetStack.moveToFront("startActivityUnchecked");
            }
            mRootActivityContainer.resumeFocusedStacksTopActivities(
                    mTargetStack, mStartActivity, mOptions);
        }
    } else if (mStartActivity != null) {
        mSupervisor.mRecentTasks.add(mStartActivity.getTaskRecord());
    }
    mRootActivityContainer.updateUserStack(mStartActivity.mUserId, mTargetStack);

    mSupervisor.handleNonResizableTaskIfNeeded(mStartActivity.getTaskRecord(),
            preferredWindowingMode, mPreferredDisplayId, mTargetStack);

    return START_SUCCESS;
}
复制代码

注意前面的注释Ⅰ,mRequest.mayWait在这里被赋值为true,所以会走到startActivityMayWait方法,然后调用startActivity->startActivity->startActivity->startActivityUnchecked,最终我们走到了startActivityUnchecked方法,然后我们会调用RootActivityContainer#resumeFocusedStacksTopActivities

// frameworks\base\services\core\java\com\android\server\wm\RootActivityContainer.java

boolean resumeFocusedStacksTopActivities(
        ActivityStack targetStack, ActivityRecord target, ActivityOptions targetOptions) {

    if (!mStackSupervisor.readyToResume()) {
        return false;
    }

    boolean result = false;
    if (targetStack != null && (targetStack.isTopStackOnDisplay()
            || getTopDisplayFocusedStack() == targetStack)) {
        result = targetStack.resumeTopActivityUncheckedLocked(target, targetOptions);
    }

    for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
        boolean resumedOnDisplay = false;
        final ActivityDisplay display = mActivityDisplays.get(displayNdx);
        for (int stackNdx = display.getChildCount() - 1; stackNdx >= 0; --stackNdx) {
            final ActivityStack stack = display.getChildAt(stackNdx);
            final ActivityRecord topRunningActivity = stack.topRunningActivityLocked();
            if (!stack.isFocusableAndVisible() || topRunningActivity == null) {
                continue;
            }
            if (stack == targetStack) {
                resumedOnDisplay |= result;
                continue;
            }
            if (display.isTopStack(stack) && topRunningActivity.isState(RESUMED)) {
                stack.executeAppTransition(targetOptions);
            } else {
                resumedOnDisplay |= topRunningActivity.makeActiveIfNeeded(target);
            }
        }
        if (!resumedOnDisplay) {
            final ActivityStack focusedStack = display.getFocusedStack();
            if (focusedStack != null) {
                focusedStack.resumeTopActivityUncheckedLocked(target, targetOptions);
            }
        }
    }

    return result;
}
复制代码

通过RootActivityContainer,我们将调用ActivityStack#resumeTopActivityUncheckedLocked

// frameworks\base\services\core\java\com\android\server\wm\ActivityStack.java

boolean resumeTopActivityUncheckedLocked(ActivityRecord prev, ActivityOptions options) {
	// ......
    try {
        mInResumeTopActivity = true;
        result = resumeTopActivityInnerLocked(prev, options);
        final ActivityRecord next = topRunningActivityLocked(true /* focusableOnly */);
        if (next == null || !next.canTurnScreenOn()) {
            checkReadyForSleep();
        }
    } finally {
        mInResumeTopActivity = false;
    }

    return result;
}
    
boolean resumeTopActivityInnerLocked(ActivityRecord prev, ActivityOptions options) {
    // ......
    boolean pausing = getDisplay().pauseBackStacks(userLeaving, next, false);
    if (mResumedActivity != null) {
        if (DEBUG_STATES) Slog.d(TAG_STATES,
                "resumeTopActivityLocked: Pausing " + mResumedActivity);
        pausing |= startPausingLocked(userLeaving, false, next, false);
    }
    // ......
    if (next.attachedToProcess()) {
        try {
        // ......
            transaction.setLifecycleStateRequest(
                    ResumeActivityItem.obtain(next.app.getReportedProcState(),
                            getDisplay().mDisplayContent.isNextTransitionForward()));
            mService.getLifecycleManager().scheduleTransaction(transaction);
        } catch (Exception e) {
            // ......
            mStackSupervisor.startSpecificActivityLocked(next, true, false);
            return true;
        }
        // ......
    } else {
        // Whoops, need to restart this activity!
        if (!next.hasBeenLaunched) {
            next.hasBeenLaunched = true;
        } else {
            if (SHOW_APP_STARTING_PREVIEW) {
                next.showStartingWindow(null /* prev */, false /* newTask */,
                        false /* taskSwich */);
            }
            if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, "Restarting: " + next);
        }
        if (DEBUG_STATES) Slog.d(TAG_STATES, "resumeTopActivityLocked: Restarting " + next);
        mStackSupervisor.startSpecificActivityLocked(next, true, true);
    }

    return true;
}

final boolean startPausingLocked(boolean userLeaving, boolean uiSleeping,
        ActivityRecord resuming, boolean pauseImmediately) {
    // ......
    if (prev.attachedToProcess()) {
        if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Enqueueing pending pause: " + prev);
        try {
            EventLogTags.writeAmPauseActivity(prev.mUserId, System.identityHashCode(prev),
                    prev.shortComponentName, "userLeaving=" + userLeaving);

            mService.getLifecycleManager().scheduleTransaction(prev.app.getThread(),
                    prev.appToken, PauseActivityItem.obtain(prev.finishing, userLeaving,
                            prev.configChangeFlags, pauseImmediately));
        } catch (Exception e) {
            // ......
        }
    } 
    // ......
}
复制代码

到了这一步,走到一个关键的类ActivityStack,这个类决定怎样发送生命周期的信号到应用进程。resumeTopActivityUncheckedLocked会调用resumeTopActivityInnerLocked。在这个函数里,会有两个重要的操作,一个是对应流程图里橙色的那条线,调用函数startPausingLocked,通知上一个Activity执行onPause;另一个是通知启动新的Activity,对应的是流程图中绿色的线。

先走的是橙色(pause)
mService.getLifecycleManager().scheduleTransaction(prev.app.getThread(),
                    prev.appToken, PauseActivityItem.obtain(prev.finishing, userLeaving,
                            prev.configChangeFlags, pauseImmediately));
复制代码

注意到我们这里构建了一个PauseActivityItem对象传入,这个对象将会在后面的IPC过程中传到Activity所在的进程。我们通过mService.getLifecycleManager()得到的是ClientLifecycleManager,scheduleTransaction方法有多个重载,这里调用到的是下面的方法

// frameworks\base\services\core\java\com\android\server\wm\ClientLifecycleManager.java
void scheduleTransaction(@NonNull IApplicationThread client, @NonNull IBinder activityToken,
            @NonNull ActivityLifecycleItem stateRequest) throws RemoteException {
        final ClientTransaction clientTransaction = transactionWithState(client, activityToken,
                stateRequest);
        scheduleTransaction(clientTransaction);
    }

void scheduleTransaction(ClientTransaction transaction) throws RemoteException {
    final IApplicationThread client = transaction.getClient();
    transaction.schedule();
    if (!(client instanceof Binder)) {
        transaction.recycle();
    }
}

private static ClientTransaction transactionWithState(@NonNull IApplicationThread client,
        @NonNull IBinder activityToken, @NonNull ActivityLifecycleItem stateRequest) {
    final ClientTransaction clientTransaction = ClientTransaction.obtain(client, activityToken);
    clientTransaction.setLifecycleStateRequest(stateRequest);
    return clientTransaction;
}
复制代码

在这里有个细节,我们用transactionWithState方法重新构造了ClientTransaction对象传入(ActivityLifecycleItem 继承自ClientTransaction),transactionWithState里面将PauseActivityItem通过setLifecycleStateRequest方法传入clientTransaction,之后就执行ClientTransaction#schedule。

// frameworks\base\core\java\android\app\servertransaction\ClientTransaction.java
public void schedule() throws RemoteException {
    mClient.scheduleTransaction(this);
}
复制代码

这里mClient是接口IApplicationThread的,可以看出这是一个远程调用,具体的实现就在Activity所在的进程。可以猜到这里的目的就是告诉应用进程“你的启动Activity的要求我已经收到了,你现在去pause上一个activity吧”。

// frameworks\base\core\java\android\app\ActivityThread.java
private class ApplicationThread extends IApplicationThread.Stub {
	public void scheduleTransaction(ClientTransaction transaction) throws RemoteException {
	    ActivityThread.this.scheduleTransaction(transaction);
	}
}

// frameworks\base\core\java\android\app\ClientTransactionHandler.java
void scheduleTransaction(ClientTransaction transaction) {
    transaction.preExecute(this);
    sendMessage(ActivityThread.H.EXECUTE_TRANSACTION, transaction);
}
复制代码

具体的实现有ActivityThread的内部类ApplicationThread 来完成,我们发现它调用的是它的外部类方法ActivityThread#scheduleTransaction。事实上ActivityThread并没有对应的实现,我们最终调用的是它父类ClientTransactionHandler的方法。

// frameworks\base\core\java\android\app\ActivityThread.java
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应该是一个Handler类,然后将具体的操作交给Handler来处理。

// frameworks\base\core\java\android\app\ActivityThread.java
case EXECUTE_TRANSACTION:
    final ClientTransaction transaction = (ClientTransaction) msg.obj;
    mTransactionExecutor.execute(transaction);
    if (isSystem()) {
        transaction.recycle();
    }
    break;
复制代码

这个mH事实上也是ActivityThread的一个内部类,类名就是一个大写的H。所以最终具体的实现可以在H#handleMessage里找到:

// frameworks\base\core\java\android\app\servertransaction\TransactionExecutor.java

public void execute(ClientTransaction transaction) {
    // ......
    executeCallbacks(transaction);

    executeLifecycleState(transaction);
    mPendingActions.clear();
    if (DEBUG_RESOLVER) Slog.d(TAG, tId(transaction) + "End resolving transaction");
}

private void executeLifecycleState(ClientTransaction transaction) {
    final ActivityLifecycleItem lifecycleItem = transaction.getLifecycleStateRequest();
    // ......
    lifecycleItem.execute(mTransactionHandler, token, mPendingActions);
    lifecycleItem.postExecute(mTransactionHandler, token, mPendingActions);
}
复制代码

还记得前面的clientTransaction.setLifecycleStateRequest(stateRequest);吗?在这里取出来然后调用它的execute方法。前面强调过传入的其实是PauseActivityItem,那么在这里执行的就是PauseActivityItem#execute,进到这个方法

// frameworks/base/core/java/android/app/servertransaction/PauseActivityItem.java
public void execute(ClientTransactionHandler client, IBinder token,
        PendingTransactionActions pendingActions) {
    Trace.traceBegin(TRACE_TAG_ACTIVITY_MANAGER, "activityPause");
    client.handlePauseActivity(token, mFinished, mUserLeaving, mConfigChanges, pendingActions,
            "PAUSE_ACTIVITY_ITEM");
    Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER);
}
复制代码

在这里会调用ClientTransactionHandler #handlePauseActivity方法,ActivityThread继承自ClientTransactionHandler ,实际上这个client就是ActivityThread

// frameworks\base\core\java\android\app\ActivityThread.java
public void handlePauseActivity(IBinder token, boolean finished, boolean userLeaving,
        int configChanges, PendingTransactionActions pendingActions, String reason) {
    ActivityClientRecord r = mActivities.get(token);
    if (r != null) {
        if (userLeaving) {
            performUserLeavingActivity(r);
        }
        r.activity.mConfigChangeFlags |= configChanges;
        
        performPauseActivity(r, finished, reason, pendingActions);
        
        if (r.isPreHoneycomb()) {
            QueuedWork.waitToFinish();
        }
        mSomeActivitiesChanged = true;
    }
}

final Bundle performPauseActivity(IBinder token, boolean finished, String reason,
        PendingTransactionActions pendingActions) {
    ActivityClientRecord r = mActivities.get(token);
    return r != null ? performPauseActivity(r, finished, reason, pendingActions) : null;
}

private Bundle performPauseActivity(ActivityClientRecord r, boolean finished, String reason,
        PendingTransactionActions pendingActions) {
    // ......
    final boolean shouldSaveState = !r.activity.mFinished && r.isPreHoneycomb();
    if (shouldSaveState) {
        callActivityOnSaveInstanceState(r);
    }

    performPauseActivityIfNeeded(r, reason);

    ArrayList<OnActivityPausedListener> listeners;
    synchronized (mOnPauseListeners) {
        listeners = mOnPauseListeners.remove(r.activity);
    }
    int size = (listeners != null ? listeners.size() : 0);
    for (int i = 0; i < size; i++) {
        listeners.get(i).onPaused(r.activity);
    }
    // ......
    return shouldSaveState ? r.state : null;
}

private void performPauseActivityIfNeeded(ActivityClientRecord r, String reason) {
    // ......
    try {
        r.activity.mCalled = false;
        mInstrumentation.callActivityOnPause(r.activity);
        if (!r.activity.mCalled) {
            throw new SuperNotCalledException("Activity " + safeToComponentShortString(r.intent)
                    + " did not call through to super.onPause()");
        }
    } catch (SuperNotCalledException e) {
        throw e;
    } catch (Exception e) {
        if (!mInstrumentation.onException(r.activity, e)) {
            throw new RuntimeException("Unable to pause activity "
                    + safeToComponentShortString(r.intent) + ": " + e.toString(), e);
        }
    }
    r.setState(ON_PAUSE);
}
复制代码

经过handlePauseActivity -> performPauseActivity -> performPauseActivity -> performPauseActivityIfNeeded一路下来,我们又看到这个mInstrumentation,由它将实际的生命周期分发到我们Activity,我们可以猜测,Activity的生命正式由他来掌管的。

// frameworks\base\core\java\android\app\Instrumentation.java
public void callActivityOnPause(Activity activity) {
    activity.performPause();
}

// frameworks\base\core\java\android\app\Activity.java
final void performPause() {
    dispatchActivityPrePaused();
    mDoReportFullyDrawn = false;
    mFragments.dispatchPause();
    mCalled = false;
    onPause();
    writeEventLog(LOG_AM_ON_PAUSE_CALLED, "performPause");
    mResumed = false;
    if (!mCalled && getApplicationInfo().targetSdkVersion
            >= android.os.Build.VERSION_CODES.GINGERBREAD) {
        throw new SuperNotCalledException(
                "Activity " + mComponent.toShortString() +
                " did not call through to super.onPause()");
    }
    dispatchActivityPostPaused();
}
复制代码

最终通过Instrumentation调用到Activity#performPause,经过了一大圈Activity的onPause最终在这里被调用。

然后走的绿色(create)
// frameworks\base\services\core\java\com\android\server\wm\ActivityStack.java
boolean resumeTopActivityInnerLocked(ActivityRecord prev, ActivityOptions options) {
    // ......
    boolean pausing = getDisplay().pauseBackStacks(userLeaving, next, false);
    if (mResumedActivity != null) {
        if (DEBUG_STATES) Slog.d(TAG_STATES,
                "resumeTopActivityLocked: Pausing " + mResumedActivity);
        pausing |= startPausingLocked(userLeaving, false, next, false);
    }
    // ......
    if (next.attachedToProcess()) {
        try {
        // ......
            transaction.setLifecycleStateRequest(
                    ResumeActivityItem.obtain(next.app.getReportedProcState(),
                            getDisplay().mDisplayContent.isNextTransitionForward()));
            mService.getLifecycleManager().scheduleTransaction(transaction);
        } catch (Exception e) {
            // ......
            mStackSupervisor.startSpecificActivityLocked(next, true, false);
            return true;
        }
        // ......
    } else {
        // Whoops, need to restart this activity!
        if (!next.hasBeenLaunched) {
            next.hasBeenLaunched = true;
        } else {
            if (SHOW_APP_STARTING_PREVIEW) {
                next.showStartingWindow(null /* prev */, false /* newTask */,
                        false /* taskSwich */);
            }
            if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, "Restarting: " + next);
        }
        if (DEBUG_STATES) Slog.d(TAG_STATES, "resumeTopActivityLocked: Restarting " + next);
        mStackSupervisor.startSpecificActivityLocked(next, true, true);
    }

    return true;
}
复制代码

回到ActivityStack#resumeTopActivityInnerLocked,在这里执行startPausingLocked(userLeaving, false, next, false);之后再往后走就准备创建新的Activity。会执行到StackSupervisor#startSpecificActivityLocked

// frameworks\base\services\core\java\com\android\server\wm\ActivityStackSupervisor.java
void startSpecificActivityLocked(ActivityRecord r, boolean andResume, boolean checkConfig) {
    // Is this activity's application already running?
    final WindowProcessController wpc =
            mService.getProcessController(r.processName, r.info.applicationInfo.uid);

    boolean knownToBeDead = false;
    if (wpc != null && wpc.hasThread()) {
        try {
            realStartActivityLocked(r, wpc, andResume, checkConfig);
            return;
        } catch (RemoteException e) {
            Slog.w(TAG, "Exception when starting activity "
                    + r.intent.getComponent().flattenToShortString(), e);
        }
        knownToBeDead = true;
    }
    // ......
}

boolean realStartActivityLocked(ActivityRecord r, WindowProcessController proc,
        boolean andResume, boolean checkConfig) throws RemoteException {

        try {
            if (!proc.hasThread()) {
                throw new RemoteException();
            }

            // 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,
                    // TODO: Have this take the merged configuration instead of separate global
                    // and override configs.
                    mergedConfiguration.getGlobalConfiguration(),
                    mergedConfiguration.getOverrideConfiguration(), r.compat,
                    r.launchedFromPackage, task.voiceInteractor, proc.getReportedProcState(),
                    r.icicle, r.persistentState, results, newIntents,
                    dc.isNextTransitionForward(), proc.createProfilerInfoIfNeeded(),
                            r.assistToken));

            // Set desired final state.
            final ActivityLifecycleItem lifecycleItem;
            if (andResume) {
                lifecycleItem = ResumeActivityItem.obtain(dc.isNextTransitionForward());
            } else {
                lifecycleItem = PauseActivityItem.obtain();
            }
            clientTransaction.setLifecycleStateRequest(lifecycleItem);

            // Schedule transaction.
            mService.getLifecycleManager().scheduleTransaction(clientTransaction);
            //...
        } catch (RemoteException e) {
           //...
        }
    } finally {
        endDeferResume();
    }
    // ......
    return true;
}
复制代码

startSpecificActivityLocked会调用realStartActivityLocked,然后构建一个LaunchActivityItem对象,根据前面的经验这里面应该包含了创建Activity的操作,但是跟前面有所不同的是,这个LaunchActivityItem是通过clientTransaction#addCallback注入到clientTransaction里面,而之前的PauseActivityItem是通过clientTransaction.setLifecycleStateRequest。另外LaunchActivityItem继承自ClientTransactionItem,而PauseActivityItem继承自ActivityLifecycleItem。 然后就是调用mService.getLifecycleManager().scheduleTransaction(clientTransaction),前面已经分析过这个过程,这里不在赘述,需要关注的是到达应用进程后又做了什么事情。

// frameworks\base\core\java\android\app\servertransaction\TransactionExecutor.java

public void execute(ClientTransaction transaction) {
    // ......
    executeCallbacks(transaction);

    executeLifecycleState(transaction);
    mPendingActions.clear();
    if (DEBUG_RESOLVER) Slog.d(TAG, tId(transaction) + "End resolving transaction");
}

public void executeCallbacks(ClientTransaction transaction) {
    final List<ClientTransactionItem> callbacks = transaction.getCallbacks();
    ctivityClientRecord r = mTransactionHandler.getActivityClient(token);
    final ActivityLifecycleItem finalStateRequest = transaction.getLifecycleStateRequest();
        
    final int size = callbacks.size();
    for (int i = 0; i < size; ++i) {
        // ......
        item.execute(mTransactionHandler, token, mPendingActions);
        item.postExecute(mTransactionHandler, token, mPendingActions);
        if (r == null) {
            // Launch activity request will create an activity record.
            r = mTransactionHandler.getActivityClient(token);
        }
        if (postExecutionState != UNDEFINED && r != null) {
            final boolean shouldExcludeLastTransition =
                   i == lastCallbackRequestingState && finalState == postExecutionState;
            cycleToPath(r, postExecutionState, shouldExcludeLastTransition, transaction);
        }
    }
}
复制代码

刚刚说到LaunchActivityItem是通过clientTransaction#addCallback加入的所以这里遭到executeCallbacks,但其实也一样,取出来执行execute方法。

// frameworks/base/core/java/android/app/servertransaction/LaunchActivityItem.java
public void execute(ClientTransactionHandler client, IBinder token,
        PendingTransactionActions pendingActions) {
    Trace.traceBegin(TRACE_TAG_ACTIVITY_MANAGER, "activityStart");
    ActivityClientRecord r = new ActivityClientRecord(token, mIntent, mIdent, mInfo,
            mOverrideConfig, mCompatInfo, mReferrer, mVoiceInteractor, mState, mPersistentState,
            mPendingResults, mPendingNewIntents, mIsForward,
            mProfilerInfo, client, mAssistToken);
    client.handleLaunchActivity(r, pendingActions, null /* customIntent */);
    Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER);
}

// frameworks/base/core/java/android/app/ActivityThread.java
public Activity handleLaunchActivity(ActivityClientRecord r,
        PendingTransactionActions pendingActions, Intent customIntent) {
    // ......

    final Activity a = performLaunchActivity(r, customIntent);
	// ......
    return a;
}

private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
	// ......

    ContextImpl appContext = createBaseContextForActivity(r);
    Activity activity = null;
    try {
        java.lang.ClassLoader cl = appContext.getClassLoader();
        activity = mInstrumentation.newActivity(
               cl, component.getClassName(), r.intent);
        StrictMode.incrementExpectedActivityCount(activity.getClass());
        r.intent.setExtrasClassLoader(cl);
        r.intent.prepareToEnterProcess();
        if (r.state != null) {
            r.state.setClassLoader(cl);
        }
    } catch (Exception e) {
        if (!mInstrumentation.onException(activity, e)) {
            throw new RuntimeException(
                "Unable to instantiate activity " + component
                + ": " + e.toString(), e);
        }
    }

    try {
        Application app = r.packageInfo.makeApplication(false, mInstrumentation);

        if (localLOGV) Slog.v(TAG, "Performing launch of " + r);
        if (localLOGV) Slog.v(
                TAG, r + ": app=" + app
                + ", appName=" + app.getPackageName()
                + ", pkg=" + r.packageInfo.getPackageName()
                + ", comp=" + r.intent.getComponent().toShortString()
                + ", dir=" + r.packageInfo.getAppDir());
                
        if (activity != null) {
            CharSequence title = r.activityInfo.loadLabel(appContext.getPackageManager());
            Configuration config = new Configuration(mCompatConfiguration);
            if (r.overrideConfig != null) {
                config.updateFrom(r.overrideConfig);
            }
            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Launching activity "
                    + r.activityInfo.name + " with config " + config);
            Window window = null;
            if (r.mPendingRemoveWindow != null && r.mPreserveWindow) {
                window = r.mPendingRemoveWindow;
                r.mPendingRemoveWindow = null;
                r.mPendingRemoveWindowManager = null;
            }
            appContext.setOuterContext(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);

            if (customIntent != null) {
                activity.mIntent = customIntent;
            }
            r.lastNonConfigurationInstances = null;
            checkAndBlockForNetworkAccess();
            activity.mStartedActivity = false;
            int theme = r.activityInfo.getThemeResource();
            if (theme != 0) {
               activity.setTheme(theme);
            }

            activity.mCalled = false;
            if (r.isPersistable()) {
                mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);
            } else {
                mInstrumentation.callActivityOnCreate(activity, r.state);
            }
            if (!activity.mCalled) {
                throw new SuperNotCalledException(
                    "Activity " + r.intent.getComponent().toShortString() +
                    " did not call through to super.onCreate()");
            }
            r.activity = activity;
        }
            r.setState(ON_CREATE);

            // updatePendingActivityConfiguration() reads from mActivities to update
            // ActivityClientRecord which runs in a different thread. Protect modifications to
            // mActivities to avoid race.
            synchronized (mResourcesManager) {
                mActivities.put(r.token, r);
            }

        } catch (SuperNotCalledException e) {
            throw e;

        } catch (Exception e) {
            if (!mInstrumentation.onException(activity, e)) {
                throw new RuntimeException(
                    "Unable to start activity " + component
                    + ": " + e.toString(), e);
            }
        }

        return activity;
    }
复制代码

这里跟也是一样最终调用的是ActivityThread的handleLaunchActivity,去除掉非核心代码他调用到了performLaunchActivity。在这里可以看见它通过Instrumentation#newActivity构造了一个Activity对象,然后调用Instrumentation#callActivityOnCreate。根据前面的经验,会继续调用Activity的performCreate方法,然后在调用onCreate方法,这就是我们写Activity最熟悉的地方了。

总结

Activity的启动流程以及生命周期的调用是一个相当复杂的过程,涉及到的也不仅仅是这两个进程。只是在分析的过程中要有选择的忽略调一些细节,抓住主要矛盾,慢慢就会发现相同的机制被应用在不同的地方,理解了其中一个也就理解很多其他相同的机制。 阅读这么复杂的源码不要追求只读一遍就能动,要反复的看,多次的重复之后是可以加深理解的。同时也多参考一些博客,说不定这个人写的看不懂,看另外一个人的可能就会有一种茅塞顿开的感觉。

参考

这篇关于在Android 10.0中Activity的启动流程的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!