Activity启动过程详解(Android 12源码分析)
Activity的启动方式
启动一个Activity,通常有两种情况,一种是在应用内部启动Activity,另一种是Launcher启动
1、应用内启动
通过startActivity来启动Activity
启动流程:
一、Activity启动的发起
二、Activity的管理——ATMS
三、线程切换即消息处理——mH
四、Activity启动核心实现——初始化及生命周期
2、Launcher进程启动
Launcher就是我们桌面程序,当系统开机后,Launcher也随之被启动,然后将已经安装的app显示在桌面上,等到点击某个app的时候就会fork一个新的进程,然后启动Activity
启动流程:
一、Activity启动的发起
二、Activity的管理——ATMS
三、应用进程的创建
四、根Activity 的启动
启动Activity的流程大致分为下面5个阶段 一、A进程start ActivityB 二、解析ActivityB启动参数 三、由Task管理和启动Activity 四、把AMS里面对应的application和Activity生命周期的事务在ActivityStackSupervisor里面将事务封装到ClientTransaction 五、在B进程中解析ClientTransaction的命令执行Activity的生命周期
startActivity启动流程所涉及的类:
frameworks\base\core\java\android\content/Context.java frameworks\base\core\java\android\content/ContextWrapper.java frameworks\base\core\java\android\app/ContextImpl.java frameworks\base\core\java\android\app/Instrumentation.java frameworks\base\services\core\java\com\android\server\wm/ActivityTaskManagerService.java frameworks\base\services\core\java\com\android\server\wm/ActivityStarter.java E:\AOSP_12\frameworks\base\services\core\java\com\android\server\wm/RootWindowContainer.java E:\AOSP_12\frameworks\base\services\core\java\com\android\server\wm/Task.java E:\AOSP_12\frameworks\base\services\core\java\com\android\server\wm/TaskFragment.java E:\AOSP_12\frameworks\base\services\core\java\com\android\server\wm/ActivityTaskSupervisor.java E:\AOSP_12\frameworks\base\core\java\android\app\servertransaction/ClientTransaction.java E:\AOSP_12\frameworks\base\services\core\java\com\android\server\wm/ActivityTaskManagerService.java E:\AOSP_12\frameworks\base\services\core\java\com\android\server\wm/ClientLifecycleManager.java E:\AOSP_12\frameworks\base\core\java\android\app/IApplicationThread.aidl E:\AOSP_12\frameworks\base\core\java\android\app/ActivityThread.java E:\AOSP_12\frameworks\base\core\java\android\app/ClientTransactionHandler.java E:\AOSP_12\frameworks\base\core\java\android\app\servertransaction/TransactionExecutor.java E:\AOSP_12\frameworks\base\core\java\android\app\servertransaction/ActivityLifecycleItem.java E:\AOSP_12\frameworks\base\core\java\android\app\servertransaction/LaunchActivityItem.java E:\AOSP_12\frameworks\base\core\java\android\app\servertransaction/ClientTransactionItem.java ClientTransactionItem的所有子类或者相关类均在 frameworks/base/core/java/android/app/servertransaction/目录下 E:\AOSP_12\frameworks\base\services\core\java\com\android\server\am/ActivityManagerService.java E:\AOSP_12\frameworks\base\services\core\java\com\android\server\am/ProcessList.java E:\AOSP_12\frameworks\base\core\java\android\os/Process.java E:\AOSP_12\frameworks\base\core\java\android\os/ZygoteProcess.java
一、Activity的启动的发起
启动Activity先从startActivity开始,点击startActivity进入ContextWrapper类中由于mBase对象是context,Context的实现类为ContextImpl,所以直接看ContextImpl类中的startActivity方法
@Override public void startActivity(Intent intent, Bundle options) { //判断uid是不是System_uid warnIfCallingFromSystemProcess(); // Calling start activity from outside an activity without FLAG_ACTIVITY_NEW_TASK is // generally not allowed, except if the caller specifies the task id the activity should // be launched in. A bug was existed between N and O-MR1 which allowed this to work. We // maintain this for backwards compatibility. final int targetSdkVersion = getApplicationInfo().targetSdkVersion; if ((intent.getFlags() & Intent.FLAG_ACTIVITY_NEW_TASK) == 0 && (targetSdkVersion = Build.VERSION_CODES.P) && (options == null || ActivityOptions.fromBundle(options).getLaunchTaskId() == -1)) { throw new AndroidRuntimeException( "Calling startActivity() from outside of an Activity " + " context requires the FLAG_ACTIVITY_NEW_TASK flag." + " Is this really what you want?"); } //mMainThread为ActivityThread,获取的getInstrumentation()为Instrumentation mMainThread.getInstrumentation().execStartActivity( getOuterContext(), mMainThread.getApplicationThread(), null, (Activity) null, intent, -1, options); }
看到里面调用了mMainThread.getInstrumentation().execStartActivity方法,其中mMainThread是ActivityThread,ActivityThread继承ClientTransactionHandler实现ActivityThreadInternal
是Activity运行的主进程,它管理应用程序进程中主线程中执行的调度和执行活动、广播以及活动管理请求的其他操作。而Instrumentation具有跟踪application及activity生命周期的功能,用于Android应用测试框架中代码检测。接着看mInstrumentation.execStartActivity方法:
@UnsupportedAppUsage public ActivityResult execStartActivity( Context who, IBinder contextThread, IBinder token, String target, Intent intent, int requestCode, Bundle options) { IApplicationThread whoThread = (IApplicationThread) contextThread; if (mActivityMonitors != null) { synchronized (mSync) { final int N = mActivityMonitors.size(); for (int i=0; i final ActivityMonitor am = mActivityMonitors.get(i); ActivityResult result = null; if (am.ignoreMatchingSpecificIntents()) { if (options == null) { options = ActivityOptions.makeBasic().toBundle(); } result = am.onStartActivity(who, intent, options); } if (result != null) { am.mHits++; return result; } else if (am.match(who, null, intent)) { am.mHits++; if (am.isBlocking()) { return requestCode = 0 ? am.getResult() : null; } break; } } } } try { intent.migrateExtraStreamToClipData(who); intent.prepareToLeaveProcess(who); // 这里获取了ATMS代理对象IActivityTaskManager,拿到ATMS代理对象就可以跨进程调用ATMS的startActivity int result = ActivityTaskManager.getService().startActivity(whoThread, who.getOpPackageName(), who.getAttributionTag(), intent, intent.resolveTypeIfNeeded(who.getContentResolver()), token, target, requestCode, 0, null, options); checkStartActivityResult(result, intent); } catch (RemoteException e) { throw new RuntimeException("Failure from system", e); } return null; }
可以看到Activity的启动又交给了ActivityTaskManager.getService()
public static IActivityTaskManager getService() { return IActivityTaskManagerSingleton.get(); } @UnsupportedAppUsage(trackingBug = 129726065) private static final Singleton IActivityTaskManagerSingleton = new Singleton() { @Override protected IActivityTaskManager create() { final IBinder b = ServiceManager.getService(Context.ACTIVITY_TASK_SERVICE); return IActivityTaskManager.Stub.asInterface(b); } };
这里是获取一个跨进程的服务,获取的服务是ActivityTaskManagerService(ATMS),它继承于IActivityTaskManager.stub,是一个Bindder对象,并且是通过单例提供服务的,ATMS是用于管理Activity及其容器(任务,堆栈、显示等)的系统服务,运行在系统服务进程(system_server)之中。
二 Activity的管理——ATMS
在ActivityTaskManagerService里面调用startActivity方法,如下:
@Override public final int startActivity(IApplicationThread caller, String callingPackage, String callingFeatureId, Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, int startFlags, ProfilerInfo profilerInfo, Bundle bOptions) { return startActivityAsUser(caller, callingPackage, callingFeatureId, intent, resolvedType, resultTo, resultWho, requestCode, startFlags, profilerInfo, bOptions, UserHandle.getCallingUserId()); } @Override public int startActivityAsUser(IApplicationThread caller, String callingPackage, String callingFeatureId, Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) { return startActivityAsUser(caller, callingPackage, callingFeatureId, intent, resolvedType, resultTo, resultWho, requestCode, startFlags, profilerInfo, bOptions, userId, true /*validateIncomingUser*/); } 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); enforceNotIsolatedCaller("startActivityAsUser"); userId = getActivityStartController().checkTargetUser(userId, validateIncomingUser, Binder.getCallingPid(), Binder.getCallingUid(), "startActivityAsUser"); // TODO: Switch to user app stacks here. //在此处切换到用户应用程序堆栈。 //getActivityStartController().obtainStarter()返回的是ActivityStarter对象 //采用工厂设计模式+享元设计+链式调用 return getActivityStartController().obtainStarter(intent, "startActivityAsUser") .setCaller(caller)//调用方的AppThread的IBinder .setCallingPackage(callingPackage)//调用方的包名 .setCallingFeatureId(callingFeatureId) .setResolvedType(resolvedType)//调用type .setResultTo(resultTo)//调用方的ActivityClientrecord的binder(实际上是AMS的ActivityRecord 对应在APP端的binder对象) .setResultWho(resultWho)//调用方的标识 .setRequestCode(requestCode)//需要返回的requestCode .setStartFlags(startFlags)//启动标志位 .setProfilerInfo(profilerInfo)//启动时带上的权限文件对象 .setActivityOptions(bOptions)//ActivityOptions的Activity的启动项,在一般的APP中此时是null .setUserId(userId)//是否是同步打开Activity 默认一般是rue .execute();//执行方法 }
我们可以看到startActivity最终调用到startActivityAsUser方法,在内部将所有点的参数都交给了ActivityStarter,该类包含了启动的所有逻辑,比如Intent的解析以及任务栈等。接着调用了obtainStarter,该方法通过工厂模式创建了ActivityStarter对象。如下:
@VisibleForTesting ActivityStartController(ActivityTaskManagerService service, ActivityTaskSupervisor supervisor, Factory factory) { mService = service; mSupervisor = supervisor; mFactory = factory; mFactory.setController(this); mPendingRemoteAnimationRegistry = new PendingRemoteAnimationRegistry(service.mGlobalLock, service.mH); } /** * @return A starter to configure and execute starting an activity. It is valid until after * {@link ActivityStarter#execute} is invoked. At that point, the starter should be * considered invalid and no longer modified or used. */ ActivityStarter obtainStarter(Intent intent, String reason) { return mFactory.obtain().setIntent(intent).setReason(reason); } void onExecutionComplete(ActivityStarter starter) { if (mLastStarter == null) { mLastStarter = mFactory.obtain(); } mLastStarter.set(starter); mFactory.recycle(starter); } static class DefaultFactory implements Factory { /** * The maximum count of starters that should be active at one time: * 1. last ran starter (for logging and post activity processing) * 2. current running starter * 3. starter from re-entry in (2) * */ private final int MAX_STARTER_COUNT = 3;//ActivitySatrter 最大数量 private ActivityStartController mController; private ActivityTaskManagerService mService; private ActivityTaskSupervisor mSupervisor; private ActivityStartInterceptor mInterceptor; //同步池 private SynchronizedPool mStarterPool = new SynchronizedPool(MAX_STARTER_COUNT); DefaultFactory(ActivityTaskManagerService service, ActivityTaskSupervisor supervisor, ActivityStartInterceptor interceptor) { mService = service; mSupervisor = supervisor; mInterceptor = interceptor; } @Override public void setController(ActivityStartController controller) { mController = controller; } @Override public ActivityStarter obtain() { //从同步池中获取ActivityStarter对象 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; } @Override public void recycle(ActivityStarter starter) { starter.reset(true /* clearRequest*/); mStarterPool.release(starter); } }
可以看到,默认的工厂在提供了一个容量为3的同步缓存池来缓存ActivityStarter对象,该对象创建完成之后,ActivityTaskManagerService就会将接下来启动Activity的操作交给ActivityStarter来完成
int execute() { try { // Refuse possible leaked file descriptors //拒绝可能泄露的文件描述符 if (mRequest.intent != null && mRequest.intent.hasFileDescriptors()) { throw new IllegalArgumentException("File descriptors passed in Intent"); } ..省略部分代码... res = executeRequest(mRequest);//开始执行请求 ..省略部分代码... return getExternalResult(res); } } finally { onExecutionComplete();//在ActivityStartController清除数据放回startPool池子中。 } } /** * Executing activity start request and starts the journey of starting an activity. Here * begins with performing several preliminary checks. The normally activity launch flow will * go through {@link #startActivityUnchecked} to {@link #startActivityInner}. 该方法会进行一些校验和判断权限,包括进程检查,intent检查,权限检查等。后面就会创建ActivityRecord,每个Activity都会对 应一个ActivityRecord对象,接着就会调用startActivityUnchecked方法对要启动的Activity做任务栈管理。 */ private int executeRequest(Request request) { ...省略部分代码... //创建出我们的目标ActivityRecord对象,存到传入数组0索引上 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,也就是当前activity mLastStartActivityResult = startActivityUnchecked(r, sourceRecord, voiceSession, request.voiceInteractor, startFlags, true /* doResume */, checkedOptions, inTask, inTaskFragment, restrictedBgActivity, intentGrants); ...省略部分代码.... return mLastStartActivityResult; }
在executeRequest方法中会进行一些校验和判断权限,包括进程检测,intent检查,权限检查等,后面会创建ActivityRecord,每个Activity都会对应一个ActivityRecord对象,接着就会调用startActivityUnChecked方法对要启动的Activity做任务栈管理。
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) { ...省略部分代码... //在大多数初步检查已经完成的情况下开始进行下一步确认拥有必要的权限。startActivityInner()用来检查启动所必须要有的权限。 result = startActivityInner(r, sourceRecord, voiceSession, voiceInteractor, startFlags, doResume, options, inTask, inTaskFragment, restrictedBgActivity, intentGrants); startResultSuccessful = ActivityManager.isStartResultSuccessful(result); final boolean taskAlwaysOnTop = options != null && options.getTaskAlwaysOnTop(); // Apply setAlwaysOnTop when starting an Activity is successful regardless of creating // a new Activity or recycling the existing Activity. if (taskAlwaysOnTop && startResultSuccessful) { final Task targetRootTask = mTargetRootTask != null ? mTargetRootTask : mTargetTask.getRootTask(); targetRootTask.setAlwaysOnTop(true); } } finally { ..省略部分代码... } } postStartActivityProcessing(r, result, startedActivityRootTask); return result; }
在大多数初步检查已经完成的情况下开始进行下一步确认拥有必要的权限。核心方法就是调用startActivityInner()用来检查启动所必须要有的权限
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) { //初始化设置,mStartActivity,mLaunchMode等 setInitialState(r, options, inTask, inTaskFragment, doResume, startFlags, sourceRecord, voiceSession, voiceInteractor, restrictedBgActivity); //计算启动Activity的Flag值,判断启动模式,并且在mLaunchFlags上追加对应标记 computeLaunchingTaskFlags(); //计算源Activity所在的栈 computeSourceRootTask(); //设置LaunchFlags到intent上,也就是设置启动模式 mIntent.setFlags(mLaunchFlags); // Get top task at beginning because the order may be changed when reusing existing task. final Task prevTopTask = mPreferredTaskDisplayArea.getFocusedRootTask(); //决定是否应将新Activity插入Task中。返回null,如果不是则应将新Activity添加到其中的task进行Activity记录。 //查找可用的任务栈 final Task reusedTask = getReusableTask(); // If requested, freeze the task list if (mOptions != null && mOptions.freezeRecentTasksReordering() && mSupervisor.mRecentTasks.isCallerRecents(r.launchedFromUid) && !mSupervisor.mRecentTasks.isFreezeTaskListReorderingSet()) { mFrozeTaskList = true; mSupervisor.mRecentTasks.setFreezeTaskListReordering(); } // Compute if there is an existing task that should be used for. //reusedTask为null则计算是否存在可以使用的任务栈 final Task targetTask = reusedTask != null ? reusedTask : computeTargetTask(); //是否需要创建栈 final boolean newTask = targetTask == null; mTargetTask = targetTask; computeLaunchParams(r, sourceRecord, targetTask); // Check if starting activity on given task or on a new task is allowed. //检查是否允许在给定的Task或者新的Task上启动Activity int startResult = isAllowedToStart(r, newTask, targetTask); if (startResult != START_SUCCESS) { return startResult; } final ActivityRecord targetTaskTop = newTask ? null : targetTask.getTopNonFinishingActivity(); if (targetTaskTop != null) { // Recycle the target task for this launch. startResult = recycleTask(targetTask, targetTaskTop, reusedTask, intentGrants); if (startResult != START_SUCCESS) { return startResult; } } else { mAddingToTask = true; } // If the activity being launched is the same as the one currently at the top, then // we need to check if it should only be launched once. //如果正在启动的Activity与当前位于栈顶的Activity相同 //则需要检查它是否应该只启动一次 final Task topRootTask = mPreferredTaskDisplayArea.getFocusedRootTask(); if (topRootTask != null) { startResult = deliverToCurrentTopIfNeeded(topRootTask, intentGrants); if (startResult != START_SUCCESS) { return startResult; } } //复用或者创建新栈 if (mTargetRootTask == null) { mTargetRootTask = getLaunchRootTask(mStartActivity, mLaunchFlags, targetTask, mOptions); } if (newTask) { //新建一个Task final Task taskToAffiliate = (mLaunchTaskBehind && mSourceRecord != null) ? mSourceRecord.getTask() : null; //将Activity放入新建的任务栈 setNewTask(taskToAffiliate); } else if (mAddingToTask) { //复用之前的Task addOrReparentStartingActivity(targetTask, "adding to task"); } if (!mAvoidMoveToFront && mDoResume) { mTargetRootTask.getRootTask().moveToFront("reuseOrNewTask", targetTask); if (!mTargetRootTask.isTopRootTaskInDisplayArea() && mService.mInternal.isDreaming()) { // Launching underneath dream activity (fullscreen, always-on-top). Run the launch- // -behind transition so the Activity gets created and starts in visible state. mLaunchTaskBehind = true; r.mLaunchTaskBehind = true; } } mService.mUgmInternal.grantUriPermissionUncheckedFromIntent(intentGrants, mStartActivity.getUriPermissionsLocked()); if (mStartActivity.resultTo != null && mStartActivity.resultTo.info != null) { // we need to resolve resultTo to a uid as grantImplicitAccess deals explicitly in UIDs final PackageManagerInternal pmInternal = mService.getPackageManagerInternalLocked(); final int resultToUid = pmInternal.getPackageUid( mStartActivity.resultTo.info.packageName, 0 /* flags */, mStartActivity.mUserId); pmInternal.grantImplicitAccess(mStartActivity.mUserId, mIntent, UserHandle.getAppId(mStartActivity.info.applicationInfo.uid) /*recipient*/, resultToUid /*visible*/, true /*direct*/); } final Task startedTask = mStartActivity.getTask(); if (newTask) { EventLogTags.writeWmCreateTask(mStartActivity.mUserId, startedTask.mTaskId); } mStartActivity.logStartActivity(EventLogTags.WM_CREATE_ACTIVITY, startedTask); mStartActivity.getTaskFragment().clearLastPausedActivity(); mRootWindowContainer.startPowerModeLaunchIfNeeded( false /* forceSend */, mStartActivity); final boolean isTaskSwitch = startedTask != prevTopTask && !startedTask.isEmbedded(); //创建启动黑白屏window mTargetRootTask.startActivityLocked(mStartActivity, topRootTask != null ? topRootTask.getTopNonFinishingActivity() : null, newTask, isTaskSwitch, mOptions, sourceRecord); 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"); } //启动栈中顶部的Activity mRootWindowContainer.resumeFocusedTasksTopActivities( mTargetRootTask, mStartActivity, mOptions, mTransientLaunch); } } mRootWindowContainer.updateUserRootTask(mStartActivity.mUserId, mTargetRootTask); // Update the recent tasks list immediately when the activity starts mSupervisor.mRecentTasks.add(startedTask); mSupervisor.handleNonResizableTaskIfNeeded(startedTask, mPreferredWindowingMode, mPreferredTaskDisplayArea, mTargetRootTask); return START_SUCCESS; }
在上面方法中,根据启动模式计算出flag,然后在根据flag等条件判断要启动的Activity的ActivityRecord是需要新创建Task栈还是加入到现有的Task栈中。在位Activity准备好Task栈之后,调用了mRootWindowContainer.resumeFocuredTasksTopActivities方法。
RootWindowContainer是窗口容器(WindowContainer)的根容器,管理所有的窗口容器,设备上所有的窗口(Window)显示器(Display)都是由它来管理的
下面看mRootWindowContainer.resumeFocursedTasksTopActivities方法的具体操作
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(); if (focusedRoot != null) { //如果焦点任务栈不为空则唤醒顶部的Activity result |= focusedRoot.resumeTopActivityUncheckedLocked(target, targetOptions); } else if (targetRootTask == null) { //否则唤醒首页Activity result |= resumeHomeActivity(null /* prev */, "no-focusable-task", display.getDefaultTaskDisplayArea()); } } } return result; }
mRootWindowContainer.resumeFocusedStacksToActivities()方法会恢复对应任务栈顶部的Activity,方法中会检查一些可见性相关的属性,后转交给Task调用resumeTopActivityUncheckedLocked方法来继续启动流程。
/* /* * 确保恢复根task中的顶部activity **/ @GuardedBy("mService") boolean resumeTopActivityUncheckedLocked(ActivityRecord prev, ActivityOptions options, boolean deferPause) { if (mInResumeTopActivity) { // Don't even start recursing. return false; } boolean someActivityResumed = false; try { // Protect against recursion. mInResumeTopActivity = true; if (isLeafTask()) { if (isFocusableAndVisible()) { //继续调用resumeTopActivityInnerLocked方法 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; } 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; } /** @see #resumeTopActivityUncheckedLocked(ActivityRecord, ActivityOptions, boolean) */ @GuardedBy("mService") boolean resumeTopActivityUncheckedLocked(ActivityRecord prev, ActivityOptions options) { return resumeTopActivityUncheckedLocked(prev, options, false /* skipPause */); } /** * Task用来描述一个Activity的任务栈 */ @GuardedBy("mService") private boolean resumeTopActivityInnerLocked(ActivityRecord prev, ActivityOptions options, boolean deferPause) { if (!mAtmService.isBooting() && !mAtmService.isBooted()) { // Not ready yet! return false; } //在当前Task栈中找到最上层正在运行的Activity //如果这个Activity没有获取焦点,那这个Activity将会被重新启动 //获取当前顶部正在运行的Activity final ActivityRecord topActivity = topRunningActivity(true /* focusableOnly */); if (topActivity == null) { // There are no activities left in this task, let's look somewhere else. //如果根任务栈为空则返回下一个焦点Activity return resumeNextFocusableActivityWhenRootTaskIsEmpty(prev, options); } final boolean[] resumed = new boolean[1]; //获取当前顶部正在运行的Activity的TaskFragment final TaskFragment topFragment = topActivity.getTaskFragment(); //唤醒 resumed[0] = topFragment.resumeTopActivity(prev, options, deferPause); forAllLeafTaskFragments(f -> { if (topFragment == f) { return; } if (!f.canBeResumed(null /* starting */)) { return; } //调用TaskFragment的一个关键方法resumeTopActivity来继续唤醒顶部Activity resumed[0] |= f.resumeTopActivity(prev, options, deferPause); }, true); return resumed[0]; }
跟踪代码执行到TaskFragment
final boolean resumeTopActivity(ActivityRecord prev, ActivityOptions options, boolean deferPause) { ActivityRecord next = topRunningActivity(true /* focusableOnly */); if (next == null || !next.canResumeByCompat()) { return false; } next.delayedResume = false; final TaskDisplayArea taskDisplayArea = getDisplayArea(); // If the top activity is the resumed one, nothing to do. if (mResumedActivity == next && next.isState(RESUMED) && taskDisplayArea.allResumedActivitiesComplete()) { // Make sure we have executed any pending transitions, since there // should be nothing left to do at this point. executeAppTransition(options); // For devices that are not in fullscreen mode (e.g. freeform windows), it's possible // we still want to check if the visibility of other windows have changed (e.g. bringing // a fullscreen window forward to cover another freeform activity.) if (taskDisplayArea.inMultiWindowMode()) { taskDisplayArea.ensureActivitiesVisible(null /* starting */, 0 /* configChanges */, false /* preserveWindows */, true /* notifyClients */); } ProtoLog.d(WM_DEBUG_STATES, "resumeTopActivity: Top activity " + "resumed %s", next); return false; } // If we are currently pausing an activity, then don't do anything until that is done. final boolean allPausedComplete = mRootWindowContainer.allPausedActivitiesComplete(); if (!allPausedComplete) { ProtoLog.v(WM_DEBUG_STATES, "resumeTopActivity: Skip resume: some activity pausing."); return false; } // If we are sleeping, and there is no resumed activity, and the top activity is paused, // well that is the state we want. if (mLastPausedActivity == next && shouldSleepOrShutDownActivities()) { // 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: Going to sleep and" + " all paused"); return false; } // Make sure that the user who owns this activity is started. If not, // we will just leave it as is because someone should be bringing // another user's activities to the top of the stack. if (!mAtmService.mAmInternal.hasStartedUserState(next.mUserId)) { Slog.w(TAG, "Skipping resume of top activity " + next + ": user " + next.mUserId + " is stopped"); return false; } // The activity may be waiting for stop, but that is no longer // appropriate for it. mTaskSupervisor.mStoppingActivities.remove(next); if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, "Resuming " + next); mTaskSupervisor.setLaunchSource(next.info.applicationInfo.uid); ActivityRecord lastResumed = null; final Task lastFocusedRootTask = taskDisplayArea.getLastFocusedRootTask(); if (lastFocusedRootTask != null && lastFocusedRootTask != getRootTaskFragment().asTask()) { // So, why aren't we using prev here??? See the param comment on the method. prev // doesn't represent the last resumed activity. However, the last focus stack does if // it isn't null. lastResumed = lastFocusedRootTask.getTopResumedActivity(); } boolean pausing = !deferPause && taskDisplayArea.pauseBackTasks(next); if (mResumedActivity != null) { ProtoLog.d(WM_DEBUG_STATES, "resumeTopActivity: Pausing %s", mResumedActivity); //暂停栈顶的Activity pausing |= startPausing(mTaskSupervisor.mUserLeaving, false /* uiSleeping */, next, "resumeTopActivity"); } 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. //要启动的Activity已存在,且不需要重新创建,例如设置singleTask或singleTop启动模式 //next就是要启动的这个ActivityRecord,它是一个全新的ActivityRecord,所以这个地方 //返回值为false if (next.attachedToProcess()) {//为false 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 ? "pre-top-activity" : "pre-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; } // If the most recent activity was noHistory but was only stopped rather // than stopped+finished because the device went to sleep, we need to make // sure to finish it as we're making a new activity topmost. if (shouldSleepActivities()) { mTaskSupervisor.finishNoHistoryActivitiesIfNeeded(next); } if (prev != null && prev != next && next.nowVisible) { // The next activity is already visible, so hide the previous // activity's windows right now so we can show the new one ASAP. // We only do this if the previous is finishing, which should mean // it is on top of the one being resumed so hiding it quickly // is good. Otherwise, we want to do the normal route of allowing // the resumed activity to be shown so we can decide if the // previous should actually be hidden depending on whether the // new one is found to be full-screen or not. if (prev.finishing) { prev.setVisibility(false); if (DEBUG_SWITCH) { Slog.v(TAG_SWITCH, "Not waiting for visible to hide: " + prev + ", nowVisible=" + next.nowVisible); } } else { if (DEBUG_SWITCH) { Slog.v(TAG_SWITCH, "Previous already visible but still waiting to hide: " + prev + ", nowVisible=" + next.nowVisible); } } } // Launching this app's activity, make sure the app is no longer // considered stopped. try { mTaskSupervisor.getActivityMetricsLogger() .notifyBeforePackageUnstopped(next.packageName); mAtmService.getPackageManager().setPackageStoppedState( next.packageName, false, next.mUserId); /* TODO: Verify if correct userid */ } catch (RemoteException e1) { } catch (IllegalArgumentException e) { Slog.w(TAG, "Failed trying to unstop package " + next.packageName + ": " + e); } // We are starting up the next activity, so tell the window manager // that the previous one will be hidden soon. This way it can know // to ignore it when computing the desired screen orientation. boolean anim = true; final DisplayContent dc = taskDisplayArea.mDisplayContent; if (prev != null) { if (prev.finishing) { if (DEBUG_TRANSITION) { Slog.v(TAG_TRANSITION, "Prepare close transition: prev=" + prev); } if (mTaskSupervisor.mNoAnimActivities.contains(prev)) { anim = false; dc.prepareAppTransition(TRANSIT_NONE); } else { dc.prepareAppTransition(TRANSIT_CLOSE); } prev.setVisibility(false); } else { if (DEBUG_TRANSITION) { Slog.v(TAG_TRANSITION, "Prepare open transition: prev=" + prev); } if (mTaskSupervisor.mNoAnimActivities.contains(next)) { anim = false; dc.prepareAppTransition(TRANSIT_NONE); } else { dc.prepareAppTransition(TRANSIT_OPEN, next.mLaunchTaskBehind ? TRANSIT_FLAG_OPEN_BEHIND : 0); } } } else { if (DEBUG_TRANSITION) Slog.v(TAG_TRANSITION, "Prepare open transition: no previous"); if (mTaskSupervisor.mNoAnimActivities.contains(next)) { anim = false; dc.prepareAppTransition(TRANSIT_NONE); } else { dc.prepareAppTransition(TRANSIT_OPEN); } } //activity动画 if (anim) { next.applyOptionsAnimation(); } else { next.abortAndClearOptionsAnimation(); } mTaskSupervisor.mNoAnimActivities.clear(); //进程存在 if (next.attachedToProcess()) {//为false if (DEBUG_SWITCH) { Slog.v(TAG_SWITCH, "Resume running: " + next + " stopped=" + next.stopped + " visibleRequested=" + next.mVisibleRequested); } // If the previous activity is translucent, force a visibility update of // the next activity, so that it's added to WM's opening app list, and // transition animation can be set up properly. // For example, pressing Home button with a translucent activity in focus. // Launcher is already visible in this case. If we don't add it to opening // apps, maybeUpdateTransitToWallpaper() will fail to identify this as a // TRANSIT_WALLPAPER_OPEN animation, and run some funny animation. final boolean lastActivityTranslucent = inMultiWindowMode() || mLastPausedActivity != null && !mLastPausedActivity.occludesParent(); // This activity is now becoming visible. if (!next.mVisibleRequested || next.stopped || lastActivityTranslucent) { next.setVisibility(true); } // schedule launch ticks to collect information about slow apps. next.startLaunchTickingLocked(); ActivityRecord lastResumedActivity = lastFocusedRootTask == null ? null : lastFocusedRootTask.getTopResumedActivity(); final ActivityRecord.State lastState = next.getState(); mAtmService.updateCpuStats(); ProtoLog.v(WM_DEBUG_STATES, "Moving to RESUMED: %s (in existing)", next); next.setState(RESUMED, "resumeTopActivity"); // Have the window manager re-evaluate the orientation of // the screen based on the new activity order. boolean notUpdated = true; // Activity should also be visible if set mLaunchTaskBehind to true (see // ActivityRecord#shouldBeVisibleIgnoringKeyguard()). if (shouldBeVisible(next)) { // We have special rotation behavior when here is some active activity that // requests specific orientation or Keyguard is locked. Make sure all activity // visibilities are set correctly as well as the transition is updated if needed // to get the correct rotation behavior. Otherwise the following call to update // the orientation may cause incorrect configurations delivered to client as a // result of invisible window resize. // TODO: Remove this once visibilities are set correctly immediately when // starting an activity. notUpdated = !mRootWindowContainer.ensureVisibilityAndConfig(next, getDisplayId(), true /* markFrozenIfConfigChanged */, false /* deferResume */); } if (notUpdated) { // The configuration update wasn't able to keep the existing // instance of the activity, and instead started a new one. // We should be all done, but let's just make sure our activity // is still at the top and schedule another run if something // weird happened. ActivityRecord nextNext = topRunningActivity(); ProtoLog.i(WM_DEBUG_STATES, "Activity config changed during resume: " + "%s, new next: %s", next, nextNext); if (nextNext != next) { // Do over! mTaskSupervisor.scheduleResumeTopActivities(); } if (!next.mVisibleRequested || next.stopped) { next.setVisibility(true); } //如果要启动的Activity进程存在,则会调用completeResumeLocked方法 next.completeResumeLocked(); return true; } try { //开启一个事务 final ClientTransaction transaction = ClientTransaction.obtain(next.app.getThread(), next.appToken); // Deliver all pending results. ArrayList a = next.results; if (a != null) { final int size = a.size(); if (!next.finishing && size > 0) { if (DEBUG_RESULTS) { Slog.v(TAG_RESULTS, "Delivering results to " + next + ": " + a); } transaction.addCallback(ActivityResultItem.obtain(a)); } } if (next.newIntents != null) { //添加onNewIntent的callback,最终会在APP端执行onNewIntent() transaction.addCallback( NewIntentItem.obtain(next.newIntents, true /* resume */)); } // Well the app will no longer be stopped. // Clear app token stopped state in window manager if needed. next.notifyAppResumed(next.stopped); EventLogTags.writeWmResumeActivity(next.mUserId, System.identityHashCode(next), next.getTask().mTaskId, next.shortComponentName); mAtmService.getAppWarningsLocked().onResumeActivity(next); next.app.setPendingUiCleanAndForceProcessStateUpTo(mAtmService.mTopProcessState); next.abortAndClearOptionsAnimation(); //设置Actiivity最终的生命周期状态为onResume transaction.setLifecycleStateRequest( ResumeActivityItem.obtain(next.app.getReportedProcState(), dc.isNextTransitionForward())); //开始执行事务 mAtmService.getLifecycleManager().scheduleTransaction(transaction); ProtoLog.d(WM_DEBUG_STATES, "resumeTopActivity: Resumed %s", next); } catch (Exception e) { // Whoops, need to restart this activity! ProtoLog.v(WM_DEBUG_STATES, "Resume failed; resetting state to %s: " + "%s", lastState, next); next.setState(lastState, "resumeTopActivityInnerLocked"); // lastResumedActivity being non-null implies there is a lastStack present. if (lastResumedActivity != null) { lastResumedActivity.setState(RESUMED, "resumeTopActivityInnerLocked"); } Slog.i(TAG, "Restarting because process died: " + next); if (!next.hasBeenLaunched) { next.hasBeenLaunched = true; } else if (SHOW_APP_STARTING_PREVIEW && lastFocusedRootTask != null && lastFocusedRootTask.isTopRootTaskInDisplayArea()) { next.showStartingWindow(false /* taskSwitch */); } //Activity的启动事务就是在realStartActivityLocked方法中启动 mTaskSupervisor.startSpecificActivity(next, true, false); return true; } // From this point on, if something goes wrong there is no way // to recover the activity. try { next.completeResumeLocked(); } catch (Exception e) { // If any exception gets thrown, toss away this // activity and try the next one. Slog.w(TAG, "Exception thrown during resume of " + next, e); next.finishIfPossible("resume-exception", true /* oomAdj */); return true; } } 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); //启动指定的Activity mTaskSupervisor.startSpecificActivity(next, true, true); } return true; }
resumeTopActivity方法中主要有两个部分内容。
1、next.attachedToProcess()为true,即要启动的这个Activity已经存在,并且设置了像"singleInstance"的启动模式,无需重新创建Activity的情况下,则先通过ClientTransaction添加了一个NewIntentItem的callback,接下来通过setLifecycleStateRequestt设置了一个ResumeActivityItem对象
2、next.attachedToProcess()为false,则继续执行Activity的启动流程。
在resumeTopActivity方法中因为启动的ActivityRecord是一个全新的Activity,所以在该方法中判断next.attachedToProcess()为false,所以会调用mTaskSupervisor.StartSpecificActivity()开启指定的activity ,代码如下:
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; //进程已经创建的话,直接启动activity if (wpc != null && wpc.hasThread()) { try { //Activity的启动事务就是在realStartActivityLoked方法中启动 //如果进程存在,启动Activity并返回 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; } r.notifyUnknownVisibilityLaunchedForKeyguardTransition(); final boolean isTop = andResume && r.isTopRunningActivity(); //如果进程不存在,为app启动一个进程 mService.startProcessAsync(r, knownToBeDead, isTop, isTop ? "top-activity" : "activity"); }
在该方法中ActivityStackSupervisor.startSpecificActivity()方法中获取WindowProcessController,通过wpc.hasThread()方法判断应用进程是否已创建并运行中,其内部是通过IApplicationThread是否已经被赋值来判断的,如果已被赋值则表示应用进程已创建且运行中,此时进入判断体内部,走ActivityStackSupervisor.realStartActivityLocked()方法继续Activity的启动流程,即普通Activity的启动流程。如果未被赋值,则需要创建。在这里我们先看进程已经创建并且执行realStartActivity()方法。
boolean realStartActivityLocked(ActivityRecord r, WindowProcessController proc, boolean andResume, boolean checkConfig) throws RemoteException { //传递过来的andResume =true 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; } final Task task = r.getTask(); final Task rootTask = task.getRootTask(); beginDeferResume(); // The LaunchActivityItem also contains process configuration, so the configuration change // from WindowProcessController#setProcess can be deferred. The major reason is that if // the activity has FixedRotationAdjustments, it needs to be applied with configuration. // In general, this reduces a binder transaction if process configuration is changed. proc.pauseConfigurationDispatch(); try { r.startFreezingScreenLocked(proc, 0); // schedule launch ticks to collect information about slow apps. r.startLaunchTickingLocked(); r.setProcess(proc); // Ensure activity is allowed to be resumed after process has set. if (andResume && !r.canResumeByCompat()) { andResume = false; } r.notifyUnknownVisibilityLaunchedForKeyguardTransition(); // Have the window manager re-evaluate the orientation of the screen based on the new // activity order. Note that as a result of this, it can call back into the activity // manager with a new orientation. We don't care about that, because the activity is // not currently running so we are just restarting it anyway. if (checkConfig) { // Deferring resume here because we're going to launch new activity shortly. // We don't want to perform a redundant launch of the same record while ensuring // configurations and trying to resume top activity of focused root task. mRootWindowContainer.ensureVisibilityAndConfig(r, r.getDisplayId(), false /* markFrozenIfConfigChanged */, true /* deferResume */); } if (mKeyguardController.checkKeyguardVisibility(r) && r.allowMoveToFront()) { // We only set the visibility to true if the activity is not being launched in // background, and is allowed to be visible based on keyguard state. This avoids // setting this into motion in window manager that is later cancelled due to later // calls to ensure visible activities that set visibility back to false. r.setVisibility(true); } final int applicationInfoUid = (r.info.applicationInfo != null) ? r.info.applicationInfo.uid : -1; if ((r.mUserId != proc.mUserId) || (r.info.applicationInfo.uid != applicationInfoUid)) { Slog.wtf(TAG, "User ID for activity changing for " + r + " appInfo.uid=" + r.info.applicationInfo.uid + " info.ai.uid=" + applicationInfoUid + " old=" + r.app + " new=" + proc); } // Send the controller to client if the process is the first time to launch activity. // So the client can save binder transactions of getting the controller from activity // task manager service. final IActivityClientController activityClientController = proc.hasEverLaunchedActivity() ? null : mService.mActivityClientController; r.launchCount++; r.lastLaunchTime = SystemClock.uptimeMillis(); proc.setLastActivityLaunchTime(r.lastLaunchTime); if (DEBUG_ALL) Slog.v(TAG, "Launching: " + r); final LockTaskController lockTaskController = mService.getLockTaskController(); if (task.mLockTaskAuth == LOCK_TASK_AUTH_LAUNCHABLE || task.mLockTaskAuth == LOCK_TASK_AUTH_LAUNCHABLE_PRIV || (task.mLockTaskAuth == LOCK_TASK_AUTH_ALLOWLISTED && lockTaskController.getLockTaskModeState() == LOCK_TASK_MODE_LOCKED)) { lockTaskController.startLockTaskMode(task, false, 0 /* blank UID */); } try { if (!proc.hasThread()) { throw new RemoteException(); } List results = null; List newIntents = null; if (andResume) { // We don't need to deliver new intents and/or set results if activity is going // to pause immediately after launch. results = r.results; newIntents = r.newIntents; } if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, "Launching: " + r + " savedState=" + r.getSavedState() + " with results=" + results + " newIntents=" + newIntents + " andResume=" + andResume); EventLogTags.writeWmRestartActivity(r.mUserId, System.identityHashCode(r), task.mTaskId, r.shortComponentName); if (r.isActivityTypeHome()) { // Home process is the root process of the task. updateHomeProcess(task.getBottomMostActivity().app); } mService.getPackageManagerInternalLocked().notifyPackageUse( r.intent.getComponent().getPackageName(), NOTIFY_PACKAGE_USE_ACTIVITY); r.forceNewConfig = false; mService.getAppWarningsLocked().onStartActivity(r); r.compat = mService.compatibilityInfoForPackageLocked(r.info.applicationInfo); // Because we could be starting an Activity in the system process this may not go // across a Binder interface which would create a new Configuration. Consequently // we have to always create a new Configuration here. final Configuration procConfig = proc.prepareConfigurationForLaunchingActivity(); final MergedConfiguration mergedConfiguration = new MergedConfiguration( procConfig, r.getMergedOverrideConfiguration()); r.setLastReportedConfiguration(mergedConfiguration); logIfTransactionTooLarge(r.intent, r.getSavedState()); if (r.isEmbedded()) { // Sending TaskFragmentInfo to client to ensure the info is updated before // the activity creation. mService.mTaskFragmentOrganizerController.dispatchPendingInfoChangedEvent( r.getOrganizedTaskFragment()); } // Create activity launch transaction. //创建Activity启动事务 //这里传入的proc.getThread会赋值给ClientTransaction的成员变量mClient //而ClientTransaction会调用mClient.scheduleTransaction(this)来执行事务 //所以事务最终是调用app.thread的scheduleTransacction执行。 //而这个app.thread是ActivityThread的内部类ApplicationThread final ClientTransaction clientTransaction = ClientTransaction.obtain( proc.getThread(), r.appToken); final boolean isTransitionForward = r.isTransitionForward(); //为事务设置Callback LaunchActivityItem,在客户端时会被调用 //添加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.createFixedRotationAdjustmentsIfNeeded(), r.shareableActivityToken, r.getLaunchedFromBubble())); // Set desired final state. //生命周期对象,ActivityLifecycleItem 用来请求Activity应该到达那个生命周期 final ActivityLifecycleItem lifecycleItem; if (andResume) { //需要resume的话,设置resumeActivityItem到clientTransaction中 lifecycleItem = ResumeActivityItem.obtain(isTransitionForward); } else { //将最终生命周期设置为pause状态 lifecycleItem = PauseActivityItem.obtain(); } //设置生命周期请求 clientTransaction.setLifecycleStateRequest(lifecycleItem); // Schedule transaction. //获取生命周期管理类ClientLifeCycleManager,并执行事务 mService.getLifecycleManager().scheduleTransaction(clientTransaction); if (procConfig.seq > mRootWindowContainer.getConfiguration().seq) { // If the seq is increased, there should be something changed (e.g. registered // activity configuration). proc.setLastReportedConfiguration(procConfig); } if ((proc.mInfo.privateFlags & ApplicationInfo.PRIVATE_FLAG_CANT_SAVE_STATE) != 0 && mService.mHasHeavyWeightFeature) { // This may be a heavy-weight process! Note that the package manager will ensure // that only activity can run in the main process of the .apk, which is the only // thing that will be considered heavy-weight. if (proc.mName.equals(proc.mInfo.packageName)) { if (mService.mHeavyWeightProcess != null && mService.mHeavyWeightProcess != proc) { Slog.w(TAG, "Starting new heavy weight process " + proc + " when already running " + mService.mHeavyWeightProcess); } mService.setHeavyWeightProcess(r); } } } catch (RemoteException e) { if (r.launchFailed) { // This is the second time we failed -- finish activity and give up. //第二次启动失败的异常处理 Slog.e(TAG, "Second failure launching " + r.intent.getComponent().flattenToShortString() + ", giving up", e); proc.appDied("2nd-crash"); r.finishIfPossible("2nd-crash", false /* oomAdj */); return false; } // This is the first time we failed -- restart process and // retry. //第一次启动失败,重试 r.launchFailed = true; proc.removeActivity(r, true /* keepAssociation */); throw e; } } finally { endDeferResume(); proc.resumeConfigurationDispatch(); } r.launchFailed = false; // TODO(lifecycler): Resume or pause requests are done as part of launch transaction, // so updating the state should be done accordingly. if (andResume && readyToResume()) { // As part of the process of launching, ActivityThread also performs // a resume. rootTask.minimalResumeActivityLocked(r); } else { // This activity is not starting in the resumed state... which should look like we asked // it to pause+stop (but remain visible), and it has done so and reported back the // current icicle and other state. ProtoLog.v(WM_DEBUG_STATES, "Moving to PAUSED: %s " + "(starting in paused state)", r); r.setState(PAUSED, "realStartActivityLocked"); mRootWindowContainer.executeAppTransitionForAllDisplay(); } // Perform OOM scoring after the activity state is set, so the process can be updated with // the latest state. proc.onStartActivity(mService.mTopProcessState, r.info); // Launch the new version setup screen if needed. We do this -after- // launching the initial activity (that is, home), so that it can have // a chance to initialize itself while in the background, making the // switch back to it faster and look better. if (mRootWindowContainer.isTopDisplayFocusedRootTask(rootTask)) { mService.getActivityStartController().startSetupActivity(); } // Update any services we are bound to that might care about whether // their client may have activities. if (r.app != null) { r.app.updateServiceConnectionActivities(); } return true; }
代码如上:realStartActivityLocked方法中获取了一个ClientTransaction实例,并调用了它的addCallback方法,与上面的不同的是这里添加了一个LaunchActivityItem实例。
线程切换及消息处理——mH
ClientTransaction
ClientTransaction是包含了一系列要执行的事务项的事务。我们可以通过调用它的addCallback方法来添加一个事务项,你也可以多次调用来添加多个事务项。addCallback接收的参数类型为ClientTransactionItem,而这个ClientTransactionItem有多个子类,例如上面已经出现的NewIntentItem、LaunchActivityItem等都是其子类。
另外可以通过ClientTransactionItem的setLifecycleStateRequest方法设置Activity执行完后最终的生命周期状态,其参数的类型为ActivityLifecycleItem。ActivityLifecycleItem也是继承自ClientTransactionItem。同时ActivityLifecycleItem也有多个子类,它的每个子类都对应了Activity的一个生命周期事件。
在完成callback与LifecycleStateRequest的设置之后,便通过调用
mService.getLifecycleManager().scheduleTransaction(clientTransaction)方法开启事务项的执行。
这里的mService.getLifecycleManager()获取到的是什么呢?跟踪ActivityTaskManagerService源码我们可以找到getLifecycleManager的代码如下:
frameworks/base/services/core/java/com/android/server/wm/ActivityTaskManagerService.java ClientLifecycleManager getLifecycleManager() { return mLifecycleManager; }
可以看到,getLifecycleManager返回了一个ClientLifecycleManager的实例,并调用了scheduleTransaction方法,代码如下:
void scheduleTransaction(ClientTransaction transaction) throws RemoteException { final IApplicationThread client = transaction.getClient(); //执行事务,会调用ClientTransaction的schedule方法 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(); } } /** * Schedule a single lifecycle request or callback to client activity. * @param client Target client. * @param activityToken Target activity token. * @param stateRequest A request to move target activity to a desired lifecycle state. * @throws RemoteException * * @see ClientTransactionItem */ void scheduleTransaction(@NonNull IApplicationThread client, @NonNull IBinder activityToken, @NonNull ActivityLifecycleItem stateRequest) throws RemoteException { final ClientTransaction clientTransaction = transactionWithState(client, activityToken, stateRequest); scheduleTransaction(clientTransaction); }
在schedule方法中通过mClient调用了scheduleTransaction,这里的mClient即为IApplicationThread,这个参数是在实例化ClientTransaction时传递进来的,IApplicationThread是一个AIDL类,那么通过编译后它会生成一个IApplicationThread.Stub类,在ActivityThread中ApplicationThread就是继承了IApplicationThread.Stub。所以这里实际上调用的是ApplicationThread中的scheduleTransaction方法中。
frameworks\base\core\java\android\app/ActivityThread.java @Override public void scheduleTransaction(ClientTransaction transaction) throws RemoteException { ActivityThread.this.scheduleTransaction(transaction); }
在ActivityThread的类里面发现没有实现scheduleTransaction方法,想到子类可以调用父类的方法,所以可以去ClientTransactionHandler.java类里面去查找scheduleTransaction方法
void scheduleTransaction(ClientTransaction transaction) { //处理 transaction.preExecute(this); //发送消息 sendMessage(ActivityThread.H.EXECUTE_TRANSACTION, transaction); }
这里将transaction作为参数调用了sendMessage方法。
void sendMessage(int what, Object obj) { sendMessage(what, obj, 0, 0, false); } private void sendMessage(int what, Object obj, int arg1) { sendMessage(what, obj, arg1, 0, false); } private void sendMessage(int what, Object obj, int arg1, int arg2) { sendMessage(what, obj, arg1, arg2, false); } private void sendMessage(int what, Object obj, int arg1, int arg2, boolean async) { Message msg = Message.obtain(); msg.what = what; msg.obj = obj; msg.arg1 = arg1; msg.arg2 = arg2; if (async) { // 设置异步消息,会优先执行 msg.setAsynchronous(true); } mH.sendMessage(msg); }
可以看到,这里最终将ClientTransaction与EXECUTE_TRANSACTION打包成一个message,并且将这个message设置成了异步消息,最终通过mH发送了出去,这里的mH是一个继承自Handler的H类,位于ActivityThread类的内部。
接下来看一下在H类的内部是如何处理这条消息的,我们搜索EXECUTE_TRANSACTION可以看到如下代码:
case EXECUTE_TRANSACTION: final ClientTransaction transaction = (ClientTransaction) msg.obj; //执行事务 mTransactionExecutor.execute(transaction); if (isSystem()) { // Client transactions inside system process are recycled on the client side // instead of ClientLifecycleManager to avoid being cleared before this // message is handled. transaction.recycle(); } // TODO(lifecycler): Recycle locally scheduled transactions. break;
这里的代码很简单,通过Message拿到ClientTransaction后,然后通过TransactionExecutor的execute方法来执行ClientTransaction。
public void execute(ClientTransaction transaction) { ...省略部分代码... if (DEBUG_RESOLVER) Slog.d(TAG, transactionToString(transaction, mTransactionHandler)); //执行回调 executeCallbacks(transaction); //处理生命周期状态 executeLifecycleState(transaction); mPendingActions.clear(); if (DEBUG_RESOLVER) Slog.d(TAG, tId(transaction) + "End resolving transaction"); }
这个方法里的执行逻辑可以分为两部分:
1、通过executeCallbacks方法执行所有被添加进来的ClientTransactionItem
2、通过executeLifecycleState方法将Activity的生命周期执行到指定的状态。
executeCallbacks方法分析
executeCallbacks的代码如下:
@VisibleForTesting public void executeCallbacks(ClientTransaction transaction) { final List callbacks = transaction.getCallbacks(); if (callbacks == null || callbacks.isEmpty()) { // No callbacks to execute, return early. return; } if (DEBUG_RESOLVER) Slog.d(TAG, tId(transaction) + "Resolving callbacks in transaction"); final IBinder token = transaction.getActivityToken(); ActivityClientRecord r = mTransactionHandler.getActivityClient(token); // In case when post-execution state of the last callback matches the final state requested // for the activity in this transaction, we won't do the last transition here and do it when // moving to final state instead (because it may contain additional parameters from server). final ActivityLifecycleItem finalStateRequest = transaction.getLifecycleStateRequest(); final int finalState = finalStateRequest != null ? finalStateRequest.getTargetState() : UNDEFINED; // Index of the last callback that requests some post-execution state. final int lastCallbackRequestingState = lastCallbackRequestingState(transaction); final int size = callbacks.size(); //遍历callbacks数组 for (int i = 0; i在executeCallbacks中遍历了所有的ClientTransactionItem并执行了ClientTransactionItem的execute方法。上一章我们分析了,当Activity正常启动时,通过addCallback添加的是一个LaunchActivityItem的实例。以此为例,这里会先执行LaunchActivity的execute方法,进而执行Activity的实例化即onCreate生命周期的调用。这块源码后面再分析
ClientTransactionItem
我们上文提到过ClientTransactionItem有多个实现类,这些实现类对应了Activity中不同的执行流程。例如在Activity启动时如果不需要重新创建Activity,则会通过addCallback添加了一个NewIntentItem来执行Activity的onNewIntent方法。而当需要重新创建Activity时,则传入的是一个LaunchActivityItem,用来创建并启动Activity。
ClientTransactionItem的所有子类或相关类均在framework/base/core/java/android/app/servertransaction/目录下,如下图所示:
上文中提到的ActivityLifecycleItem继承自ClientTransactionItem,且其子类均为Activity生命周期相关的实现,例如,StartActivityItem,ResumeActivityItem、DestoryActivityItem等。显而易见的是,这里将Activity的生命周期以及其他相关方法以面向对象的思想封装成了一个个的对象来执行。相比早些年的Android版本代码,所有生命周期以及相关方法都通过Handler的sendMessage的方法发送出来,这种面向对象的思想的逻辑更加清晰,且代码更容易维护。
executeLifecycleState方法
接着来看executeCallbacks中的executeLifecycleState方法,前面提到过,这里会将Activity执行到指定的生命周期状态。上边的代码中我们看到在Activity启动时,setLifecycleStateRequest设置的是一个ResumeActivityItem,代码如下:
// 设置 Activity 最终的生命周期状态为 Resume transaction.setLifecycleStateRequest( ResumeActivityItem.obtain(next.app.getReportedProcState(), dc.isNextTransitionForward()));设置了ResumeActivityItem后,接下俩看看executeLifecycleState方法的源码:
private void executeLifecycleState(ClientTransaction transaction) { //获取ActivityLifecycleItem,这里获取的是我们之前添加的ResumeActivityItem final ActivityLifecycleItem lifecycleItem = transaction.getLifecycleStateRequest(); if (lifecycleItem == null) { // No lifecycle request, return early. return; } final IBinder token = transaction.getActivityToken(); final ActivityClientRecord r = mTransactionHandler.getActivityClient(token); if (DEBUG_RESOLVER) { Slog.d(TAG, tId(transaction) + "Resolving lifecycle state: " + lifecycleItem + " for activity: " + getShortActivityName(token, mTransactionHandler)); } if (r == null) { // Ignore requests for non-existent client records for now. return; } // Cycle to the state right before the final requested state. //切换到对应的生命周期 //ResumeActivityItem的getTargetState是on_RESUME 第二个参数为执行完时的生命周期状态 cycleToPath(r, lifecycleItem.getTargetState(), true /* excludeLastState */, transaction); // Execute the final transition with proper parameters. //执行ResumeActivityItem的execute lifecycleItem.execute(mTransactionHandler, token, mPendingActions); lifecycleItem.postExecute(mTransactionHandler, token, mPendingActions); }这段代码的关键点在于cycleToPath。同时,通过lifecycleItem.getTargetState()作为结束时的生命周期状态。由于此时设置的时一个ResumeActivityItem,它的getTargetState返回的是一个ON_RESUME的值,代码如下:
// frameworks/base/core/java/android/app/servertransaction/ResumeActivityItem.java @Override public int getTargetState() { return ON_RESUME; } @Retention(RetentionPolicy.SOURCE) public @interface LifecycleState{} public static final int UNDEFINED = -1; public static final int PRE_ON_CREATE = 0; public static final int ON_CREATE = 1; public static final int ON_START = 2; public static final int ON_RESUME = 3; public static final int ON_PAUSE = 4; public static final int ON_STOP = 5; public static final int ON_DESTROY = 6; public static final int ON_RESTART = 7;可以看到ON_RESUME的值为3。接下来看cycleToPath源码:
private void cycleToPath(ActivityClientRecord r, int finish, boolean excludeLastState, ClientTransaction transaction) { //获取当前Activity的生命周期,即开始时的状态 final int start = r.getLifecycleState(); if (DEBUG_RESOLVER) { Slog.d(TAG, tId(transaction) + "Cycle activity: " + getShortActivityName(r.token, mTransactionHandler) + " from: " + getStateName(start) + " to: " + getStateName(finish) + " excludeLastState: " + excludeLastState); } //这里的start是ON_CREATE,finish 是ON_RESUME, //mHelper是TransactionExceutorHelper类的对象 //调用getLifecyclePath返回的path包含ON_START和ON_RESUME //这里是Activity执行onStart函数的关键所在 final IntArray path = mHelper.getLifecyclePath(start, finish, excludeLastState); //执行path中的相关生命周期状态的函数 performLifecycleSequence(r, path, transaction); }在这个方法中,首先获取了当前Activity生命周期状态,即开始执行getLifecyclePath时Activity的生命周期状态,由于executeLifecycleState方法是在executeCallback之后执行的,上面我们已经提到此时的Activity已经执行完成了创建流程,并执行过了onCreate的生命周期。因此,这里的start应该是ON_CREATE状态,ON_CREATE的值为1.接下来看getLifecyclePath做了什么
// frameworks/base/core/java/android/app/servertransaction/TransactionExecutorHelper.java public IntArray getLifecyclePath(int start, int finish, boolean excludeLastState) { if (start == UNDEFINED || finish == UNDEFINED) { throw new IllegalArgumentException("Can't resolve lifecycle path for undefined state"); } if (start == ON_RESTART || finish == ON_RESTART) { throw new IllegalArgumentException( "Can't start or finish in intermittent RESTART state"); } if (finish == PRE_ON_CREATE && start != finish) { throw new IllegalArgumentException("Can only start in pre-onCreate state"); } mLifecycleSequence.clear(); // Activity 启动 时,执行到这里的 start 状态为 ON_CREATE,结束状态为 ON_RESUME if (finish >= start) { if (start == ON_START && finish == ON_STOP) { // A case when we from start to stop state soon, we don't need to go // through the resumed, paused state. mLifecycleSequence.add(ON_STOP); } else { // 会走到这里的逻辑,将 ON_START 与 ON_RESUME 添加到数组 for (int i = start + 1; i mLifecycleSequence.add(i); } } } else { // finish