Android启动一个Actiity会经历哪些流程了(Android 12)

704 阅读8分钟

为什么需要了解Activity启动流程

从笔者个人的的视角出发,对系统源码的了解,可以从一定上加深我们对业务中一些页面或者组件的行为的理解。以AMS这个流程为例,你可以了解到一些启动activity时候的一些调度行为,了解一些深层次的原因,那么我们在业务开发 和 在一些问题修复 以及处理一些性能问题的时候 可以多一些额外的视角。

举个🌰,我们在想办法降低页面TTI的时候,如果我们知道整个activity启动流程并且知道他是有一定耗时的,是不是就能很快去想到能不能把一些页面的加载行为和这个AMS的流程去异步并行,比如从点击那一刻开始加载,而不是等待进入到页面之后再去加载数据,通过这种思路来前置进行这些数据加载的行为。(仅代表个人的看法和思路,欢迎大家补充)

OK,下面我们就来整体捋一下这整一个流程。

总体的梳理思路

首先就是入口,众所周知,就是Activity.startActivity()。 另外在看源码之前,我们先抛一下粗粒度的流程:

  1. startActivity是在客户端进程中发起的
  2. 但是页面数据的装载是在system_server进程(AMS服务)中处理的
  3. 然后最终仍然要回到客户端进程中执行真正的Activity创建和生命周期调度

所以流程上是 应用进程 -> AMS服务 -> 应用进程,下面我们从这三个阶段分别去分析他们中流程的一些行为 image.png

第一阶段:应用进程 - 拉起AMS服务

  1. 从startActivity方法开始看 (仅列关键方法)
class Activity {

    public void startActivity(Intent intent, @Nullable Bundle options) {
        ...
        startActivityForResult(intent, -1, options);
        ...
    }

    public void startActivityForResult(@RequiresPermission Intent intent, int requestCode,  
    @Nullable Bundle options) {
        ...
        Instrumentation.ActivityResult ar =  mInstrumentation.execStartActivity(  
            this, mMainThread.getApplicationThread(), mToken, this,  
            intent, requestCode, options);
        ...
    }
}
  1. 看到最终调用了Instrumentation对象的execStartActivity方法,接着往下看
public class Instrumentation {
    public ActivityResult execStartActivity(
        Context who, IBinder contextThread, IBinder token, Activity target,  
        Intent intent, int requestCode, Bundle options) {
        ...
        int result = ActivityTaskManager.getService().startActivity(whoThread,  
            who.getOpPackageName(), who.getAttributionTag(), intent,  
            intent.resolveTypeIfNeeded(who.getContentResolver()), token,  
            target != null ? target.mEmbeddedID : null, requestCode, 0, null, options);
        ...
    }
}
  1. 看到调用了ActivityTaskManager.getService(),发起了startActivity。然后具体看一下这个ActivityTaskManager.getService()去拿了哪个service
class ActivityTaskManager {

    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);  
        }  
    };
}
  1. 发现他通过ServiceManager.getService去拿了系统的AMS服务,然后通过IActivityTaskManager.Stub.asInterface(b)去具象化了这个对象,然后通过这个对象去发起IPC通信。这个时候就走到了AMS服务的逻辑。

第二阶段:AMS服务进程 - 定义一些创建行为

  1. 继续看IActivityTaskManager的实现类ATMS的startActivity方法
class ActivityTaskManagerService extends IActivityTaskManager.Stub {
@Override  
    public final int startActivity(IApplicationThread caller, String callingPackage,  
        String callingFeatureId, Intent intent, String resolvedType, IBinder resultTo,  
        String resultWho, int requestCode, int startFlags, ProfilerInfo profilerInfo,  
    Bundle bOptions) { 
    
        return startActivityAsUser(caller, callingPackage, callingFeatureId, intent, resolvedType,  
            resultTo, resultWho, requestCode, startFlags, profilerInfo, bOptions,  
            UserHandle.getCallingUserId());  
    }
    
    private int startActivityAsUser(IApplicationThread caller, String callingPackage, ...) {
            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();
    }
}
  1. 会走到startActivityAsUser方法中,先用getActivityStartController().obtainStarter去创建一个ActivityStarter对象,然后用拼接一些activiy的信息,最后调用excute()。 下面就看下excute()方法里面做了什么。
class ActivityStarter {
    int execute() {
        ...
        synchronized (mService.mGlobalLock) {
            ...
            res = executeRequest(mRequest);
            ...
        }
        ...
    }
    
