当我点击桌面App的图标时发生了什么-浅析Activity启动流程(代码基于Android-12)

当我点击桌面App的图标时发生了什么-浅析Activity启动流程(代码基于Android-12)

文章目录

一、当我的手指点击了桌面的App-Icon

1.检测桌面图标被点击

当桌面图标BubbleTextView被点击时,触发点击事件,调用其startActivitySafely()方法,然后调用Activity#startActivity()方法

    
public boolean startActivitySafely(View v, Intent intent, @Nullable ItemInfo item,
            @Nullable String sourceContainer) {
        // ...

        Bundle optsBundle = (v != null) ? getActivityLaunchOptionsAsBundle(v) : null;
        UserHandle user = item == null ? null : item.user;

        // Prepare intent
        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        // ...
        try {
            boolean isShortcut = (item instanceof WorkspaceItemInfo)
                    && (item.itemType == Favorites.ITEM_TYPE_SHORTCUT
                    || item.itemType == Favorites.ITEM_TYPE_DEEP_SHORTCUT)
                    && !((WorkspaceItemInfo) item).isPromise();
            if (isShortcut) {
                // Shortcuts need some special checks due to legacy reasons.
                // ....
            } else if (user == null || user.equals(Process.myUserHandle())) {
                
              	// 调用 Activity.startActivity()
                // opts不为空,Launcher.isChild=false(mParent==null)
                startActivity(intent, optsBundle);
                
               // ...
            } else {
                // ...
            }
            // ...
            return true;
        } catch (ActivityNotFoundException|SecurityException e) {
            Toast.makeText(this, R.string.activity_not_found, Toast.LENGTH_SHORT).show();
            Log.e(TAG, "Unable to launch. tag=" + item + " intent=" + intent, e);
        }
        return false;
    }

2.调用 Activity#startActivityForResult()

    @Override
    public void startActivity(Intent intent, @Nullable Bundle options) {
        // 判断intent是否要设置一些属性
        ....
        if (options != null) {
            // 走这里
            startActivityForResult(intent, -1, options);
        } else {
            // Note we want to go through this call for compatibility with
            // applications that may have overridden the method.
            startActivityForResult(intent, -1);
        }
    }

二、APP正在热身(从点击BubbleTextViewActivityThread#main()执行)(代码较长,请耐心阅读哦)

2.1 Activity#startActivityForResult()

public void startActivityForResult(@RequiresPermission Intent intent, int requestCode,
            @Nullable Bundle options) {
    	// Launcher.mParent ==null
    	// 在Launcher对象被创建后执行了attach()方法会设置mParent,传入的是null
   		// 或者调用设置setParent()
        if (mParent == null) {
            options = transferSpringboardActivityOptions(options);
            // 调用 Instrumentation.execStartActivity(), 这是个调度方法类,里面有很多callXXX等和Activity,Application相关方法
            Instrumentation.ActivityResult ar =
                mInstrumentation.execStartActivity(
                    this, mMainThread.getApplicationThread(), mToken, this,
                    intent, requestCode, options);
            
            if (ar != null) {
                mMainThread.sendActivityResult(
                    mToken, mEmbeddedID, requestCode, ar.getResultCode(),
                    ar.getResultData());
            }
            
            if (requestCode >= 0) {
                // If this start is requesting a result, we can avoid making
                // the activity visible until the result is received.  Setting
                // this code during onCreate(Bundle savedInstanceState) or onResume() will keep the
                // activity hidden during this time, to avoid flickering.
                // This can only be done when a result is requested because
                // that guarantees we will get information back when the
                // activity is finished, no matter what happens to it.
                mStartedActivity = true;
            }

            cancelInputsAndStartExitTransition(options);
            // TODO Consider clearing/flushing other event sources and events for child windows.
        } else {
            if (options != null) {
                mParent.startActivityFromChild(this, intent, requestCode, options);
            } else {
                // Note we want to go through this method for compatibility with
                // existing applications that may have overridden it.
                mParent.startActivityFromChild(this, intent, requestCode);
            }
        }
    }

2.2 Instrumentation#execStartActivity()

// who: Launcher
// contextThread: Launcher进程所在ApplicationThread
public ActivityResult execStartActivity(
            Context who, IBinder contextThread, IBinder token, Activity target,
            Intent intent, int requestCode, Bundle options) {
        IApplicationThread whoThread = (IApplicationThread) contextThread;
        // ...
        // ...
        try {
            intent.migrateExtraStreamToClipData(who);
            intent.prepareToLeaveProcess(who);
            // 调用 ActivityTaskManager.aidl实现:ATMS(ActivityTaskManagerService)#startActivity()
            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);
            checkStartActivityResult(result, intent);
        } catch (RemoteException e) {
            throw new RuntimeException("Failure from system", e);
        }
        return null;
    }
