Android源码分析之Activity启动流程

1,090 阅读6分钟

Activity是Android中重要的组件之一,而Activity启动流程也是主要的知识点,本篇文章源码是Android11(api 30)版本。

Android系统中Binder机制是系统的基础,Activity启动也是需要Binder机制来跨进程管理生命周期,还有Window的管理也是跨进程完成的,所以下面分为App进程和System进程来区分Activity启动流程中不同进程都是怎么工作的。下面开始追踪源码

1、App进程

(1)Activity

在Activity中启动另外一个Activity,这部分代码比较好跟,最后会走到startActivityForResult(@RequiresPermission Intent intent, int requestCode,@NullableBundle options)具体代码如下

//mParent是以前Activity嵌套Activity才会出现的,现在google已经不建议这样搞了
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());
    }
}
...

Instrumentation

在Instrumentation中的execStartActivity方法,会开始通过ATMS开始跨进程通信,获取ActivityTaskManagerService,到这现有阶段的App进程暂时告一段落,接下来会传递到System进程

...
try {
    intent.migrateExtraStreamToClipData(who);
    intent.prepareToLeaveProcess(who);
    int result = ActivityTaskManager.getService().startActivity(whoThread,
            who.getBasePackageName(), who.getAttributionTag(), 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);
}
...

2、System进程

ActivityTaskManagerService

在ActivityTaskManagerService中会首先调startActivity方法然后接着往后startActivityAsUser,下面简单看下startActivityAsUser这个方法

private int startActivityAsUser(IApplicationThread caller, String callingPackage,
        @Nullable String callingFeatureId, Intent intent, String resolvedType,
        IBinder resultTo, String resultWho, int requestCode, int startFlags,
        ProfilerInfo profilerInfo, Bundle bOptions, int userId, boolean validateIncomingUser) {
   ...
    // TODO: Switch to user app stacks here.
    return getActivityStartController().obtainStarter(intent, "startActivityAsUser")
            .setCaller(caller)
            .setCallingPackage(callingPackage)
            .setCallingFeatureId(callingFeatureId)
            .setResolvedType(resolvedType)
            .setResultTo(resultTo)
            .setResultWho(resultWho)
            .setRequestCode(requestCode)
            .setStartFlags(startFlags)
            .setProfilerInfo(profilerInfo)
            .setActivityOptions(bOptions)
            .setUserId(userId)
            .execute();

}

可以看到通过getActivityStartController()获取到一个ActivityStartController 的对象,然后通过obtainStarter再生成一个ActivityStarter对象,在对此对象进行一列别的配置然后执行此对象的execute()方法, 这里先了解下ActivityStarter这个类的作用,直接复制一下官方的注释:

Controller for interpreting how and then launching an activity. This class collects all the logic for determining how an intent and flags should be turned into an activity and associated task and stack. 主要是后半段控制Activity的栈管理,此类就是栈控制器,所有的Activity都会在此进行栈管理,下面继续execute()方法

此方法会首先生成或者解析出来一下记录Activity所需的信息,对mRequest进行赋值,方便对Activity进行进出栈管理,对mRequest参数进行赋值以后执行executeRequest(mRequest)

...
if (res != START_SUCCESS) {
    return res;
}
res = executeRequest(mRequest);

Binder.restoreCallingIdentity(origId);
...

executeRequest中需要明确三个类的关系ActivityRecord,ActivityStack,Task

WeChat3ae728f524472eadec84e72fd9a6a69a.png *注意:ActivityRecord中持有一个AcitivtyInfo,还没有将Activity创建出来

android系统中会同时存在多个ActvityStack,其实一个是给所有APP使用的,而在这个ActivityStack中存在多个Task,这也就是咱们所说的Activity栈,Task可能是一个App一个也有可能是一个App多个,具体看Activity的启动方式,而Task中存放的是ActivityRecord。

executeRequest中就生成了Task所需要的ActivityRecord,同时也需要着重注意的代码是调startActivityUnchecked的参数

//doResume为true这个参数会一直带到startActivityInner中
mLastStartActivityResult = startActivityUnchecked(r, sourceRecord, voiceSession,
        request.voiceInteractor, startFlags, true /* doResume */, checkedOptions, inTask,
        restrictedBgActivity, intentGrants);

executeRequest进行一系列的检查和运行时权限检查,如果错误直接终止返回错误码,成功继续执行startActivityUnchecked这一步所有的检查都已经完成就要调startActivityInner执行开启Activity和压栈操作了

...
        //继续执行startActivityInner
        result = startActivityInner(r, sourceRecord, voiceSession, voiceInteractor,
                startFlags, doResume, options, inTask, restrictedBgActivity, intentGrants);
 ...

然后执行startActivityInner,此方法会寻找当前的ActivtyStack和寻找Task,并执行你所设置的Activity的启动模式同时执行addOrReparentStartingActivity进行压栈操作并放到所属Task的栈顶。mDoResume这个参数就是在上面传过来的true,判断此参数以后会继续判断当前Activity是不是已经在栈中需要恢复为可见,还是不在栈中需要重新new一个,代码如下