    private int executeRequest(Request request) {
        ...
        final ActivityRecord r = new ActivityRecord.Builder(mService)  
            .setCaller(callerApp)  
            .setLaunchedFromPid(callingPid)  
            .setLaunchedFromUid(callingUid)  
            .setLaunchedFromPackage(callingPackage)  
            .setLaunchedFromFeature(callingFeatureId)  
            .setIntent(intent)  
            .setResolvedType(resolvedType)  
            .setActivityInfo(aInfo)  
            .setConfiguration(mService.getGlobalConfiguration())  
            .setResultTo(resultRecord)  
            .setResultWho(resultWho)  
            .setRequestCode(requestCode)  
            .setComponentSpecified(request.componentSpecified)  
            .setRootVoiceInteraction(voiceSession != null)  
            .setActivityOptions(checkedOptions)  
            .setSourceRecord(sourceRecord)  
            .build();
            
          ...
          
          mLastStartActivityResult = startActivityUnchecked(r, sourceRecord, voiceSession,  
                request.voiceInteractor, startFlags, true /* doResume */, checkedOptions,  
                inTask, inTaskFragment, restrictedBgActivity, intentGrants);
          
    }
}
  1. 可以看到在这个ActivityStarter里面做了两件事情,先是把这个Activity的信息塞到这个ActivityRecord对象里面,然后带着这个ActivityRecord对象继续往下走startActivityUnchecked方法,接着往下看
class ActivityStarter {

    private int startActivityUnchecked(final ActivityRecord r, ActivityRecord sourceRecord,  
        IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,  
        int startFlags, boolean doResume, ActivityOptions options, Task inTask,  
        TaskFragment inTaskFragment, boolean restrictedBgActivity,  
        NeededUriGrants intentGrants) {
        ...
        result = startActivityInner(r, sourceRecord, voiceSession, voiceInteractor,  
            startFlags, doResume, options, inTask, inTaskFragment, restrictedBgActivity,  
            intentGrants);
        ...
    }
    
    int startActivityInner(final ActivityRecord r, ActivityRecord sourceRecord,  
        IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,  
        int startFlags, boolean doResume, ActivityOptions options, Task inTask,  
        TaskFragment inTaskFragment, boolean restrictedBgActivity,  
        NeededUriGrants intentGrants) {
        ...
        
        computeLaunchingTaskFlags();
        
        mIntent.setFlags(mLaunchFlags);
        ...
        mService.mUgmInternal.grantUriPermissionUncheckedFromIntent(intentGrants,  
mStartActivity.getUriPermissionsLocked());
        ...
        mRootWindowContainer.resumeFocusedStacksTopActivities(mTargetStack, mStartActivity, mOptions);
        ...
    }
}
  1. 可以看到最终进入了startActivityInner方法,在这个方法里面又去新增了一些activity的信息:比如计算启动模式和给Activity添加Uri权限,然后再最后调用resumeFocusedStacksTopActivities继续往下走
class RootWindowContainer {
    boolean resumeFocusedTasksTopActivities(  
        Task targetRootTask, ActivityRecord target, ActivityOptions targetOptions,  
        boolean deferPause) {
        final Task focusedRoot = display.getFocusedRootTask();  
        if (focusedRoot != null) {  
            result |= focusedRoot.resumeTopActivityUncheckedLocked(target, targetOptions);
        }
        ...
    }

}
  1. 调用一个Task对的resumeTopActivityUncheckedLocked
class Task extends TaskFragment {
    private boolean resumeTopActivityInnerLocked(ActivityRecord prev, ActivityOptions options,  
        boolean deferPause) {
        ...
        final TaskFragment topFragment = topActivity.getTaskFragment();  
        resumed[0] = topFragment.resumeTopActivity(prev, options, deferPause);
        ...
    }
}

class TaskFragment extends WindowContainer<WindowContainer> {
    ...
    mTaskSupervisor.startSpecificActivity(next, true, false);
    ...
}
  1. 继续看 mTaskSupervisor.startSpecificActivity里面干了啥
public class ActivityTaskSupervisor implements RecentTasks.Callbacks {
    public class ActivityTaskSupervisor implements RecentTasks.Callbacks {
        ...
        if (wpc != null && wpc.hasThread()) {
            realStartActivityLocked(r, wpc, andResume, checkConfig);  
            return;
        }
        ...
        mService.startProcessAsync(r, knownToBeDead, isTop, isTop ? "top-activity" : "activity");
    }

}
  1. 首先通过wpc.hasThread()判断ApplicationThread是否被赋值(也就是应用进程是否被创建),如果未创建调用ATMS的startProcessAsync去创建进程;否则realStartActivityLocked去继续创建activity,继续看realStartActivityLocked的实现
