Activity的启动流程(api29)

929 阅读9分钟

Activity作为Android四大组件之一,是我们平时开发过程中接触最多的。Activity的启动过程涉及到了服务进程,细节极多,加上Android系统各个版本的源码变化极大,在这里我将基于Android10(api29)带大家一起了解Activity启动的大概流程。

我们都知道,在一个Activity中启动另一个Activity需要调用startActivity方法。而Activity启动之后的第一个生命周期则是onCreate,我们只需要追踪从startActivity()方法开始到onCreate方法被调用期间到底进行了什么操作即可。

首先我们需要了解几个关键类:

  • Instrumentation:用于实现应用程序插装代码的基类,可以监视系统与应用程序的所有交互。Activity启动通过AIDL调用ATMS、新Activity的创建和生命周期的执行都通过它来完成。

  • ActivityThread:继承自ClientTransactionHandler,每个应用程序的唯一实例,程序入口main方法就在ActivityThread中,负责对Activity创建的管理。内部类==ApplicationThread==继承了IApplicationThread.Stub,负责把ATMS的任务交给ActivityThread。

  • ATMS:(ActivityTaskManagerService)Android核心服务,负责四大组件的启动,切换,调度等工作。

假设从Activity A跳转到另一个app的Activity B,整个过程可以分为3大部分:

1.Activity A => ActivityManagerService

2.ActivityManagerService => ApplicationThread

3.ApplicationThread => Activity B

Activity A => ActivityManagerService阶段

Activity.startActivity

@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方法,传入-1表示不需要获取startActivity的结果
        startActivityForResult(intent, -1);
    }
}

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);
        if (ar != null) {
            mMainThread.sendActivityResult(
                mToken, mEmbeddedID, requestCode, ar.getResultCode(),
                ar.getResultData());
        }
        if (requestCode >= 0) {
            mStartedActivity = true;
        }

        cancelInputsAndStartExitTransition(options);
    } else {
        ...
    }
}

在startActivityForResult中,调用Instrumentation.execStartActivity方法,交给Instrumentation进行处理。

其中:

  • Instrumentation是用来监控应用与系统的交互的。
  • mMainThread是ActivityThread类型,可以理解为Activity A所在的进程。
  • mMainThread.getApplicationThread获取了一个ApplicationThread的引用,用来实现进程间的通信的。

Instrumentation.execStartActivity

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中,通过ActivityTaskManager.getService()获取一个ActivityTaskManagerService(ATMS)实例。注意:api29是ActivityTaskManagerService,而在api28中是ActivityManagerService(AMS),没有这个Task喔。

具体代码如下:

public static IActivityTaskManager getService() {
    return IActivityTaskManagerSingleton.get();
}

private static final Singleton<IActivityTaskManager> IActivityTaskManagerSingleton =
        new Singleton<IActivityTaskManager>() {
            @Override
            protected IActivityTaskManager create() {
                final IBinder b = ServiceManager.getService(Context.ACTIVITY_TASK_SERVICE);
                return IActivityTaskManager.Stub.asInterface(b);
            }
        };

可以看得出来,这里实际上是通过AIDL来调用ATMS的startActivity。至此,startActivity的工作重心从进程A转移到ATMS中来。

ActivityManagerService => ApplicationThread阶段

ActivityTaskManagerService.startActivity方法最终会调用它内部的重载方法startActivityAsUser

具体代码如下:

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)
            .execute();

}

在这里通过ActivityStartController.obtainStarter方法得到一个ActivityStarter实例,并最终调用它的execute方法。由于调用了setMyWait方法,里面设置了mRequest.mayWait = true,因此在execute中会调用它内部的startActivityMayWait()方法。

