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]

相关推荐
恋猫de小郭2 小时前
Flutter 设计包解耦新进展,material_ui 和 cupertino_ui 发布预告
android·前端·flutter
blackorbird5 小时前
新型Keenadu安卓固件级后门揭开跨僵尸网络协同攻击链条
android·网络
前路不黑暗@6 小时前
Java项目:Java脚手架项目的阿里云短信服务集成(十六)
android·java·spring boot·学习·spring cloud·阿里云·maven
吴声子夜歌6 小时前
RxJava——Flowable与背压
android·java·rxjava
L-李俊漩6 小时前
Android studio修改gradle路径
android·android studio
九狼JIULANG7 小时前
基于Flutter+Riverpod+MVI 实现的跨平台「AI 提示词优化工具」
android·开源·github
山北雨夜漫步7 小时前
点评day03优惠卷秒杀-库存超卖,一人一单(单机模式)
android
zh_xuan7 小时前
React Native页面加载流程
android·react native
yuezhilangniao8 小时前
从Next.js到APK:Capacitor跨平台(安卓端)打包完全指南
android·开发语言·javascript