boolean realStartActivityLocked(ActivityRecord r, WindowProcessController proc,  
    boolean andResume, boolean checkConfig) throws RemoteException {
    ...
    // Create activity launch transaction.  
    final ClientTransaction clientTransaction = ClientTransaction.obtain(  
        proc.getThread(), r.appToken);
        
    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.getFilteredReferrer(r.launchedFromPackage), task.voiceInteractor,  
        proc.getReportedProcState(), r.getSavedState(), r.getPersistentSavedState(),  
        results, newIntents, r.takeOptions(), isTransitionForward,  
        proc.createProfilerInfoIfNeeded(), r.assistToken, activityClientController,  
        r.createFixedRotationAdjustmentsIfNeeded(), r.shareableActivityToken,  
        r.getLaunchedFromBubble()));
        
    final ActivityLifecycleItem lifecycleItem;  
    if (andResume) {  
        lifecycleItem = ResumeActivityItem.obtain(isTransitionForward);  
    } else {  
        lifecycleItem = PauseActivityItem.obtain();  
    }
    clientTransaction.setLifecycleStateRequest(lifecycleItem);
    
    // Schedule transaction.  
    mService.getLifecycleManager().scheduleTransaction(clientTransaction);
    ...
}

8.简单描述一下realStartActivityLocked做的事情

(1)通过ClientTransaction.obtain新建的一个clientTransaction任务流

(2)往clientTransaction通过addCallback塞一个LaunchActivityItem对象,很明显看名字也知道这个对象是用于创建和启动activity用的

(3)setLifecycleStateRequest(ResumeActivityItem),看名字这个对象的作用应该是把activity的生命周期推到onResume

(4)最后通过mService.getLifecycleManager().scheduleTransaction提交这个clientTransaction,下面继续看一下这个方法干了啥

class ClientLifecycleManager {

    void scheduleTransaction(ClientTransaction transaction) throws RemoteException {  
        final IApplicationThread client = transaction.getClient();  
        transaction.schedule();  
        ...
    }

}
class ClientTransaction {
    public void schedule() throws RemoteException {  
        mClient.scheduleTransaction(this);  
    }
}
  1. 可以看到client是应用进程的ApplicationThread对象在AMS中的代理,调用scheduleTransaction(this)后,又把ClientTransaction打包回到了应用进程。原因是因为在AMS里他只是定义了应用在创建activity需要做什么,而实际的操作仍然需要回到activty中去进行。 所以下进入第三阶段

第三阶段:应用进程 - 实际创建activity

public final class ActivityThread extends ClientTransactionHandler {
    private class ApplicationThread extends IApplicationThread.Stub {
        public void scheduleTransaction(ClientTransaction transaction) throws RemoteException {  
            ActivityThread.this.scheduleTransaction(transaction);  
        }
        
        void scheduleTransaction(ClientTransaction transaction) {  
            transaction.preExecute(this);  
            sendMessage(ActivityThread.H.EXECUTE_TRANSACTION, transaction);  
        }
        
        void sendMessage(int what, Object obj) {  
            sendMessage(what, obj, 0, 0, false);  
        }
        
        private void sendMessage(int what, Object obj, int arg1, int arg2, boolean async) {  
            if (DEBUG_MESSAGES) {   
                Message msg = Message.obtain();  
                ...
                msg.obj = obj;  
                ...
                if (async) {  
                msg.setAsynchronous(true);  
                }  
                mH.sendMessage(msg);  
            }
    }

}
  1. 看到ApplicationThread.scheduleTransaction会走到ActivityThread.scheduleTransaction, 然后会把这个transaction打包成一个message,然后通过mH这个Handler发送到主线程。然后继续看mH收到EXECUTE_TRANSACTION消息后去干了啥。
public void handleMessage(Message msg) {
    case EXECUTE_TRANSACTION:  
        final ClientTransaction transaction = (ClientTransaction) msg.obj;  
        mTransactionExecutor.execute(transaction);
}

public class TransactionExecutor {
    public void execute(ClientTransaction transaction) {
        ...
        executeCallbacks(transaction);  
  
        executeLifecycleState(transaction);
        ...
    }
}
  1. 去调用mTransactionExecutor.excute去解析和真正执行这个transaction。然后他分别调用了executeCallbacks和executeLifecycleState这两个方法。下面分别去看下里面具体做了啥

(1)首先来看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);  
        ...
        item.execute(mTransactionHandler, token, mPendingActions);
    }
}