ATM.getService() -> IActivityTaskManager
/** @hide */ 
public static IActivityTaskManager getService() { 
	return IActivityTaskManagerSingleton.get(); 
}

IActivityTaskManager.aidl, 实现为ActivitytTaskManagerService.java

public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
 // ....
}

2.4 ATMS#startActivityAsUser

private int startActivityAsUser(IApplicationThread caller, String callingPackage,
                                    @Nullable String callingFeatureId, Intent intent, String resolvedType,
                                    IBinder resultTo, String resultWho, int requestCode, int startFlags,
                                    ProfilerInfo profilerInfo, Bundle bOptions, int userId, boolean validateIncomingUser) {
        assertPackageMatchesCallingUid(callingPackage);
        
        // ...

        userId = getActivityStartController().checkTargetUser(userId, validateIncomingUser,
                Binder.getCallingPid(), Binder.getCallingUid(), "startActivityAsUser");

        // TODO: Switch to user app stacks here.
    
    	// 获取 ActivityStarter, 然后配置属性,最后调用execute()
    	// 等于是把方法传入的参数值变相的保存到一个类中
        return getActivityStartController().obtainStarter(intent, "startActivityAsUser")
        		// Launcher所在的ApplicationThread
                .setCaller(caller)
                .setCallingPackage(callingPackage)
                .setCallingFeatureId(callingFeatureId)
                .setResolvedType(resolvedType)
                .setResultTo(resultTo)
                .setResultWho(resultWho)
                .setRequestCode(requestCode)
                .setStartFlags(startFlags)
                .setProfilerInfo(profilerInfo)
                .setActivityOptions(bOptions)
                .setUserId(userId)
            	// 配置好ActivityStarter后,开始执行
                .execute();

    }
  • getActivityStartController()是什么?

    ActivityStartController getActivityStartController() {
            return mActivityStartController;
    }
    

    一个控制启动Activity的类…

    上面的方法是把启动Activity所需的信息全部设置到obtainStarter()返回的对象[ActivityStarter]中了:

    // 委派Activity活动启动的控制器
    public class ActivityStartController {
        // 用于starter回收复用的接口
        Factory mFactory;
        
        // 1, 看下面
        ActivityStarter obtainStarter(Intent intent, String reason) {
            return mFactory.obtain().setIntent(intent).setReason(reason);
        }
    }
    
    
    // Factory默认实现, 用来从缓存池获取一个AS对象
        static class DefaultFactory implements Factory {
            // ...
    
            // 2  获取一个ActivityStarter
            @Override
            public ActivityStarter obtain() {
                ActivityStarter starter = mStarterPool.acquire();
    
                if (starter == null) {
                    if (mService.mRootWindowContainer == null) {
                        throw new IllegalStateException("Too early to start activity.");
                    }
                    starter = new ActivityStarter(mController, mService, mSupervisor, mInterceptor);
                }
    
                return starter;
            }
        }
    
    

    OK,ActivityStarter获取好了,回到2.4,配置好后执行ActivityStarter#execute(),继续跟进!

2,5 ActivityStarter#execute()

