AMS-Activity启动流程

了解了WMS窗口层级结构之后,试着从WMS的角度来分析activity启动流程。

1. 创建窗口层级结构树的节点

1.1 分析窗口层级变化

从launcher启动一个app,启动前的窗口层级:

启动后的窗口层级:

可以看到启动之后,DefaultTaskDisplayArea下面多了一套层级Task 11 -- ActivityRecord -- windowState,

那么是如何添加的呢,我们还是在WindowContainer.java的2个addChild函数中添加log来跟踪调用信息:

java 复制代码
// WindowContainer.java
    protected void addChild(E child, Comparator<E> comparator) {
        if (child instanceof Task || child instanceof ActivityRecord || child instanceof WindowToken
            || child instanceof WindowState) {
            android.util.Log.d("Test111", this + " add child " + child, new Exception());
        }
        ...
    }
    void addChild(E child, int index) {
        if (child instanceof Task || child instanceof ActivityRecord || child instanceof WindowToken
                || child instanceof WindowState) {
            android.util.Log.d("Test111", this + " add child2  " + child, new Exception());
        }
        ...
    }
java 复制代码
 D Test111 : DefaultTaskDisplayArea@236455599 add child2  Task{6dcada9 #11 type=standard ?? U=0 visible=false visibleRequested=false mode=undefined translucent=true sz=0}
 D Test111 : java.lang.Exception
 D Test111 : 	at com.android.server.wm.WindowContainer.addChild(WindowContainer.java:552)
 D Test111 : 	at com.android.server.wm.TaskDisplayArea.addChildTask(TaskDisplayArea.java:383)
 D Test111 : 	at com.android.server.wm.TaskDisplayArea.addChild(TaskDisplayArea.java:369)
 D Test111 : 	at com.android.server.wm.Task$Builder.build(Task.java:6611)
 D Test111 : 	at com.android.server.wm.TaskDisplayArea.getOrCreateRootTask(TaskDisplayArea.java:1133)
 D Test111 : 	at com.android.server.wm.TaskDisplayArea.getOrCreateRootTask(TaskDisplayArea.java:1158)
 D Test111 : 	at com.android.server.wm.RootWindowContainer.getLaunchRootTask(RootWindowContainer.java:2982)
 D Test111 : 	at com.android.server.wm.ActivityStarter.getLaunchRootTask(ActivityStarter.java:2901)
 D Test111 : 	at com.android.server.wm.ActivityStarter.startActivityInner(ActivityStarter.java:1766)
 D Test111 : 	at com.android.server.wm.ActivityStarter.startActivityUnchecked(ActivityStarter.java:1584)
 D Test111 : 	at com.android.server.wm.ActivityStarter.executeRequest(ActivityStarter.java:1185)
 D Test111 : 	at com.android.server.wm.ActivityStarter.execute(ActivityStarter.java:672)
 D Test111 : 	at com.android.server.wm.ActivityTaskManagerService.startActivityAsUser(ActivityTaskManagerService.java:1243)
 D Test111 : 	at com.android.server.wm.ActivityTaskManagerService.startActivityAsUser(ActivityTaskManagerService.java:1215)
 D Test111 : 	at com.android.server.wm.ActivityTaskManagerService.startActivity(ActivityTaskManagerService.java:1190)
 D Test111 : 	at android.app.IActivityTaskManager$Stub.onTransact(IActivityTaskManager.java:893)
 D Test111 : 	at com.android.server.wm.ActivityTaskManagerService.onTransact(ActivityTaskManagerService.java:5119)
 D Test111 : 	at android.os.Binder.execTransactInternal(Binder.java:1179)
 D Test111 : 	at android.os.Binder.execTransact(Binder.java:1143)
 D Test111 : Task{6dcada9 #11 type=standard A=10107:com.example.mytestapplication U=0 visible=false visibleRequested=false mode=fullscreen translucent=true sz=0} add child2  ActivityRecord{5297b65 u0 com.example.mytestapplication/.MainActivity
 D Test111 : java.lang.Exception
 D Test111 : 	at com.android.server.wm.WindowContainer.addChild(WindowContainer.java:552)
 D Test111 : 	at com.android.server.wm.TaskFragment.addChild(TaskFragment.java:1693)
 D Test111 : 	at com.android.server.wm.Task.addChild(Task.java:1448)
 D Test111 : 	at com.android.server.wm.ActivityStarter.addOrReparentStartingActivity(ActivityStarter.java:2832)
 D Test111 : 	at com.android.server.wm.ActivityStarter.setNewTask(ActivityStarter.java:2784)
 D Test111 : 	at com.android.server.wm.ActivityStarter.startActivityInner(ActivityStarter.java:1771)
 D Test111 : 	at com.android.server.wm.ActivityStarter.startActivityUnchecked(ActivityStarter.java:1584)
 D Test111 : 	at com.android.server.wm.ActivityStarter.executeRequest(ActivityStarter.java:1185)
 D Test111 : 	at com.android.server.wm.ActivityStarter.execute(ActivityStarter.java:672)
 D Test111 : 	at com.android.server.wm.ActivityTaskManagerService.startActivityAsUser(ActivityTaskManagerService.java:1243)
 D Test111 : 	at com.android.server.wm.ActivityTaskManagerService.startActivityAsUser(ActivityTaskManagerService.java:1215)
 D Test111 : 	at com.android.server.wm.ActivityTaskManagerService.startActivity(ActivityTaskManagerService.java:1190)
 D Test111 : 	at android.app.IActivityTaskManager$Stub.onTransact(IActivityTaskManager.java:893)
 D Test111 : 	at com.android.server.wm.ActivityTaskManagerService.onTransact(ActivityTaskManagerService.java:5119)
 D Test111 : 	at android.os.Binder.execTransactInternal(Binder.java:1179)
 D Test111 : 	at android.os.Binder.execTransact(Binder.java:1143)
 D Test111 : ActivityRecord{5297b65 u0 com.example.mytestapplication/.MainActivity t11} add child Window{c52dc92 u0 Splash Screen com.example.mytestapplication}
 D Test111 : java.lang.Exception
 D Test111 : 	at com.android.server.wm.WindowContainer.addChild(WindowContainer.java:517)
 D Test111 : 	at com.android.server.wm.WindowToken.addWindow(WindowToken.java:321)
 D Test111 : 	at com.android.server.wm.ActivityRecord.addWindow(ActivityRecord.java:3938)
 D Test111 : 	at com.android.server.wm.WindowManagerService.addWindow(WindowManagerService.java:1778)
 D Test111 : 	at com.android.server.wm.Session.addToDisplayAsUser(Session.java:204)
 D Test111 : 	at android.view.IWindowSession$Stub.onTransact(IWindowSession.java:646)
 D Test111 : 	at com.android.server.wm.Session.onTransact(Session.java:170)
 D Test111 : 	at android.os.Binder.execTransactInternal(Binder.java:1184)
 D Test111 : 	at android.os.Binder.execTransact(Binder.java:1143)
 D Test111 : ActivityRecord{5297b65 u0 com.example.mytestapplication/.MainActivity t11} add child Window{edc9045 u0 com.example.mytestapplication/com.example.mytestapplication.MainActivity}
 D Test111 : java.lang.Exception
 D Test111 : 	at com.android.server.wm.WindowContainer.addChild(WindowContainer.java:517)
 D Test111 : 	at com.android.server.wm.WindowToken.addWindow(WindowToken.java:321)
 D Test111 : 	at com.android.server.wm.ActivityRecord.addWindow(ActivityRecord.java:3938)
 D Test111 : 	at com.android.server.wm.WindowManagerService.addWindow(WindowManagerService.java:1778)
 D Test111 : 	at com.android.server.wm.Session.addToDisplayAsUser(Session.java:204)
 D Test111 : 	at android.view.IWindowSession$Stub.onTransact(IWindowSession.java:646)
 D Test111 : 	at com.android.server.wm.Session.onTransact(Session.java:170)
 D Test111 : 	at android.os.Binder.execTransactInternal(Binder.java:1179)
 D Test111 : 	at android.os.Binder.execTransact(Binder.java:1143)
            rootTask.minimalResumeActivityLocked(r);

从Log打印看,先创建Task,然后创建ActivityRecord,最后创建WindowState,

launcher从调用startActivity开始,经过ActivityTaskManagerService.javastartActivity,到ActivityStarter.java

java 复制代码
// ActivityStarter.java  
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) {
...
        if (mTargetRootTask == null) {
            // 1
            mTargetRootTask = getLaunchRootTask(mStartActivity, mLaunchFlags, targetTask, mOptions);
        }
        if (newTask) {
            // 2
            final Task taskToAffiliate = (mLaunchTaskBehind && mSourceRecord != null)
                    ? mSourceRecord.getTask() : null;
            setNewTask(taskToAffiliate);
        } else if (mAddingToTask) {
            addOrReparentStartingActivity(targetTask, "adding to task");
        } 
    	// 3
        if (newTask) {
            EventLogTags.writeWmCreateTask(mStartActivity.mUserId, startedTask.mTaskId);
        }    
        mStartActivity.logStartActivity(EventLogTags.WM_CREATE_ACTIVITY, startedTask)    
...

}
  1. 创建Task,参考下面1.2

  2. 创建ActivityRecord1.3

  3. 分别输出event log:

    java 复制代码
    wm_create_task: [0,27]
    wm_create_activity[0,268082872,27,com.example.mytestapplication/.MainActivity,android.intent.action.MAIN,NULL,NULL,270532608]

1.2 创建Task

调用到RootWindowContainer.javagetLaunchRootTask,找到DefaultTaskDisplayArea

在这里创建了Task 11, 并设置DefaultTaskDisplayArea为parent.

java 复制代码
   // TaskDisplayArea.java
    Task getOrCreateRootTask(int windowingMode, int activityType, boolean onTop,
            @Nullable Task candidateTask, @Nullable Task sourceTask,
            @Nullable ActivityOptions options, int launchFlags) {
        ...
        return new Task.Builder(mAtmService)
                .setWindowingMode(windowingMode)
                .setActivityType(activityType)
                .setOnTop(onTop)
                .setParent(this)
                .setSourceTask(sourceTask)
                .setActivityOptions(options)
                .setLaunchFlags(launchFlags)
                .build(); 
    }

在Task的构造函数的最后,会输出event log: wm_task_created: [mTaskId,getRootTaskId]

1.3 创建ActivityRecord

回到ActivityStarter.java startActivityInner,在创建完Task之后,调用setNewTask,经过的调用又会走到下面函数:

java 复制代码
// // ActivityStarter.java   
private void addOrReparentStartingActivity(@NonNull Task task, String reason) {
        TaskFragment newParent = task;
		...
        if (mStartActivity.getTaskFragment() == null
                || mStartActivity.getTaskFragment() == newParent) {
            newParent.addChild(mStartActivity, POSITION_TOP);
        } else {
            mStartActivity.reparent(newParent, newParent.getChildCount() /* top */, reason);
        }
    }

mStartActivity: 是ActivityStarter.java executeRequest函数中创建的ActivityRecord对象,并一直传递到startActivityInner函数,在函数第一句调用setInitialState函数时,就将刚创建的ActivityRecord对象赋值给了mStartActivity

newParent: 根据log推导,我们知道newParent就是刚创建的Task。

所以在这里将ActivityRecord挂在到Task上。

1.4 创建WindowState

再下面创建WindowState和挂载窗口层级的堆栈,看出来是app通过调用WMS的addToDisplayAsUser触发的,我们之前分析过,这部分是app在resume时候调用的,这个留在后面再说,我们先关注一下launcher的pause处理流程。

2. Pause

2.1 分析Pasue调用栈

PauseActivityItem.javaobtain函数打log,看谁构造了PauseActivityItem

java 复制代码
// PauseActivityItem.java
    /** Obtain an instance initialized with provided params. */
    public static PauseActivityItem obtain(boolean finished, boolean userLeaving, int configChanges,
            boolean dontReport) {
        PauseActivityItem instance = ObjectPool.obtain(PauseActivityItem.class);
        if (instance == null) {
            instance = new PauseActivityItem();
        }
        instance.mFinished = finished;
        instance.mUserLeaving = userLeaving;
        instance.mConfigChanges = configChanges;
        instance.mDontReport = dontReport;

        return instance;
    }

log中的调用栈如下:

java 复制代码
I Test111 : java.lang.Exception
I Test111 : 	at android.app.servertransaction.PauseActivityItem.obtain(PauseActivityItem.java:82)
I Test111 : 	at com.android.server.wm.TaskFragment.schedulePauseActivity(TaskFragment.java:1527)
I Test111 : 	at com.android.server.wm.TaskFragment.startPausing(TaskFragment.java:1469)
I Test111 : 	at com.android.server.wm.TaskFragment.startPausing(TaskFragment.java:1380)
I Test111 : 	at com.android.server.wm.TaskDisplayArea.lambda$pauseBackTasks$7(TaskDisplayArea.java:1478)
I Test111 : 	at com.android.server.wm.TaskDisplayArea$$ExternalSyntheticLambda4.accept(Unknown Source:6)
I Test111 : 	at com.android.server.wm.TaskFragment.forAllLeafTaskFragments(TaskFragment.java:1655)
I Test111 : 	at com.android.server.wm.TaskDisplayArea.lambda$pauseBackTasks$8$TaskDisplayArea(TaskDisplayArea.java:1475)
I Test111 : 	at com.android.server.wm.TaskDisplayArea$$ExternalSyntheticLambda6.accept(Unknown Source:8)
I Test111 : 	at com.android.server.wm.Task.forAllLeafTasks(Task.java:3185)
I Test111 : 	at com.android.server.wm.Task.forAllLeafTasks(Task.java:3173)
I Test111 : 	at com.android.server.wm.WindowContainer.forAllLeafTasks(WindowContainer.java:1781)
I Test111 : 	at com.android.server.wm.TaskDisplayArea.pauseBackTasks(TaskDisplayArea.java:1461)
I Test111 : 	at com.android.server.wm.TaskFragment.resumeTopActivity(TaskFragment.java:1059)
I Test111 : 	at com.android.server.wm.Task.resumeTopActivityInnerLocked(Task.java:5035)
I Test111 : 	at com.android.server.wm.Task.resumeTopActivityUncheckedLocked(Task.java:4970)
I Test111 : 	at com.android.server.wm.RootWindowContainer.resumeFocusedTasksTopActivities(RootWindowContainer.java:2361)
I Test111 : 	at com.android.server.wm.ActivityStarter.startActivityInner(ActivityStarter.java:1842)
I Test111 : 	at com.android.server.wm.ActivityStarter.startActivityUnchecked(ActivityStarter.java:1584)
I Test111 : 	at com.android.server.wm.ActivityStarter.executeRequest(ActivityStarter.java:1185)
I Test111 : 	at com.android.server.wm.ActivityStarter.execute(ActivityStarter.java:672)
I Test111 : 	at com.android.server.wm.ActivityTaskManagerService.startActivityAsUser(ActivityTaskManagerService.java:1243)
I Test111 : 	at com.android.server.wm.ActivityTaskManagerService.startActivityAsUser(ActivityTaskManagerService.java:1215)
I Test111 : 	at com.android.server.wm.ActivityTaskManagerService.startActivity(ActivityTaskManagerService.java:1190)
I Test111 : 	at android.app.IActivityTaskManager$Stub.onTransact(IActivityTaskManager.java:893)
I Test111 : 	at com.android.server.wm.ActivityTaskManagerService.onTransact(ActivityTaskManagerService.java:5119)
I Test111 : 	at android.os.Binder.execTransactInternal(Binder.java:1179)
I Test111 : 	at android.os.Binder.execTransact(Binder.java:1143)

可以看出来在app流程走到startActivityInner中会触发launcher的pause处理。

2.1 sysytem server发起pause

java 复制代码
// ActivityStarter.java  
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) {
...
        if (mTargetRootTask == null) {
            // 1
            mTargetRootTask = getLaunchRootTask(mStartActivity, mLaunchFlags, targetTask, mOptions);
        }
        if (newTask) {
            // 2
            final Task taskToAffiliate = (mLaunchTaskBehind && mSourceRecord != null)
                    ? mSourceRecord.getTask() : null;
            setNewTask(taskToAffiliate);
        } else if (mAddingToTask) {
            addOrReparentStartingActivity(targetTask, "adding to task");
        }    	
...
		// 3
        mRootWindowContainer.resumeFocusedTasksTopActivities(
                mTargetRootTask, mStartActivity, mOptions, mTransientLaunch);
}