ActivityStarter.startActivityMayWait

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) {
    // ...省略中间代码
    // 通过ActivityStackSupervisor获取ResolveInfo信息
    ResolveInfo rInfo = mSupervisor.resolveIntent(intent, resolvedType, userId,
                0, computeResolveFilterUid(callingUid, realCallingUid, mRequest.filterCallingUid));
    // ...省略中间代码
    // 通过ActivityStackSupervisor获取目标Activity信息
    ActivityInfo aInfo = mSupervisor.resolveActivity(intent, rInfo, startFlags, profilerInfo);
    // ...省略中间代码
    // 调用重载的startActivity方法
    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);
    // ...略略略
}

在startActivityMyWait方法里面会调用重载的startActivity方法,而最终则会调用startActivityUnchecked方法。

ActivityStarter.startActivityUnchecked

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

    final int preferredWindowingMode = mLaunchParams.mWindowingMode;

    // 计算Activity启动的flag
    computeLaunchingTaskFlags();

    computeSourceStack();

    mIntent.setFlags(mLaunchFlags);
    // ... 省略中间代码
    // 在ActivityStack中处理Task和Activity的进栈操作
    mTargetStack.startActivityLocked(mStartActivity, topFocused, newTask, mKeepCurTransition,
                mOptions);
    // ... 省略中间代码
    // 启动栈顶Activity
     mRootActivityContainer.resumeFocusedStacksTopActivities(
                        mTargetStack, mStartActivity, mOptions);
    // ...略略略
}

computeLaunchingTaskFlags的具体代码如下:

private void computeLaunchingTaskFlags() {
    // ...省略部分代码
    if (mInTask == null) {
        if (mSourceRecord == null) {
            // This activity is not being started from another...  in this
            // case we -always- start a new task.
            if ((mLaunchFlags & FLAG_ACTIVITY_NEW_TASK) == 0 && mInTask == null) {
                Slog.w(TAG, "startActivity called from non-Activity context; forcing " +
                        "Intent.FLAG_ACTIVITY_NEW_TASK for: " + mIntent);
                mLaunchFlags |= FLAG_ACTIVITY_NEW_TASK;
            }
        } else if (mSourceRecord.launchMode == LAUNCH_SINGLE_INSTANCE) {
            // The original activity who is starting us is running as a single
            // instance...  this new activity it is starting must go on its
            // own task.
            mLaunchFlags |= FLAG_ACTIVITY_NEW_TASK;
        } else if (isLaunchModeOneOf(LAUNCH_SINGLE_INSTANCE, LAUNCH_SINGLE_TASK)) {
            // The activity being started is a single instance...  it always
            // gets launched into its own task.
            mLaunchFlags |= FLAG_ACTIVITY_NEW_TASK;
        }
    }
}

这个方法用来计算启动Activity的flag以决定这个Activity最终放到哪个栈中。

  • mInTask的类型是TaskRecord,若为null则表示要加入的栈不存在,需要判断是否新建Task。
  • mSourceRecord的类型是ActivityRecord用来描述初始Activity(即调用了startActivity的Activity),若果用Context或Application启动Activity,此时mSourceRecord为null。
  • 如果初始Activity是在SingleInstance栈中的Activity,则需要添加FLAG_ACTIVITY_NEW_TASK来新建一个栈来放置新的Activity,因为SingleInstance的栈中只允许有一个Activity。
  • 如果LaunchModel是SingleTask或SingleInstance,也需要添加FLAG_ACTIVITY_NEW_TASK来新建一个栈。

ActivityStack.startActivityLocked

void startActivityLocked(ActivityRecord r, ActivityRecord focusedTopActivity,
            boolean newTask, boolean keepCurTransition, ActivityOptions options) {
    TaskRecord rTask = r.getTaskRecord();
    final int taskId = rTask.taskId;
    // mLaunchTaskBehind tasks get placed at the back of the task stack.
    if (!r.mLaunchTaskBehind && (taskForIdLocked(taskId) == null || newTask)) {
        // Last activity in task had been removed or ActivityManagerService is reusing task.
        // Insert or replace.
        // Might not even be in.
        insertTaskAtTop(rTask, r);
    }
    // ...略略略
}

在ActivityStack的startActivityLocked方法中调用insertTaskAtTop将Task和Activity入栈。