int execute() {
    // ...  ActivityInfo和Intent合法性检查
    
    // 新建启动结果
    int res;
            synchronized (mService.mGlobalLock) {
                final boolean globalConfigWillChange = mRequest.globalConfig != null
                        && mService.getGlobalConfiguration().diff(mRequest.globalConfig) != 0;
                final Task rootTask = mRootWindowContainer.getTopDisplayFocusedRootTask();
                if (rootTask != null) {
                    rootTask.mConfigWillChange = globalConfigWillChange;
                }
               

                final long origId = Binder.clearCallingIdentity();

                // 某些意外情况导致启动不成功,具体是什么不知道
                res = resolveToHeavyWeightSwitcherIfNeeded();
                if (res != START_SUCCESS) {
                    return res;
                }
                
                // 看这里,获取启动结果,看下面分析
                res = executeRequest(mRequest);
                
                Binder.restoreCallingIdentity(origId);

			   // ....
                // 返回启动结果
                return getExternalResult(res);
}

如果没有意外情况(意外情况具体是什么不知道),则走到res = executeRequest(mRequest);:

private int executeRequest(Request request) {
    // 正常的启动流程会从 startActivityUnchecked() -> startActivityInner()
    
    // 省略超长判断逻辑》。。。
    
    //  信息整合到ActivityRecord类中
    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();

    mLastStartActivityRecord = r;
    
    // 将创建的Activity代表类ActivityRecord对象作为参数传给 startActivityUnchecked()方法
    // 记住这个 doResume参数为true哦!!!
    mLastStartActivityResult = startActivityUnchecked(r, sourceRecord, voiceSession,
                request.voiceInteractor, startFlags, true /* doResume */, checkedOptions,
                inTask, inTaskFragment, restrictedBgActivity, intentGrants);
}

2.6 ActivityStarter#startActivityUnchecked()

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) {
        int result = START_CANCELED;
        final Task startedActivityRootTask;

        final TransitionController transitionController = r.mTransitionController;
        Transition newTransition = (!transitionController.isCollecting()
                && transitionController.getTransitionPlayer() != null)
                ? transitionController.createTransition(TRANSIT_OPEN) : null;
        RemoteTransition remoteTransition = r.takeRemoteTransition();
        if (newTransition != null && remoteTransition != null) {
            newTransition.setRemoteTransition(remoteTransition);
        }
        transitionController.collect(r);
        try {
            mService.deferWindowLayout();
            Trace.traceBegin(Trace.TRACE_TAG_WINDOW_MANAGER, "startActivityInner");
            
            // 获取启动结果,调度了startActivityInner(), doResume==true
            result = startActivityInner(r, sourceRecord, voiceSession, voiceInteractor,
                    startFlags, doResume, options, inTask, inTaskFragment, restrictedBgActivity,
                    intentGrants);
        } finally {
            Trace.traceEnd(Trace.TRACE_TAG_WINDOW_MANAGER);
            startedActivityRootTask = handleStartResult(r, options, result, newTransition,
                    remoteTransition);
            mService.continueWindowLayout();
        }
        postStartActivityProcessing(r, result, startedActivityRootTask);

        return result;
    }

2.7 ActivityStarter#startActivityInner()

private Task mTargetRootTask;

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) {
    
    	// 赋值mDoResume, doResume==true
    	setInitialState(r, options, inTask, inTaskFragment, doResume, startFlags, sourceRecord,
                voiceSession, voiceInteractor, restrictedBgActivity);

		// ....
    
    	
    	// 调用 Task#startActivityLocked()----> WMS 准备启动Surface,具体怎么启动不知道
    	mTargetRootTask.startActivityLocked(mStartActivity, topRootTask, newTask, isTaskSwitch,
                mOptions, sourceRecord);

}

2.8 Task#startActivityLocked()Task是继承自TaskFragment

class Task extends TaskFragment {
    
    void startActivityLocked(ActivityRecord r, @Nullable Task topTask, boolean newTask,
                             boolean isTaskSwitch, ActivityOptions options, @Nullable ActivityRecord sourceRecord) {
         // .... 准备切换动画
        
         // WMS 准备 Surface
        
    }
}

好像走到这里,方法调用断掉了,我们回到这个startActivityLocked()调用处:

private Task mTargetRootTask;

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) {
    	// 1 
    	setInitialState(r, options, inTask, inTaskFragment, doResume, startFlags, sourceRecord,
                voiceSession, voiceInteractor, restrictedBgActivity);

		// ....
    
    	
    	// 调用 Task#startActivityLocked()----> 准备启动SplashScreen(),通知SysUi搞一个SplashScreen window
    	// 当然要满足条件, 具体要看官网对SplashScreen用法的介绍
    	// mWmService.mStartingSurfaceController.showStartingWindow(r, prev, newTask,
		//	                        isTaskSwitch, sourceRecord);
		// 不过S代码中并未找到这个方法,有这个方法StartingSurfaceController.createSplashScreenStartingSurface(...)
    	mTargetRootTask.startActivityLocked(mStartActivity, topRootTask, newTask, isTaskSwitch,
                mOptions, sourceRecord);
    
    	 // mDoResume满足逻辑块
    	if (mDoResume) {
            // ....
        }

}

嗯,还有个比较长的mDoResume逻辑块,还记得在上面的方法让你记住传入了一个doResume==true的参数吗?请看2.5

private int executeRequest(Request request) {
    // 正常的启动流程会从 startActivityUnchecked() -> startActivityInner()
    
    // 省略超长判断逻辑》。。。
    
    // 将创建的Activity代表类ActivityRecord对象作为参数传给 startActivityUnchecked()方法
    // 记住这个 doResume参数为true哦!!!
    mLastStartActivityResult = startActivityUnchecked(r, sourceRecord, voiceSession,
                request.voiceInteractor, startFlags, true /* doResume */, checkedOptions,
                inTask, inTaskFragment, restrictedBgActivity, intentGrants);
}