startActivityInner的 1, 2部分分别是Task的构造和挂载,以及ActivityRecord的构造和挂载,上面已经介绍。

3则是launcher的pause, 通过函数名可以推测,它应该还包括目标Activity的resume处理,但我们先只关注pause.

在调用到TaskDisplayArea.javapauseBackTasks函数时:

java 复制代码
    boolean pauseBackTasks(ActivityRecord resuming) {
        final int[] someActivityPaused = {0};
        forAllLeafTasks((task) -> {
            final ActivityRecord resumedActivity = task.getResumedActivity();
            if (resumedActivity != null
                    && (task.getVisibility(resuming) != TASK_VISIBILITY_VISIBLE
                    || !task.isTopActivityFocusable())) {
                ProtoLog.d(WM_DEBUG_STATES, "pauseBackTasks: task=%s "
                        + "mResumedActivity=%s", task, resumedActivity);
                if (task.startPausingLocked(false /* uiSleeping*/,
                        resuming, "pauseBackTasks")) {
                    someActivityPaused[0]++;
                }
            }
        }, true /* traverseTopToBottom */);
        return someActivityPaused[0] > 0;
    }

forAllLeafTasks的真正实现在Task.java,这类写法我们之前在分析WMS时也经常见到,就是在WindowContainer.java以及它的子类中都会有实现,