if (mDoResume) {
    final ActivityRecord topTaskActivity =
            mStartActivity.getTask().topRunningActivityLocked();
            //判断当前栈的第一个activity是否有焦点而且栈顶的activity是否为目标activity,如果是的话直接显示,否则new一个activity
    if (!mTargetStack.isTopActivityFocusable()
            || (topTaskActivity != null && topTaskActivity.isTaskOverlay()
            && mStartActivity != topTaskActivity)) {
       
        mTargetStack.ensureActivitiesVisible(null /* starting */,
                0 /* configChanges */, !PRESERVE_WINDOWS);
        mTargetStack.getDisplay().mDisplayContent.executeAppTransition();
    } else {
        if (mTargetStack.isTopActivityFocusable()
                && !mRootWindowContainer.isTopDisplayFocusedStack(mTargetStack)) {
            mTargetStack.moveToFront("startActivityInner");
        }
        mRootWindowContainer.resumeFocusedStacksTopActivities(
                mTargetStack, mStartActivity, mOptions);
    }
}

RootWindowContainer

继续追踪Activity的创建逻辑resumeFocusedStacksTopActivities,因为是新的activity所以resumedOnDisplay为false,

if (!resumedOnDisplay) {
    final ActivityStack focusedStack = display.getFocusedStack();
    //当前栈是否存在如果为还没有activity栈会执行resumeHomeActivity创建activity并且创建activity栈
    if (focusedStack != null) {
        result |= focusedStack.resumeTopActivityUncheckedLocked(target, targetOptions);
    } else if (targetStack == null) {
        result |= resumeHomeActivity(null /* prev */, "no-focusable-task",
                display.getDefaultTaskDisplayArea());
    }
}

ActivityStack

这里假如已经有一个activity栈,所以继续执行resumeTopActivityUncheckedLocked方法 在resumeTopActivityUncheckedLocked会执行resumeTopActivityInnerLocked,在此方法中会生成一个next对象,在刚才栈管理的时候已经将目标Activity的ActivityRecord放到了对应栈的栈顶,所以此next对象就是目标Activity,此时next.attachedToProcess()判断为false因为当前还没有指定WindowProcessController,接下来会继续执行mStackSupervisor.startSpecificActivity(next, true, true);其中mStackSupervisor为父类参数

ActivityStackSupervisor

void startSpecificActivity(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;
   ...
}

在这个方法中首先查找当前Application是否已经run起来了,然后执行realStartActivityLocked(r, wpc, andResume, checkConfig);这个方法为目标ActivityRecord设置了最后的一些参数,然后冻结了window准备执行动画,创建Activity

boolean realStartActivityLocked(ActivityRecord r, WindowProcessController proc,
        boolean andResume, boolean checkConfig) throws RemoteException {
        ...
        
        final ClientTransaction clientTransaction = ClientTransaction.obtain(
        proc.getThread(), r.appToken);

        final DisplayContent dc = r.getDisplay().mDisplayContent;
        // Create activity launch transaction.
        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.getSavedState(), r.getPersistentSavedState(), results, newIntents,
                        dc.isNextTransitionForward(), proc.createProfilerInfoIfNeeded(),
                        r.assistToken, r.createFixedRotationAdjustmentsIfNeeded()));

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

主要看scheduleTransaction这个方法,这个方法开始执行转场动画

ClientLifecycleManager

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

这个方法中通过getCLient获取一个IApplicationThread对象,IApplicationThread为AIDL接口,其实现类为ActivityThread的内部类ApplicationThread。

ClientTransaction

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

mClient也是一个IApplicationThread对象,到ApplicationThread中查看其方法实现,到目前位置System进程基本上完成,开始回到App进程,通过Binder机制传递到了App进程

3、App进程

ApplicationThread

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

ActivityThread中没有scheduleTransaction方法其为父类ClientTransactionHandler

ClientTransactionHandler

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

在ActivityThread中有一个H类是Handler的子类,sendMessage直接使用此Handler进行发送,直接看ActivityThread.H.EXECUTE_TRANSACTION对应的消息处理方法

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

TransactionExecutor

执行execute后最终会执行cycleToPath

private void cycleToPath(ActivityClientRecord r, int finish, boolean excludeLastState,
            ClientTransaction transaction) {
        ...
        performLifecycleSequence(r, path, transaction);
    }
    /** Transition the client through previously initialized state sequence. */
    private void performLifecycleSequence(ActivityClientRecord r, IntArray path,
            ClientTransaction transaction) {
        final int size = path.size();
        for (int i = 0, state; i < size; i++) {
            state = path.get(i);
            
            switch (state) {
                case ON_CREATE:
                    mTransactionHandler.handleLaunchActivity(r, mPendingActions,
                            null /* customIntent */);
                    break;
                    ...
            }
        }
    }

到这一步已经和对应的生命周期对应上了,看ON_CREATE执行了handleLaunchActivity方法,下面看这个方法的实现

ClientTransactionHandler(ActivityThread的父类,所以可以直接看ActivityThread中其方法的实现)

public Activity handleLaunchActivity(ActivityClientRecord r,
        PendingTransactionActions pendingActions, Intent customIntent) {
   ...
    final Activity a = performLaunchActivity(r, customIntent);
   ...

这个方法中又执行了performLaunchActivity方法,大概做了这几件事

  • 通过反射创建Activity实例,这是通过Instrumentation.newActivity方法实现的;
  • 通过Activity.attach方法,实例化Window对象;
  • 调用Activity的onCreate回调; 到这Activity被创建,window被赋值,Activity启动基本完成,这时候还需要执行下一个onresume生命周期然后显示view,具体View,Window,Activity,ViewRootImp之间的关系下篇文章继续