这俩个参数一看就必然有联系!既然是mDoResume,是个成员变量,我们查看一下它的赋值处:
在这里插入图片描述

很显然,只有set()setInitialState()这俩个方法中,mDoResume才可能为true

追溯到2.7startActivityInner()方法的第一句:

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) {
    	// 赋值mDoResume
    	setInitialState(r, options, inTask, inTaskFragment, doResume, startFlags, sourceRecord,
                voiceSession, voiceInteractor, restrictedBgActivity);
}

private void setInitialState(...) {
    reset()
    // ... 
    // 传进来的doResume是TRUE
    mDoResume = doResume;
    // 下面是判断是否是延迟resume和安全模式下的启动,均会重新设置mDoResume为false,不考虑
}

OKK,现在知道会走mDoResume逻辑块了,来看看吧!

if (mDoResume) {
            final ActivityRecord topTaskActivity = startedTask.topRunningActivityLocked();
    		
    		// 看起来就不会走的样子
            if (!mTargetRootTask.isTopActivityFocusable()
                    || (topTaskActivity != null && topTaskActivity.isTaskOverlay()
                    && mStartActivity != topTaskActivity)) {
                // If the activity is not focusable, we can't resume it, but still would like to
                // make sure it becomes visible as it starts (this will also trigger entry
                // animation). An example of this are PIP activities.
                // Also, we don't want to resume activities in a task that currently has an overlay
                // as the starting activity just needs to be in the visible paused state until the
                // over is removed.
                // Passing {@code null} as the start parameter ensures all activities are made
                // visible.
                mTargetRootTask.ensureActivitiesVisible(null /* starting */,
                        0 /* configChanges */, !PRESERVE_WINDOWS);
                // Go ahead and tell window manager to execute app transition for this activity
                // since the app transition will not be triggered through the resume channel.
                mTargetRootTask.mDisplayContent.executeAppTransition();
            } else {
                // If the target root-task was not previously focusable (previous top running
                // activity on that root-task was not visible) then any prior calls to move the
                // root-task to the will not update the focused root-task.  If starting the new
                // activity now allows the task root-task to be focusable, then ensure that we
                // now update the focused root-task accordingly.
                if (mTargetRootTask.isTopActivityFocusable()
                        && !mRootWindowContainer.isTopDisplayFocusedRootTask(mTargetRootTask)) {
                    mTargetRootTask.moveToFront("startActivityInner");
                }
                
                // 看这里
                mRootWindowContainer.resumeFocusedTasksTopActivities(
                        mTargetRootTask, mStartActivity, mOptions, mTransientLaunch);
            }
        }

跟进mRootWindowContainer.resumeFocusedTasksTopActivities()!

2.9 RootWindwContainer#resumeFocusedTasksTopActivities()

class RootWindowContainer extends WindowContainer<DisplayContent> implements DisplayManager.DisplayListener {
    
    // 最后都走到参数最多的resumeFocusedTasksTopActivities
   	boolean resumeFocusedTasksTopActivities(Task targetRootTask, ActivityRecord target, ActivityOptions targetOptions,
            boolean deferPause) {
        
        if (!mTaskSupervisor.readyToResume()) {
            return false;
        }

        boolean result = false;
        if (targetRootTask != null && (targetRootTask.isTopRootTaskInDisplayArea()
                || getTopDisplayFocusedRootTask() == targetRootTask)) {
            result = targetRootTask.resumeTopActivityUncheckedLocked(target, targetOptions,
                    deferPause);
        }

        for (int displayNdx = getChildCount() - 1; displayNdx >= 0; --displayNdx) {
            final DisplayContent display = getChildAt(displayNdx);
            final boolean curResult = result;
            boolean[] resumedOnDisplay = new boolean[1];
            display.forAllRootTasks(rootTask -> {
                final ActivityRecord topRunningActivity = rootTask.topRunningActivity();
                if (!rootTask.isFocusableAndVisible() || topRunningActivity == null) {
                    return;
                }
                if (rootTask == targetRootTask) {
                    // Simply update the result for targetRootTask because the targetRootTask
                    // had already resumed in above. We don't want to resume it again,
                    // especially in some cases, it would cause a second launch failure
                    // if app process was dead.
                    resumedOnDisplay[0] |= curResult;
                    return;
                }
                if (rootTask.getDisplayArea().isTopRootTask(rootTask)
                        && topRunningActivity.isState(RESUMED)) {
                    // Kick off any lingering app transitions form the MoveTaskToFront
                    // operation, but only consider the top task and root-task on that
                    // display.
                    rootTask.executeAppTransition(targetOptions);
                } else {
                    resumedOnDisplay[0] |= topRunningActivity.makeActiveIfNeeded(target);
                }
            });
            result |= resumedOnDisplay[0];
            if (!resumedOnDisplay[0]) {
                // In cases when there are no valid activities (e.g. device just booted or launcher
                // crashed) it's possible that nothing was resumed on a display. Requesting resume
                // of top activity in focused root task explicitly will make sure that at least home
                // activity is started and resumed, and no recursion occurs.
                final Task focusedRoot = display.getFocusedRootTask();
                // 调用对应的Task resume activity
                if (focusedRoot != null) {
                    result |= focusedRoot.resumeTopActivityUncheckedLocked(target, targetOptions);
                } else if (targetRootTask == null) {
                    result |= resumeHomeActivity(null /* prev */, "no-focusable-task",
                            display.getDefaultTaskDisplayArea());
                }
            }
        }

        return result;
    }
    
}