RootActivityContainer.resumeFocusedStacksTopActivities

RootActivityContainer是个临时类,从它的注释中可以知道它是用于将事物从ActivityStackSupervisor中分离出来。其目的是将其与RootWindowContainer合并,作为统一层次结构的一部分(翻译过来大概就是这么个意思)。而resumeFocusedStacksTopActivities方法里面也是调用ActivityStack的resumeTopActivityUncheckedLocked方法,然后又调用了resumeTopActivityInnerLocked方法,最后调用了ActivityStackSupervisor的startSpecificActivityLocked方法。

ActivityStackSupervisor.startSpecificActivityLocked

在这个方法中会调用它内部的realStartActivityLocked方法,并创建Activity所在进程。

void startSpecificActivityLocked(ActivityRecord r, boolean andResume, boolean checkConfig) {
    // Is this activity's application already running?
    // 根据进程名和Application的uid判断目标进程是否已经创建
    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);
        }

        // If a dead object exception was thrown -- fall through to
        // restart the application.
        knownToBeDead = true;
    }
    
    if (getKeyguardController().isKeyguardLocked()) {
        r.notifyUnknownVisibilityLaunched();
    }

    try {
        if (Trace.isTagEnabled(TRACE_TAG_ACTIVITY_MANAGER)) {
            Trace.traceBegin(TRACE_TAG_ACTIVITY_MANAGER, "dispatchingStartProcess:"
                    + r.processName);
        }
        // Post message to start process to avoid possible deadlock of calling into AMS with the
        // ATMS lock held.
        // 通过ATMS的mH来发送一个创建Activity所在进程的消息,避免死锁...
        final Message msg = PooledLambda.obtainMessage(
                ActivityManagerInternal::startProcess, mService.mAmInternal, r.processName,
                r.info.applicationInfo, knownToBeDead, "activity", r.intent.getComponent());
        mService.mH.sendMessage(msg);
    } finally {
        Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER);
    }
}

ActivityStackSupervisor.realStartActivityLocked

boolean realStartActivityLocked(ActivityRecord r, WindowProcessController proc,
            boolean andResume, boolean checkConfig) throws RemoteException {
    // ...省略中间代码
    try {
        // ...省略中间代码
        // Create activity launch transaction.
        final ClientTransaction clientTransaction = ClientTransaction.obtain(
                proc.getThread(), r.appToken);
        // 记住这个LaunchActivityItem,很关键
        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));

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

        // Schedule transaction.
        mService.getLifecycleManager().scheduleTransaction(clientTransaction);
        // ... 略略略
    } // .... 略略略
    return true;
}

在这个方法中,创建了一个ClientTransaction,并传入了一个ApplicationThread,添加了一个LaunchActivityItem类型的Callback,最终通过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();
    }
}

这里实际上是调用了传入的ClientTransaction的schedule方法,而ClientTransaction里面的代码如下:

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

public static ClientTransaction obtain(IApplicationThread client, IBinder activityToken) {
    ClientTransaction instance = ObjectPool.obtain(ClientTransaction.class);
    if (instance == null) {
        instance = new ClientTransaction();
    }
    instance.mClient = client;
    instance.mActivityToken = activityToken;

    return instance;
}

而这个schedule里面的mClient对象则是在事务创建时传入的ApplicationThread对象,所以schedule里面调用的是ApplicationThread的scheduleTransaction方法。此时startActivity操作已经从ATMS转移到另一个进程B中的ApplicationThread中去,看到曙光了有木有。

ApplicationThread => Activity阶段

ApplicationThread是ActivityThread的内部类,scheduleTransaction又会调用ActivityThread的scheduleTransaction方法。ActivityThread继承了抽象类ClientTransactionHandler,所以真正调用的是ClientTransactionHandler的scheduleTransaction方法,其代码如下:

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

只是发送了一个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;
        // ... 略略略
    }
}

调用了TransactionExecutor的execute方法,实际上调用了它的executeCallbacks方法。

TransactionExecutor.executeCallbacks