getCallbacks里面的内容就是上面ams往这个transaction添加的LaunchActivityItem, 然后继续执行了LaunchActivityItem.excute(), 继续看下这个里面做了啥

public class LaunchActivityItem extends ClientTransactionItem {
    public void execute(ClientTransactionHandler client, IBinder token,  
        PendingTransactionActions pendingActions) {
        client.handleLaunchActivity(r, pendingActions, null /* customIntent */);
    }
}

调用ClientTransactionHandler.handleLaunchActivity, 这个方法的具体实现在AcitivityThread中,继续往下看。

class ActivityThread {

    public Activity handleLaunchActivity(ActivityClientRecord r,  
        PendingTransactionActions pendingActions, Intent customIntent) {
        ..
        final Activity a = performLaunchActivity(r, customIntent);
        ..
    }
    
    private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
        ...
        ContextImpl appContext = createBaseContextForActivity(r);  
        Activity activity = null;
        java.lang.ClassLoader cl = appContext.getClassLoader();
        
        activity = mInstrumentation.newActivity(
            cl, component.getClassName(), r.intent);
        
        ...
        
        Application app = r.packageInfo.makeApplication(false, mInstrumentation);
        mInstrumentation.callApplicationOnCreate(app);
        ...
        
        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, r.shareableActivityToken);
        ...
        
        if (r.isPersistable()) {  
            mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);  
        } else {  
            mInstrumentation.callActivityOnCreate(activity, r.state);  
        }
        ...
    }
}

这个方法分别做了以下这些事情:

第一步通过activtyRecord中的信息加载Activity类,然后通过mInstrumentation.newActivity去创建可这个activity对象;

第二步通过makeApplication去创建Application对象,然后通过mInstrumentation.callApplicationOnCreate(app)去走Application的onCreate方法;

第三步调用activity的attach方法去初始化一些activity的数据;

第四步调用mInstrumentation.callActivityOnCreate去把activity的生命周期推到onCreate

(2)然后看第二个方法executeLifecycleState(transaction)具体去做了啥

private void executeLifecycleState(ClientTransaction transaction) {
    final ActivityLifecycleItem lifecycleItem = transaction.getLifecycleStateRequest();
    ...
    lifecycleItem.execute(mTransactionHandler, token, mPendingActions);
}

首先通过transaction.getLifecycleStateRequest()拿到了一个ActivityLifecycleItem对象,这个getLifecycleStateRequest拿到的对象就是我们在第二个阶段中塞进去的ResumeActivityItem, 然后调用了这个ResumeActivityItem的excute(), 往下看

public class ResumeActivityItem extends ActivityLifecycleItem {
    public void execute(ClientTransactionHandler client, ActivityClientRecord r,  
        PendingTransactionActions pendingActions) {  
        
        client.handleResumeActivity(r, true /* finalStateRequest */, mIsForward,  
        "RESUME_ACTIVITY");  
    }
}

class ActivityThread {
    public void handleResumeActivity(ActivityClientRecord r, boolean finalStateRequest,  
        boolean isForward, String reason) {
        ...
        if (!performResumeActivity(r, finalStateRequest, reason)) {  
            return;  
        }
        ...
        
        View decor = r.window.getDecorView();
        decor.setVisibility(View.INVISIBLE);
        ViewManager wm = a.getWindowManager();
        ..
        wm.addView(decor, l);
        ...
        
        if (r.activity.mVisibleFromClient) {  
            r.activity.makeVisible();  
        }
        ...
    }

}

里面主要干了两件事情:

调用performResumeActivity把activity的生命周期推到onResume

把decorView加到wm上,并开始测量,布局,绘制,最后展示出来。

到这里activity就被创建完成了。

总结

简单再捋一下逻辑,

  1. 首先创建activity这个命令startActivity是由应用进程发起的,
  2. 然后通过IPC调度到system_server进程,由AMS组装activity信息和编排activity的一些调度任务,并把所有的信息打包成一个ClientTransaction
  3. 最后再把ClientTransaction交给应用进程,应用进程通过handler把这个ClientTransaction丢给主线程,然后再去解析和执行这个ClientTransaction 去真正的创建activity和执行activity生命周期的调度

参考blog

juejin.cn/post/734566…