2.10 Task#resumeTopActivityUncheckedLocked(ActivityRecord prev, ActivityOptions options)

到这里,方法参数已经少到只有俩个啦!!!!

/** @see #resumeTopActivityUncheckedLocked(ActivityRecord, ActivityOptions, boolean) */
    @GuardedBy("mService")
    boolean resumeTopActivityUncheckedLocked(ActivityRecord prev, ActivityOptions options) {
        return resumeTopActivityUncheckedLocked(prev, options, false /* skipPause */);
    }

调用的是三个参数的,而且最后一个参数为false

@GuardedBy("mService")
 boolean resumeTopActivityUncheckedLocked(ActivityRecord prev, ActivityOptions options,boolean deferPause) {
 
     	// ...
     
     	// 开启resume递归,直到满足是叶子activity
     	if (mInResumeTopActivity) {
            // Don't even start recursing.
            return false;
        }

        boolean someActivityResumed = false;
        try {
            // Protect against recursion.
            mInResumeTopActivity = true;

            // 递归满足叶子节点执行
            if (isLeafTask()) {
                if (isFocusableAndVisible()) {
                    // 走到这里
                    someActivityResumed = resumeTopActivityInnerLocked(prev, options, deferPause);
                }
            } else {
                int idx = mChildren.size() - 1;
                while (idx >= 0) {
                    final Task child = (Task) getChildAt(idx--);
                    if (!child.isTopActivityFocusable()) {
                        continue;
                    }
                    if (child.getVisibility(null /* starting */)
                            != TASK_FRAGMENT_VISIBILITY_VISIBLE) {
                        break;
                    }

                    // 递归直到满足isLeafTask()
                    someActivityResumed |= child.resumeTopActivityUncheckedLocked(prev, options,
                            deferPause);
                    // Doing so in order to prevent IndexOOB since hierarchy might changes while
                    // resuming activities, for example dismissing split-screen while starting
                    // non-resizeable activity.
                    if (idx >= mChildren.size()) {
                        idx = mChildren.size() - 1;
                    }
                }
            }

            // When resuming the top activity, it may be necessary to pause the top activity (for
            // example, returning to the lock screen. We suppress the normal pause logic in
            // {@link #resumeTopActivityUncheckedLocked}, since the top activity is resumed at the
            // end. We call the {@link ActivityTaskSupervisor#checkReadyForSleepLocked} again here
            // to ensure any necessary pause logic occurs. In the case where the Activity will be
            // shown regardless of the lock screen, the call to
            // {@link ActivityTaskSupervisor#checkReadyForSleepLocked} is skipped.
            final ActivityRecord next = topRunningActivity(true /* focusableOnly */);
            if (next == null || !next.canTurnScreenOn()) {
                checkReadyForSleep();
            }
        } finally {
            mInResumeTopActivity = false;
        }

        return someActivityResumed;
 		
 }

这个方法里面会开启一个递归,Task不断的调用resumeTopActivityUncheckedLocked()直到满足isLeadTask(),然后走到resumeTopActivityInnerLocked()方法!~