public void executeCallbacks(ClientTransaction transaction) {
    final List<ClientTransactionItem> callbacks = transaction.getCallbacks();
    // ... 省略中间代码
    for (int i = 0; i < size; ++i) {
        final ClientTransactionItem item = callbacks.get(i);
        if (DEBUG_RESOLVER) Slog.d(TAG, tId(transaction) + "Resolving callback: " + item);
        final int postExecutionState = item.getPostExecutionState();
        final int closestPreExecutionState = mHelper.getClosestPreExecutionState(r,
                item.getPostExecutionState());
        if (closestPreExecutionState != UNDEFINED) {
            cycleToPath(r, closestPreExecutionState, transaction);
        }

        item.execute(mTransactionHandler, token, mPendingActions);
        item.postExecute(mTransactionHandler, token, mPendingActions);
        // ... 略略略
    }
}

在这里获取了ClientTransaction的Callbacks并且便利他们。还记得ClientTransaction创建的时候设置了一个LaunchActivityItem类型的Callback吗,没错就是这玩意。所以这里的item.execute实际上就是执行了LaunchActivityItem的execute方法咯。

LaunchActivityItem.execute

@Override
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);
    Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER);
}

呵,这里的client就是一个ActivityThread对象,调用它的handleLaunchActivity方法,看来快要找到终点了。

ActivityThread.handleLaunchActivity

public Activity handleLaunchActivity(ActivityClientRecord r,
            PendingTransactionActions pendingActions, Intent customIntent) {
    // ...省略中间代码
    // 初始化Activity的WindowManager,每个Activity对应一个Window,这个后续文章将会分析
    WindowManagerGlobal.initialize();
    
    GraphicsEnvironment.hintActivityLaunch();
    
    // 创建并显示Activity
    final Activity a = performLaunchActivity(r, customIntent);
    // ...略略略
}

private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
    try {
        // 通过反射创建Activity
        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);

        // ...省略中间代码
        // 调用Activity的attach方法关联Activity和Context,创建PhoneWindow并关联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);

        // ...省略中间代码
        // 通过Instrumentation调用Activity的onCreate方法
        if (r.isPersistable()) {
            mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);
        } else {
            mInstrumentation.callActivityOnCreate(activity, r.state);
        }
        // ...略略略
    } // ...略略略
    return activity;
}

Instrumentation.callActivityOnCreate

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

Instrumentation的callActivityOnCreate方法实际上也是调用了Activity的performCreate方法,其代码如下:

final void performCreate(Bundle icicle, PersistableBundle persistentState) {
    dispatchActivityPreCreated(icicle);
    mCanEnterPictureInPicture = true;
    restoreHasCurrentPermissionRequest(icicle);
    if (persistentState != null) {
        onCreate(icicle, persistentState);
    } else {
        onCreate(icicle);
    }
    writeEventLog(LOG_AM_ON_CREATE_CALLED, "performCreate");
    mActivityTransitionState.readState(icicle);

    mVisibleFromClient = !mWindow.getWindowStyle().getBoolean(
            com.android.internal.R.styleable.Window_windowNoDisplay, false);
    mFragments.dispatchActivityCreated();
    mActivityTransitionState.setEnterActivityOptions(this, getActivityOptions());
    dispatchActivityPostCreated(icicle);
}

啊,终于看到Activity的onCreate方法被调用了,太感人了。至此Activity B已经被成功创建并执行生命周期方法。

总结

整个Activity的启动流程主要涉及3大步骤:

  • 通过AIDL的方式调用ATMS的startActivity方法,把启动工作交给ATMS。
  • ATMS构造目标Intent、Activity的信息,通过ActivityStack和ActivityStackSupervisor进行Task和Activity的入栈操作。
  • 最后ATMS通过ClientTransaction,调用目标进程中ApplicationThread的方法,而ApplicationThread是ActivityThrea的内部类,它最终执行的还是ActivityThrea里面的方法。在ActivityThread中创建Activity并调用它的生命周期。