但一般真正的处理,只在其中一个类中,目的就是递归每一个窗口层级节点。

java 复制代码
 // Task.java
void forAllLeafTasks(Consumer<Task> callback, boolean traverseTopToBottom) {
        final int count = mChildren.size();
        boolean isLeafTask = true;
        if (traverseTopToBottom) {
            for (int i = count - 1; i >= 0; --i) {
                final Task child = mChildren.get(i).asTask();
                if (child != null) {
                    isLeafTask = false;
                    child.forAllLeafTasks(callback, traverseTopToBottom);
                }
            }
        }
        ...
        if (isLeafTask) callback.accept(this);
    }

forAllLeafTasks的目的是找到leaf task,即:该Task的child是否还是task,如果是,就不是leaf task, 如果不是,就是leaf task,找到之后继续执行上面的

2.2 通知launcher pasue

pauseBackTasks,找到满足条件的activity, 从目前来看满足条件的只有一个,就是launcher, 调用startPausing,最终会调用ATMS,通知launcher pause

java 复制代码
  // TaskFragment.java
  void schedulePauseActivity(ActivityRecord prev, boolean userLeaving,
          boolean pauseImmediately, String reason) {
      ProtoLog.v(WM_DEBUG_STATES, "Enqueueing pending pause: %s", prev);
      try {
          // 1
          EventLogTags.writeWmPauseActivity(prev.mUserId, System.identityHashCode(prev),
                  prev.shortComponentName, "userLeaving=" + userLeaving, reason);
		  // 2
          mAtmService.getLifecycleManager().scheduleTransaction(prev.app.getThread(),
                  prev.appToken, PauseActivityItem.obtain(prev.finishing, userLeaving,
                          prev.configChangeFlags, pauseImmediately));
      } catch (Exception e) {
 	...
  }
  1. 输出event log: wm_pause_activity: [0,96028723,com.android.launcher3/.uioverrides.QuickstepLauncher,userLeaving=true,pauseBackTasks]
  2. prev.app.getThread(): 就是launcher的ApplicationThread, scheduleTransaction的第三个参数是new了一个PauseActivityItem,最后会通过binder通信走到launcher的ApplicationThreadscheduleTransaction函数。

2.3 launcher处理pasue

在launcher进程内,从binder线程切换到主线程,然后调用TransactionExecutor.javaexecute,最后走到executeLifecycleState

java 复制代码
// TransactionExecutor.java 
private void executeLifecycleState(ClientTransaction transaction) {
	...
     // Execute the final transition with proper parameters.
      // 1
     lifecycleItem.execute(mTransactionHandler, token, mPendingActions);
     // 2
     lifecycleItem.postExecute(mTransactionHandler, token, mPendingActions);
  1. 走到PauseActivityItem.javaexecute,调用ActivityThread.javaperformPauseActivity,然后走到Activity.javaperformPause, 这里会走到我们熟悉的Actvity的onPause,并输出evnet log:wm_on_paused_called
  2. 走到PauseActivityItem.javapostExecute,其中会走到ActivityClient.javagetActivityClientController().activityPaused(token);getActivityClientController()会返回ActivityClientControllerSingleton类的静态对象,看下它的实现:
java 复制代码
// ActivityClient.java   
private static class ActivityClientControllerSingleton
            extends Singleton<IActivityClientController> {
	...
        protected IActivityClientController create() {
            try {
                return ActivityTaskManager.getService().getActivityClientController();
			...
    }

mark 1可以看出来getActivityClientController()其实就是为了方便和ATMS通信,返回了ATMS的内部类ActivityClientController,它当然也是继承自

IInterface.stub的:class ActivityClientController extends IActivityClientController.Stub

回到上面的postExecute,它其实最后就会和system_server通信,走到ActivityClientController.javaactivityPaused.

2.4 launcher通知system servfer Paused

java 复制代码
 // ActivityClientController.java
 public void activityPaused(IBinder token) {
     final long origId = Binder.clearCallingIdentity();
     synchronized (mGlobalLock) {
         Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "activityPaused");
         final ActivityRecord r = ActivityRecord.forTokenLocked(token);
         if (r != null) {
             r.activityPaused(false);
         }
         Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
     }
     Binder.restoreCallingIdentity(origId);
 }

通过token定位到具体的ActivityRecord,调用ActivityRecordactivityPaused

java 复制代码
// ActivityRecord.java
void activityPaused(boolean timeout) {
    ProtoLog.v(WM_DEBUG_STATES, "Activity paused: token=%s, timeout=%b", appToken,
            timeout);
	// 1
    final TaskFragment taskFragment = getTaskFragment();
    if (taskFragment != null) {
        removePauseTimeout();
		// 2
        final ActivityRecord pausingActivity = taskFragment.getPausingActivity();
        if (pausingActivity == this) {
            ProtoLog.v(WM_DEBUG_STATES, "Moving to PAUSED: %s %s", this,
                    (timeout ? "(due to timeout)" : " (pause complete)"));
            mAtmService.deferWindowLayout();
            try {
                // 3
                taskFragment.completePause(true /* resumeNext */, null /* resumingActivity */);
            } finally {
                mAtmService.continueWindowLayout();
            }
            return;
        } else {
  1. 找到ActivityRecord对应的Task,也就是launcher对应的Home Task.
  2. 返回Task的mPausingActivity,在上面system server pause launcher的过程中就给mPausingActivity赋值了,所以if可以走进去。
  3. 走到TaskFragment.javacompletePause.

3 创建app process

3.1 分析startProcessAsync调用栈

app resume的处理时序又是什么样的,如果只是正向分析代码很难,会发现很多case都会走到startProcessAsync

不妨通过关键节点来打印堆栈来看下,log有点多,分段解读。

3.1.1 第一段log

java 复制代码
Test111 : DefaultTaskDisplayArea@253126244 add child 222 Task{936fd9 #22 type=standard ?? U=0 visible=false visibleRequested=false mode=undefined translucent=true sz=0}
 // ...省略startActivity Task的创建和挂载log
Test111 : Task{936fd9 #22 type=standard A=10106:com.example.mytestapplication U=0 visible=false visibleRequested=false mode=fullscreen translucent=true sz=0} add child 222 ActivityRecord{1c23095 u0 com.example.mytestapplication/.MainActivity
// ...省略startActivity ActivityRecord 的创建和挂载log

startActivity过程中创建Task和ActivityRecord, 并挂载到窗口层级树。

3.1.2 第二段log

java 复制代码
 Test111 : startProcessAsync, processName=com.example.mytestapplication
 Test111 : java.lang.Exception
 Test111 : 	at com.android.server.wm.ActivityTaskManagerService.startProcessAsync(ActivityTaskManagerService.java:4681)
 Test111 : 	at com.android.server.wm.TaskFragment.resumeTopActivity(TaskFragment.java:1081)
 Test111 : 	at com.android.server.wm.Task.resumeTopActivityInnerLocked(Task.java:5035)
 Test111 : 	at com.android.server.wm.Task.resumeTopActivityUncheckedLocked(Task.java:4970)
 Test111 : 	at com.android.server.wm.RootWindowContainer.resumeFocusedTasksTopActivities(RootWindowContainer.java:2361)
 Test111 : 	at com.android.server.wm.ActivityStarter.startActivityInner(ActivityStarter.java:1842)
 Test111 : 	at com.android.server.wm.ActivityStarter.startActivityUnchecked(ActivityStarter.java:1584)
 Test111 : 	at com.android.server.wm.ActivityStarter.executeRequest(ActivityStarter.java:1185)
 Test111 : 	at com.android.server.wm.ActivityStarter.execute(ActivityStarter.java:672)
 Test111 : 	at com.android.server.wm.ActivityTaskManagerService.startActivityAsUser(ActivityTaskManagerService.java:1243)
 Test111 : 	at com.android.server.wm.ActivityTaskManagerService.startActivityAsUser(ActivityTaskManagerService.java:1215)
 Test111 : 	at com.android.server.wm.ActivityTaskManagerService.startActivity(ActivityTaskManagerService.java:1190)
 Test111 : 	at android.app.IActivityTaskManager$Stub.onTransact(IActivityTaskManager.java:893)
 Test111 : 	at com.android.server.wm.ActivityTaskManagerService.onTransact(ActivityTaskManagerService.java:5124)
 Test111 : 	at android.os.Binder.execTransactInternal(Binder.java:1179)
 Test111 : 	at android.os.Binder.execTransact(Binder.java:1143)
 Test111 : startProcessLocked, processName=com.example.mytestapplication
 Test111 : startProcess222, processName=com.example.mytestapplication
 Test111 : java.lang.Exception
 Test111 : 	at com.android.server.am.ProcessList.startProcess(ProcessList.java:2432)
 Test111 : 	at com.android.server.am.ProcessList.handleProcessStart(ProcessList.java:2177)
 Test111 : 	at com.android.server.am.ProcessList.lambda$startProcessLocked$0$ProcessList(ProcessList.java:2104)
 Test111 : 	at com.android.server.am.ProcessList$$ExternalSyntheticLambda1.run(Unknown Source:22)
 Test111 : 	at android.os.Handler.handleCallback(Handler.java:938)
 Test111 : 	at android.os.Handler.dispatchMessage(Handler.java:99)
 Test111 : 	at android.os.Looper.loopOnce(Looper.java:201)
 Test111 : 	at android.os.Looper.loop(Looper.java:288)
 Test111 : 	at android.os.HandlerThread.run(HandlerThread.java:67)
 Test111 : 	at com.android.server.ServiceThread.run(ServiceThread.java:44)

这一段log,我分别在ActivityTaskManagerService.java -- startProcessAsync函数ProcessList.java -- startProcessLocked函数,以及ProcessList.java -- startProcess函数 ,追加log堆栈调用打印。

可以看到start app进程的地方还是在ActivityStarter.startActivityInner:

java 复制代码
// ActivityStarter.java  
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) {
...
        if (mTargetRootTask == null) {
            // 1 创建Task并挂载到窗口层级树
            mTargetRootTask = getLaunchRootTask(mStartActivity, mLaunchFlags, targetTask, mOptions);
        }
        if (newTask) {
            // 2 创建ActivityRecord并挂载到窗口层级树
            final Task taskToAffiliate = (mLaunchTaskBehind && mSourceRecord != null)
                    ? mSourceRecord.getTask() : null;
            setNewTask(taskToAffiliate);
        } else if (mAddingToTask) {
            addOrReparentStartingActivity(targetTask, "adding to task");
        }    	
...
		// 3
        mRootWindowContainer.resumeFocusedTasksTopActivities(
                mTargetRootTask, mStartActivity, mOptions, mTransientLaunch);

}

mark 3中经过一系列的调用,在TaskFragment.java -- resumeTopActivity函数中:

java 复制代码
    final boolean resumeTopActivity(ActivityRecord prev, ActivityOptions options,
            boolean deferPause) {
        ActivityRecord next = topRunningActivity(true /* focusableOnly */);
        if (next == null || !next.canResumeByCompat()) {
            return false;Resume
        }
        ...
        // 1
        boolean pausing = !deferPause && taskDisplayArea.pauseBackTasks(next);
        // 2
        if (pausing) {
  			...
            // 3
            if (next.attachedToProcess()) {
                next.app.updateProcessInfo(false /* updateServiceConnectionActivities */,
                        true /* activityChange */, false /* updateOomAdj */,
                        false /* addPendingTopUid */);
            // 4
            } else if (!next.isProcessRunning()) {
                // Since the start-process is asynchronous, if we already know the process of next
                // activity isn't running, we can start the process earlier to save the time to wait
                // for the current activity to be paused.
                final boolean isTop = this == taskDisplayArea.getFocusedRootTask();
                // 5
                mAtmService.startProcessAsync(next, false /* knownToBeDead */, isTop,
                        isTop ? "pre-top-activity" : "pre-activity");
            }        
  1. pause流程,上面说了。
  2. 上面刚处理pause,所以在pausing中。
  3. 我们是冷启动app,app进程还没有创建出来,所以这里if不满足
  4. 我们是冷启动app,app进程还没有创建出来,if满足
  5. 开始startProcess流程,先调用ATMS的startProcessAsync,再调用AMS的startProcess,最后走到Process.javastart函数来拉起app进程。

令我比较疑惑的是,除了在startActivityInner中会走startProcess, 还有其他地方也会走到startProcess, 比如如下:

3.1.3 第三段log

java 复制代码
 Test111 : startProcessAsync, processName=com.example.mytestapplication
 Test111 : java.lang.Exception
 Test111 : 	at com.android.server.wm.ActivityTaskManagerService.startProcessAsync(ActivityTaskManagerService.java:4681)
 Test111 : 	at com.android.server.wm.ActivityTaskSupervisor.startSpecificActivity(ActivityTaskSupervisor.java:1013)
 Test111 : 	at com.android.server.wm.TaskFragment.resumeTopActivity(TaskFragment.java:1345)
 Test111 : 	at com.android.server.wm.Task.resumeTopActivityInnerLocked(Task.java:5035)
 Test111 : 	at com.android.server.wm.Task.resumeTopActivityUncheckedLocked(Task.java:4970)
 Test111 : 	at com.android.server.wm.RootWindowContainer.resumeFocusedTasksTopActivities(RootWindowContainer.java:2361)
 Test111 : 	at com.android.server.wm.RootWindowContainer.resumeFocusedTasksTopActivities(RootWindowContainer.java:2347)
 Test111 : 	at com.android.server.wm.TaskFragment.completePause(TaskFragment.java:1596)
 Test111 : 	at com.android.server.wm.ActivityRecord.activityPaused(ActivityRecord.java:5714)
 Test111 : 	at com.android.server.wm.ActivityClientController.activityPaused(ActivityClientController.java:175)
 Test111 : 	at android.app.IActivityClientController$Stub.onTransact(IActivityClientController.java:548)
 Test111 : 	at com.android.server.wm.ActivityClientController.onTransact(ActivityClientController.java:121)
 Test111 : 	at android.os.Binder.execTransactInternal(Binder.java:1179)
 Test111 : 	at android.os.Binder.execTransact(Binder.java:1143)

在lanuncer进程回调activityPausedcompletePause处理中,也会走到startProcessAsync

3.1.4 第四段log

java 复制代码
 Test111 : startProcessAsync, processName=com.example.mytestapplication
 Test111 : java.lang.Exception
 Test111 : 	at com.android.server.wm.ActivityTaskManagerService.startProcessAsync(ActivityTaskManagerService.java:4681)
 Test111 : 	at com.android.server.wm.ActivityTaskSupervisor.startSpecificActivity(ActivityTaskSupervisor.java:1013)
 Test111 : 	at com.android.server.wm.EnsureActivitiesVisibleHelper.makeVisibleAndRestartIfNeeded(EnsureActivitiesVisibleHelper.java:265)
 Test111 : 	at com.android.server.wm.EnsureActivitiesVisibleHelper.setActivityVisibilityState(EnsureActivitiesVisibleHelper.java:191)
 Test111 : 	at com.android.server.wm.EnsureActivitiesVisibleHelper.process(EnsureActivitiesVisibleHelper.java:139)
 Test111 : 	at com.android.server.wm.TaskFragment.updateActivityVisibilities(TaskFragment.java:979)
 Test111 : 	at com.android.server.wm.Task.lambda$ensureActivitiesVisible$15(Task.java:4866)
 Test111 : 	at com.android.server.wm.Task$$ExternalSyntheticLambda20.accept(Unknown Source:10)
 Test111 : 	at com.android.server.wm.Task.forAllLeafTasks(Task.java:3185)
 Test111 : 	at com.android.server.wm.Task.ensureActivitiesVisible(Task.java:4865)
 Test111 : 	at com.android.server.wm.DisplayContent.lambda$ensureActivitiesVisible$46(DisplayContent.java:5999)
 Test111 : 	at com.android.server.wm.DisplayContent$$ExternalSyntheticLambda17.accept(Unknown Source:10)
 Test111 : 	at com.android.server.wm.Task.forAllRootTasks(Task.java:3197)
 Test111 : 	at com.android.server.wm.WindowContainer.forAllRootTasks(WindowContainer.java:1817)
 Test111 : 	at com.android.server.wm.WindowContainer.forAllRootTasks(WindowContainer.java:1817)
 Test111 : 	at com.android.server.wm.WindowContainer.forAllRootTasks(WindowContainer.java:1817)
 Test111 : 	at com.android.server.wm.WindowContainer.forAllRootTasks(WindowContainer.java:1817)
 Test111 : 	at com.android.server.wm.WindowContainer.forAllRootTasks(WindowContainer.java:1817)
 Test111 : 	at com.android.server.wm.WindowContainer.forAllRootTasks(WindowContainer.java:1817)
 Test111 : 	at com.android.server.wm.WindowContainer.forAllRootTasks(WindowContainer.java:1810)
 Test111 : 	at com.android.server.wm.DisplayContent.ensureActivitiesVisible(DisplayContent.java:5998)
 Test111 : 	at com.android.server.wm.RootWindowContainer.ensureActivitiesVisible(RootWindowContainer.java:2020)
 Test111 : 	at com.android.server.wm.RootWindowContainer.ensureActivitiesVisible(RootWindowContainer.java:2001)
 Test111 : 	at com.android.server.wm.TaskFragment.completePause(TaskFragment.java:1616)
 Test111 : 	at com.android.server.wm.ActivityRecord.activityPaused(ActivityRecord.java:5714)
 Test111 : 	at com.android.server.wm.ActivityClientController.activityPaused(ActivityClientController.java:175)
 Test111 : 	at android.app.IActivityClientController$Stub.onTransact(IActivityClientController.java:548)
 Test111 : 	at com.android.server.wm.ActivityClientController.onTransact(ActivityClientController.java:121)
 Test111 : 	at android.os.Binder.execTransactInternal(Binder.java:1179)
 Test111 : 	at android.os.Binder.execTransact(Binder.java:1143)

在lanuncer进程回调activityPausedensureActivitiesVisible处理中,也会走到startProcessAsync

但前面已经有startProcess的触发了,后面又来了2次,会不会有问题,答案当然是不会。

如果app进程拉起的快,会在ProcessList.javastartProcessLocked函数中判断如果该app进程已经启动,直接return.

如果app进程拉起的慢,同样会在ProcessList.javastartProcessLocked函数(和上面不是同一个startProcessLocked)中判断该app进程是isPendingStart,也会return。

3.2 app进程启动

上面讲了AMS通过zygote拉起app进程。那么app进程起来后的流程是什么样的,继续分析。

当app进程起来后,会先执行ActivityThread.javamain函数。

java 复制代码
    // ActivityThread.java
    public static void main(String[] args) {
        Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "ActivityThreadMain");
        ...
        ActivityThread thread = new ActivityThread();
        thread.attach(false, startSeq);        

构造出ActivityThread,并调用其attach函数,在ActivityThreadattach函数中,调用mgr.attachApplication(mAppThread, startSeq);, mgr就是AMS在app侧的代理。所以这里就调用到了system server进程中,调用ActivityManagerService.javaattachApplication.

java 复制代码
// ActivityManagerService.java
    private boolean attachApplicationLocked(@NonNull IApplicationThread thread,
            int pid, int callingUid, long startSeq) {
		...
        // 1
		EventLogTags.writeAmProcBound(app.userId, pid, app.processName);
        ...
        // 2
    	thread.bindApplication( ...
		// 3
        if (normalMode) {
            try {
                didSomething = mAtmInternal.attachApplication(app.getWindowProcessController());
   		...                             
  1. 输出event log: am_proc_bound: [0,1854,com.example.mytestapplication]
  2. 回调ActivityThread的bindApplication,在app进程中,在这一步会调用Application的onCreate
  3. 调用ATMS的attachApplication, ATMS内部又会调用RootWindowContainer.javaattachApplication.
java 复制代码
    boolean attachApplication(WindowProcessController app) throws RemoteException {
     ...
        for (int displayNdx = getChildCount() - 1; displayNdx >= 0; --displayNdx) {
          ...
            final DisplayContent display = getChildAt(displayNdx);
            //1
            display.forAllRootTasks(rootTask -> {
                if (mTmpRemoteException != null) {
                    return;
                }

                if (rootTask.getVisibility(null /* starting */)
                        == TASK_FRAGMENT_VISIBILITY_INVISIBLE) {
                    return;
                }

                final PooledFunction c = PooledLambda.obtainFunction(
                        RootWindowContainer::startActivityForAttachedApplicationIfNeeded, this,
                        PooledLambda.__(ActivityRecord.class), app,
                        rootTask.topRunningActivity());
                // 2
                rootTask.forAllActivities(c);
                c.recycle();
            });
		...
    }
  1. forAllRootTasks: 轮询窗口层级结构树,它的真正实现在Task.java中:
java 复制代码
    @Override
    void forAllRootTasks(Consumer<Task> callback, boolean traverseTopToBottom) {
        if (isRootTask()) {
            callback.accept(this);
        }
    }

callback.accept(this); : 将Task作为参数传入attachApplication函数内的lambda表达式, 并执行。

  1. lambda表达式内又会轮询窗口层级结构树,它的实现在ActivityRecord.java中:
java 复制代码
    boolean forAllActivities(
            Function<ActivityRecord, Boolean> callback, boolean traverseTopToBottom) {
        return callback.apply(this);
    }

ActivityRecord作为参数带入上面的PooledFunction c,并执行c, c的实现是调用RootWindowContainer::startActivityForAttachedApplicationIfNeeded,其中又会调用ActivityTaskSupervisor.java

realStartActivityLocked

4 app process onCreate/onStart/onResume

4.1 realStartActivityLocked

java 复制代码
// ActivityTaskSupervisor.java
    boolean realStartActivityLocked(ActivityRecord r, WindowProcessController proc,
            boolean andResume, boolean checkConfig) throws RemoteException {
        // 1
       if (!mRootWindowContainer.allPausedActivitiesComplete()) {
            // While there are activities pausing we skipping starting any new activities until
            // pauses are complete. NOTE: that we also do this for activities that are starting in
            // the paused state because they will first be resumed then paused on the client side.
            ProtoLog.v(WM_DEBUG_STATES,
                    "realStartActivityLocked: Skipping start of r=%s some activities pausing...",
                    r);
            return false;
                
		...
            // 2
            EventLogTags.writeWmRestartActivity(r.mUserId, System.identityHashCode(r),
                        task.mTaskId, r.shortComponentName);      
        	// 3
           clientTransaction.addCallback(LaunchActivityItem.obtain(new Intent(r.intent),
			...
           // Set desired final state.
           final ActivityLifecycleItem lifecycleItem;
           if (andResume) {
               lifecycleItem = ResumeActivityItem.obtain(isTransitionForward);
           } else {
               lifecycleItem = PauseActivityItem.obtain();
           }
           clientTransaction.setLifecycleStateRequest(lifecycleItem);

           // Schedule transaction.
         	// 4                                                          
           mService.getLifecycleManager().scheduleTransaction(clientTransaction);
           ...
           // 5
           rootTask.minimalResumeActivityLocked(r);           
   
  1. 检查是不是所有的activity是否已经pause,如果没有是不允许继续往下走的.
  2. 输出event log: wm_restart_activity: [0,29503637,22,com.example.mytestapplication/.MainActivity],注意这里面的restart不是重新开始的意思,而是real start的缩写。
  3. 构造一个LaunchActivityItem对象,添加到clientTransactionmActivityCallbacks, 构造一个ResumeActivityItem对象,赋值给clientTransactionmLifecycleStateRequest成员。
  4. scheduleTransaction, 内部是一次binder通信,调用到app进程,走到ActivityThread.java内部类ApplicationThreadscheduleTransaction函数,在走到TransactionExecutor.javaexecute函数,参考下面4.2
  5. minimalResumeActivityLocked,参考下面4.3

4.2 scheduleTransaction

java 复制代码
// TransactionExecutor.java   
	public void execute(ClientTransaction transaction) {
  		...
        // 1
        executeCallbacks(transaction);
		// 2
        executeLifecycleState(transaction);
        mPendingActions.clear();
        if (DEBUG_RESOLVER) Slog.d(TAG, tId(transaction) + "End resolving transaction");
    }
  1. clientTransactionmActivityCallbacks中拿到LaunchActivityItem对象,执行其Execute函数,最终会走到Activity.javaperformCreate, 在这里会回调Activity的onCreate,以及输出event log:

    wm_on_create_called: [29503637,com.example.mytestapplication.MainActivity,performCreate]

  2. executeLifecycleState中有2个重要的处理, 参考下面代码中的注释:

java 复制代码
// TransactionExecutor.java   
	private void executeLifecycleState(ClientTransaction transaction) {
        // 1
        final ActivityLifecycleItem lifecycleItem = transaction.getLifecycleStateRequest();
        ...
        // Cycle to the state right before the final requested state.
		// 2
        cycleToPath(r, lifecycleItem.getTargetState(), true /* excludeLastState */, transaction);

        // Execute the final transition with proper parameters.
        // 3
        lifecycleItem.execute(mTransactionHandler, token, mPendingActions);
        lifecycleItem.postExecute(mTransactionHandler, token, mPendingActions);
    }
  1. 拿到ResumeActivityItem对象。

  2. 因为当前是onCreate状态,要迁移到onResume状态,中间还间隔了一个onStart,所以这里会走一次ActivityThread.java的handleStartActivity,最后走到Activity.javaperformStart函数,

    java 复制代码
    // Activity.java   
    final void performStart(String reason) {
    		...
            // 回调Activity OnStart
            mInstrumentation.callActivityOnStart(this);
    		...
             // 输出event log: wm_on_start_called: [268082872,com.example.mytestapplication.MainActivity,handleStartActivity]
            EventLogTags.writeWmOnStartCalled(mIdent, getComponentName().getClassName(), reason);
  3. 执行ResumeActivityItem的execute,会执行到Activity.javaperformResume函数,其中会回调Activity的OnResume,并且输出event log: wm_on_resume_called: [268082872,com.example.mytestapplication.MainActivity,RESUME_ACTIVITY]

相关推荐
dora11 小时前
Android弱网优化 —— 都要卫星互联网了,谁给我限速体验2G
android·性能优化
用户31714786113312 小时前
仿今日头条 APP 开发实战:RecyclerView 核心玩法 + 全布局体系深度拆解
android
用户416596736935512 小时前
在 Jetpack Compose 中实现拼音与四线三格的精准对齐
android
用户693717500138412 小时前
太钻 Android 了,在电鸭刷私活把我自己刷清醒了
android·前端·github
冰语竹12 小时前
Android学习之Activity生命周期
android·学习
lizhenjun11412 小时前
Aosp14及后续版本默认不可用profiler调试问题分析
android·学习
独隅12 小时前
MacOS 系统下 ADB (Android Debug Bridge) 全面安装与配置指南
android·macos·adb
SammeryD12 小时前
Android gradle镜像
android
2501_9151063212 小时前
Flutter 开发工具有哪些 跨平台项目开发与上架实操指南
android·flutter·ios·小程序·uni-app·iphone·webview