2.11 Task#resumeTopActivityInnerLocked()

    @GuardedBy("mService")
    private boolean resumeTopActivityInnerLocked(ActivityRecord prev, ActivityOptions options,
                                                 boolean deferPause) {
        // 还在reboot界面?直接跳过
        if (!mAtmService.isBooting() && !mAtmService.isBooted()) {
            // Not ready yet!
            return false;
        }

        final ActivityRecord topActivity = topRunningActivity(true /* focusableOnly */);
        if (topActivity == null) {
            // There are no activities left in this task, let's look somewhere else.
            return resumeNextFocusableActivityWhenRootTaskIsEmpty(prev, options);
        }

        final boolean[] resumed = new boolean[1];
        final TaskFragment topFragment = topActivity.getTaskFragment();
        // 1.先执行一次resumeTopActivity
        resumed[0] = topFragment.resumeTopActivity(prev, options, deferPause);
        // 2.递归执行resumeTopActivity找到要启动的那个Activity
        forAllLeafTaskFragments(f -> {
            if (topFragment == f) {
                return;
            }
            if (!f.canBeResumed(null /* starting */)) {
                return;
            }
            resumed[0] |= f.resumeTopActivity(prev, options, deferPause);
        }, true);
        return resumed[0];
    }

2.12 *TaskFragment#resumeTopActivity()

final boolean resumeTopActivity(ActivityRecord prev, ActivityOptions options,
                                boolean deferPause) {
    ActivityRecord next = topRunningActivity(true /* focusableOnly */);
    
    // 看具体代码像是执行一些APP之间的过渡逻辑....
    
   	boolean pausing = !deferPause && taskDisplayArea.pauseBackTasks(next);
    
    // 2.11中的递归,activity pause,走其他AC的生命周期
    if (pausing) {
            ProtoLog.v(WM_DEBUG_STATES, "resumeTopActivity: Skip resume: need to"
                    + " start pausing");
            // At this point we want to put the upcoming activity's process
            // at the top of the LRU list, since we know we will be needing it
            // very soon and it would be a waste to let it get killed if it
            // happens to be sitting towards the end.
            if (next.attachedToProcess()) {
                next.app.updateProcessInfo(false /* updateServiceConnectionActivities */,
                        true /* activityChange */, false /* updateOomAdj */,
                        false /* addPendingTopUid */);
            } 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();
                mAtmService.startProcessAsync(next, false /* knownToBeDead */, isTop,
                        isTop ? HostingRecord.HOSTING_TYPE_NEXT_TOP_ACTIVITY
                                : HostingRecord.HOSTING_TYPE_NEXT_ACTIVITY);
            }
            if (lastResumed != null) {
                lastResumed.setWillCloseOrEnterPip(true);
            }
            return true;
        } else if (mResumedActivity == next && next.isState(RESUMED)
                && taskDisplayArea.allResumedActivitiesComplete()) {
            // It is possible for the activity to be resumed when we paused back stacks above if the
            // next activity doesn't have to wait for pause to complete.
            // So, nothing else to-do except:
            // Make sure we have executed any pending transitions, since there
            // should be nothing left to do at this point.
            executeAppTransition(options);
            ProtoLog.d(WM_DEBUG_STATES, "resumeTopActivity: Top activity resumed "
                    + "(dontWaitForPause) %s", next);
            return true;
        }
    
    // 做过渡动画.....
    
    // 判断next所在进程是否启动,由于next是新的app,所以进程没有创建,走else分支
    if (next.attachedToProcess()) {
        // .....
    } else {
        
    }
    
}

next(ActivityRecord)是我们的要启动的目标时,先判断next所在进程是否创建了!好像能和ActivityThread有点关系了!

// 判断next所在进程是否启动,由于next是新的app,所以进程没有创建,走else分支
    if (next.attachedToProcess()) {
        // .....
    } else {
      	// Whoops, need to restart this activity!
            if (!next.hasBeenLaunched) {
                next.hasBeenLaunched = true;
            } else {
                if (SHOW_APP_STARTING_PREVIEW) {
                    next.showStartingWindow(false /* taskSwich */);
                }
                if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, "Restarting: " + next);
            }
            ProtoLog.d(WM_DEBUG_STATES, "resumeTopActivity: Restarting %s", next);
            // 调用ActivityTaskSupervisor#startSpecificActivity(),通知AMS去启动一个新的进程
            mTaskSupervisor.startSpecificActivity(next, true, true);  
    }

	return ture;

2.13. ActivityTaskSupervisor#startSpecificActivity()

    void startSpecificActivity(ActivityRecord r, boolean andResume, boolean checkConfig) {
        // Is this activity's application already running?
        final WindowProcessController wpc =
                mService.getProcessController(r.processName, r.info.applicationInfo.uid);

        boolean knownToBeDead = false;
        if (wpc != null && wpc.hasThread()) {
            try {
                // 1.如果所在进程启动了,则正常走这里
                realStartActivityLocked(r, wpc, andResume, checkConfig);
                return;
            } catch (RemoteException e) {
                Slog.w(TAG, "Exception when starting activity "
                        + r.intent.getComponent().flattenToShortString(), e);
            }

            // If a dead object exception was thrown -- fall through to
            // restart the application.
            knownToBeDead = true;
            // Remove the process record so it won't be considered as alive.
            mService.mProcessNames.remove(wpc.mName, wpc.mUid);
            mService.mProcessMap.remove(wpc.getPid());
        }

        r.notifyUnknownVisibilityLaunchedForKeyguardTransition();

        final boolean isTop = andResume && r.isTopRunningActivity();
        // ATMS启动进程
        mService.startProcessAsync(r, knownToBeDead, isTop,
                isTop ? HostingRecord.HOSTING_TYPE_TOP_ACTIVITY
                        : HostingRecord.HOSTING_TYPE_ACTIVITY);
    }

还记得之前的递归吗?

// 1.先执行一次resumeTopActivity

		// 现在看 待启动的Activity所在进程搞好了,ActivityThread.mian()也执行了
        resumed[0] = topFragment.resumeTopActivity(prev, options, deferPause);
        // 2.递归执行resumeTopActivity找到要启动的那个Activity
        forAllLeafTaskFragments(f -> {
            if (topFragment == f) {
                return;
            }
            if (!f.canBeResumed(null /* starting */)) {
                return;
            }
            // 再次执行TaskFragment#resumeTopActivity()
            resumed[0] |= f.resumeTopActivity(prev, options, deferPause);
        }, true);
        return resumed[0];

当再次执行TaskFragment#resumeTopActivity()时,在上面分析了,会走到ActivityTaskSupervisor#startSpecificActivity()方法,里面判断了进程是否创建了,然后走正常的启动(看2.14):

f (wpc != null && wpc.hasThread()) {
            try {
                // 1.如果所在进程启动了,则正常走这里
                realStartActivityLocked(r, wpc, andResume, checkConfig);
                return;
            } catch (RemoteException e) {
                Slog.w(TAG, "Exception when starting activity "
                        + r.intent.getComponent().flattenToShortString(), e);
            }

            // If a dead object exception was thrown -- fall through to
            // restart the application.
            knownToBeDead = true;
            // Remove the process record so it won't be considered as alive.
            mService.mProcessNames.remove(wpc.mName, wpc.mUid);
            mService.mProcessMap.remove(wpc.getPid());
        }

2.13.1 ATMS#startProcessAsync()

创建进程,执行android.app.ActivityThread:[终于能看到这个类了,淦!]

1、ATMS#startProcessAsync()
// 1
void startProcessAsync(ActivityRecord activity, boolean knownToBeDead, boolean isTop,
                           String hostingType) {
        try {
            if (Trace.isTagEnabled(TRACE_TAG_WINDOW_MANAGER)) {
                Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "dispatchingStartProcess:"
                        + activity.processName);
            }
            // Post message to start process to avoid possible deadlock of calling into AMS with the
            // ATMS lock held.
            
            // 执行ActivityManagerInternal::startProcess,ActivityManagerInternal实现类为 AMS.LocalService
            final Message m = PooledLambda.obtainMessage(ActivityManagerInternal::startProcess,
                    mAmInternal, activity.processName, activity.info.applicationInfo, knownToBeDead,
                    isTop, hostingType, activity.intent.getComponent());
            mH.sendMessage(m);
        } finally {
            Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
        }
    }

2、AMS.LocalService#startProcess() ------> AMS#startProcessLocked
// 1
@GuardedBy("this")
    final ProcessRecord startProcessLocked(String processName,
                                           ApplicationInfo info, boolean knownToBeDead, int intentFlags,
                                           HostingRecord hostingRecord, int zygotePolicyFlags, boolean allowWhileBooting,
                                           boolean isolated) {
        return mProcessList.startProcessLocked(processName, info, knownToBeDead, intentFlags,
                hostingRecord, zygotePolicyFlags, allowWhileBooting, isolated, 0 /* isolatedUid */,
                false /* isSdkSandbox */, 0 /* sdkSandboxClientAppUid */,
                null /* sdkSandboxClientAppPackage */,
                null /* ABI override */, null /* entryPoint */,
                null /* entryPointArgs */, null /* crashHandler */);
    }


// 2. ProcessList#startProcessLocked(),第一个参数是processName, String类型的
ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
                                     boolean knownToBeDead, int intentFlags, HostingRecord hostingRecord,
                                     int zygotePolicyFlags, boolean allowWhileBooting, boolean isolated, int isolatedUid,
                                     boolean isSdkSandbox, int sdkSandboxUid, String sdkSandboxClientAppPackage,
                                 String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {
    
  		// 做配置...crash处理什么的
    
    	// 创建进程
    	final boolean success = startProcessLocked(app, hostingRecord, zygotePolicyFlags, abiOverride);
        
        return success ? app : null;
}

// 3. startProcessLocked()
ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
                                     boolean knownToBeDead, int intentFlags, HostingRecord hostingRecord,
                                     int zygotePolicyFlags, boolean allowWhileBooting, boolean isolated, int isolatedUid,
                                     boolean isSdkSandbox, int sdkSandboxUid, String sdkSandboxClientAppPackage,
                                 String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {
    
    // 配置.....(看不懂啦)
    
    // 可以看到很多这种日志
    checkSlow(startTime, "startProcess: creating new process record");
    
    // 超长配置....
    
    // !!!!!!
    // Start the process.  It will either succeed and return a result containing
    // the PID of the new process, or else throw a RuntimeException.
    
     // 入口函数
     final String entryPoint = "android.app.ActivityThread";

     // 调用系统ZGI创建并执行了android.app.ActivityThread#main()方法
     return startProcessLocked(hostingRecord, entryPoint, app, uid, gids,
                    runtimeFlags, zygotePolicyFlags, mountExternal, seInfo, requiredAbi,
                    instructionSet, invokeWith, startUptime, startElapsedTime);
}

终于能看到,应用进程创建好之后执行了应用入口函数ActivityThread#main()!

2.14 ActivityTaskSupervisor#realStartActivityLocked():创建启动事务LauncherActivityItemActivityThread


boolean realStartActivityLocked(ActivityRecord r, WindowProcessController proc,
                                boolean andResume, boolean checkConfig) throws RemoteException {
    
    
   		// ....
    	
    	
    	// Create activity launch transaction.
                final ClientTransaction clientTransaction = ClientTransaction.obtain(
                        proc.getThread(), r.token);

                final boolean isTransitionForward = r.isTransitionForward();
                final IBinder fragmentToken = r.getTaskFragment().getFragmentToken();

                // 创建启动activity事务到待处理列表中[LaunchActivityItem]
                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.shareableActivityToken, r.getLaunchedFromBubble(), fragmentToken));

                // Set desired final state.
                final ActivityLifecycleItem lifecycleItem;
                if (andResume) {
                    // 设置resume-item
                    lifecycleItem = ResumeActivityItem.obtain(isTransitionForward);
                } else {
                    // 设置pause-item
                    lifecycleItem = PauseActivityItem.obtain();
                }
    
    			// 设置lifecycle请求,也就是onCreate之后是onResume
                clientTransaction.setLifecycleStateRequest(lifecycleItem);

                // Schedule transaction.
                // 开始处理事务!~!!!!!!
    			// mService是ActivityTaskManagerService,获取到的lm是ClientLifecycleManager对象
                mService.getLifecycleManager().scheduleTransaction(clientTransaction);
    	
    
    	// 启动失败处理...
}

2.14.1 ClientLifecycleManager#sheduleTransaction()
    /**
     * Schedule a transaction, which may consist of multiple callbacks and a lifecycle request.
     * @param transaction A sequence of client transaction items.
     * @throws RemoteException
     *
     * @see ClientTransaction
     */
    void scheduleTransaction(ClientTransaction transaction) throws RemoteException {
        // 设置 mClient, mClient是通过WindowProcessController获取到的IApplicationThread.aidl实现类-ApplicationThread(ActivityThread的内部类)
        final IApplicationThread client = transaction.getClient();
        // 也就是调用ApplicationThread#schedule(),阅读到这里,最好是看下ActivityThread.main()方法干了什么
        transaction.schedule();
        if (!(client instanceof Binder)) {
            // If client is not an instance of Binder - it's a remote call and at this point it is
            // safe to recycle the object. All objects used for local calls will be recycled after
            // the transaction is executed on client in ActivityThread.
            transaction.recycle();
        }
    }

三、热身完毕,开始干活!(分发事务ClientTransaction-ActivityThread

中我们知道了,进程创建之后执行了ActivityTread#main()方法,然后向ApplicationThread发送了LauncherActivityItemClientTransactionItem 回调,还发送了一个ResumeActivityItemActivityLifecycleItem回调,接着调用IApplicationThread.aidl实现类ApplicationThread#scheduleTransaction()来处理刚刚发送的事务回调,实现了应用进程和系统进程的交互。

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

时序图总结:

在这里插入图片描述

未完待续…

请看我的另一篇文章:链接: 浅析ActivityThread#main()方法和生命周期事务处理(代码基于Android-12)

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值