站内优化怎么做,建设设计网站,江苏泗阳今天新增病例多少,wordpress论坛收费吗Activity的启动方式
启动一个Activity#xff0c;通常有两种情况#xff0c;一种是在应用内部启动Activity#xff0c;另一种是Launcher启动 1、应用内启动 通过startActivity来启动Activity 启动流程#xff1a; 一、Activity启动的发起 二、Activity的管理——ATMS 三、…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.javaE:\AOSP_12\frameworks\base\services\core\java\com\android\server\wm/RootWindowContainer.javaE:\AOSP_12\frameworks\base\services\core\java\com\android\server\wm/Task.javaE:\AOSP_12\frameworks\base\services\core\java\com\android\server\wm/TaskFragment.javaE:\AOSP_12\frameworks\base\services\core\java\com\android\server\wm/ActivityTaskSupervisor.javaE:\AOSP_12\frameworks\base\core\java\android\app\servertransaction/ClientTransaction.javaE:\AOSP_12\frameworks\base\services\core\java\com\android\server\wm/ActivityTaskManagerService.javaE:\AOSP_12\frameworks\base\services\core\java\com\android\server\wm/ClientLifecycleManager.javaE:\AOSP_12\frameworks\base\core\java\android\app/IApplicationThread.aidlE:\AOSP_12\frameworks\base\core\java\android\app/ActivityThread.javaE:\AOSP_12\frameworks\base\core\java\android\app/ClientTransactionHandler.javaE:\AOSP_12\frameworks\base\core\java\android\app\servertransaction/TransactionExecutor.javaE:\AOSP_12\frameworks\base\core\java\android\app\servertransaction/ActivityLifecycleItem.javaE:\AOSP_12\frameworks\base\core\java\android\app\servertransaction/LaunchActivityItem.javaE:\AOSP_12\frameworks\base\core\java\android\app\servertransaction/ClientTransactionItem.javaClientTransactionItem的所有子类或者相关类均在 frameworks/base/core/java/android/app/servertransaction/目录下E:\AOSP_12\frameworks\base\services\core\java\com\android\server\am/ActivityManagerService.javaE:\AOSP_12\frameworks\base\services\core\java\com\android\server\am/ProcessList.javaE:\AOSP_12\frameworks\base\core\java\android\os/Process.javaE:\AOSP_12\frameworks\base\core\java\android\os/ZygoteProcess.java一、Activity的启动的发起
启动Activity先从startActivity开始点击startActivity进入ContextWrapper类中由于mBase对象是contextContext的实现类为ContextImpl,所以直接看ContextImpl类中的startActivity方法 Overridepublic void startActivity(Intent intent, Bundle options) {//判断uid是不是System_uidwarnIfCallingFromSystemProcess();// 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.N|| 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是ActivityThreadActivityThread继承ClientTransactionHandler实现ActivityThreadInternal 是Activity运行的主进程它管理应用程序进程中主线程中执行的调度和执行活动、广播以及活动管理请求的其他操作。而Instrumentation具有跟踪application及activity生命周期的功能用于Android应用测试框架中代码检测。接着看mInstrumentation.execStartActivity方法 UnsupportedAppUsagepublic 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 i0; iN; 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的startActivityint 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 SingletonIActivityTaskManager IActivityTaskManagerSingleton new SingletonIActivityTaskManager() {Overrideprotected 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方法如下: Overridepublic 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());}Overridepublic 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对象。如下 VisibleForTestingActivityStartController(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 SynchronizedPoolActivityStarter mStarterPool new SynchronizedPool(MAX_STARTER_COUNT);DefaultFactory(ActivityTaskManagerService service,ActivityTaskSupervisor supervisor, ActivityStartInterceptor interceptor) {mService service;mSupervisor supervisor;mInterceptor interceptor;}Overridepublic void setController(ActivityStartController controller) {mController controller;}Overridepublic 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;}Overridepublic 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也就是当前activitymLastStartActivityResult 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 listif (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上启动Activityint 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) {//新建一个Taskfinal Task taskToAffiliate (mLaunchTaskBehind mSourceRecord ! null)? mSourceRecord.getTask() : null;//将Activity放入新建的任务栈setNewTask(taskToAffiliate);} else if (mAddingToTask) {//复用之前的TaskaddOrReparentStartingActivity(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 UIDsfinal 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();//创建启动黑白屏windowmTargetRootTask.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 cant 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 dont 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);}//启动栈中顶部的ActivitymRootWindowContainer.resumeFocusedTasksTopActivities(mTargetRootTask, mStartActivity, mOptions, mTransientLaunch);}}mRootWindowContainer.updateUserRootTask(mStartActivity.mUserId, mTargetRootTask);// Update the recent tasks list immediately when the activity startsmSupervisor.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 dont 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) its 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) {//如果焦点任务栈不为空则唤醒顶部的Activityresult | focusedRoot.resumeTopActivityUncheckedLocked(target, targetOptions);} else if (targetRootTask null) {//否则唤醒首页Activityresult | 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) {// Dont 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将会被重新启动//获取当前顶部正在运行的Activityfinal ActivityRecord topActivity topRunningActivity(true /* focusableOnly */);if (topActivity null) {// There are no activities left in this task, lets look somewhere else.//如果根任务栈为空则返回下一个焦点Activityreturn resumeNextFocusableActivityWhenRootTaskIsEmpty(prev, options);}final boolean[] resumed new boolean[1];//获取当前顶部正在运行的Activity的TaskFragmentfinal 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来继续唤醒顶部Activityresumed[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), its 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 dont 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 users 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 arent we using prev here??? See the param comment on the method. prev// doesnt represent the last resumed activity. However, the last focus stack does if// it isnt null.lastResumed lastFocusedRootTask.getTopResumedActivity();}boolean pausing !deferPause taskDisplayArea.pauseBackTasks(next);if (mResumedActivity ! null) {ProtoLog.d(WM_DEBUG_STATES, resumeTopActivity: Pausing %s, mResumedActivity);//暂停栈顶的Activitypausing | 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 activitys 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,所以这个地方//返回值为falseif (next.attachedToProcess()) {//为falsenext.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 isnt 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 doesnt 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 stoppedfinished because the device went to sleep, we need to make// sure to finish it as were 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// activitys 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 apps 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()) {//为falseif (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 its added to WMs 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 dont 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 wasnt able to keep the existing// instance of the activity, and instead started a new one.// We should be all done, but lets 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.ArrayListResultInfo 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最终的生命周期状态为onResumetransaction.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);//启动指定的ActivitymTaskSupervisor.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 activitys application already running?//获取目标进程final WindowProcessController wpc mService.getProcessController(r.processName, r.info.applicationInfo.uid);boolean knownToBeDead false;//进程已经创建的话直接启动activityif (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 trueif (!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 dont care about that, because the activity is// not currently running so we are just restarting it anyway.if (checkConfig) {// Deferring resume here because were going to launch new activity shortly.// We dont 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();}ListResultInfo results null;ListReferrerIntent newIntents null;if (andResume) {// We dont 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的内部类ApplicationThreadfinal ClientTransaction clientTransaction ClientTransaction.obtain(proc.getThread(), r.appToken);final boolean isTransitionForward r.isTransitionForward();//为事务设置Callback LaunchActivityItem,在客户端时会被调用//添加LaunchActivityItemclientTransaction.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 pausestop (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.javaClientLifecycleManager 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 - its 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.javaOverridepublic 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的代码如下VisibleForTestingpublic void executeCallbacks(ClientTransaction transaction) {final ListClientTransactionItem 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 wont 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 size; i) {//从callbacks数组中取出itemfinal ClientTransactionItem item callbacks.get(i);if (DEBUG_RESOLVER) Slog.d(TAG, tId(transaction) Resolving callback: item);final int postExecutionState item.getPostExecutionState();final int closestPreExecutionState mHelper.getClosestPreExecutionState(r,item.getPostExecutionState());if (closestPreExecutionState ! UNDEFINED) {cycleToPath(r, closestPreExecutionState, transaction);}//调用launchActivityItem的execute方法item.execute(mTransactionHandler, token, mPendingActions);item.postExecute(mTransactionHandler, token, mPendingActions);if (r null) {// Launch activity request will create an activity record.r mTransactionHandler.getActivityClient(token);}if (postExecutionState ! UNDEFINED r ! null) {// Skip the very last transition and perform it by explicit state request instead.final boolean shouldExcludeLastTransition i lastCallbackRequestingState finalState postExecutionState;cycleToPath(r, postExecutionState, shouldExcludeLastTransition, transaction);}}}在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生命周期相关的实现例如StartActivityItemResumeActivityItem、DestoryActivityItem等。显而易见的是这里将Activity的生命周期以及其他相关方法以面向对象的思想封装成了一个个的对象来执行。相比早些年的Android版本代码所有生命周期以及相关方法都通过Handler的sendMessage的方法发送出来这种面向对象的思想的逻辑更加清晰且代码更容易维护。
executeLifecycleState方法
接着来看executeCallbacks中的executeLifecycleState方法前面提到过这里会将Activity执行到指定的生命周期状态。上边的代码中我们看到在Activity启动时setLifecycleStateRequest设置的是一个ResumeActivityItem,代码如下 // 设置 Activity 最终的生命周期状态为 Resumetransaction.setLifecycleStateRequest(ResumeActivityItem.obtain(next.app.getReportedProcState(),dc.isNextTransitionForward()));设置了ResumeActivityItem后接下俩看看executeLifecycleState方法的源码 private void executeLifecycleState(ClientTransaction transaction) {//获取ActivityLifecycleItem这里获取的是我们之前添加的ResumeActivityItemfinal 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的executelifecycleItem.execute(mTransactionHandler, token, mPendingActions);lifecycleItem.postExecute(mTransactionHandler, token, mPendingActions);}这段代码的关键点在于cycleToPath。同时通过lifecycleItem.getTargetState()作为结束时的生命周期状态。由于此时设置的时一个ResumeActivityItem,它的getTargetState返回的是一个ON_RESUME的值代码如下
// frameworks/base/core/java/android/app/servertransaction/ResumeActivityItem.javaOverridepublic 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.javapublic IntArray getLifecyclePath(int start, int finish, boolean excludeLastState) {if (start UNDEFINED || finish UNDEFINED) {throw new IllegalArgumentException(Cant resolve lifecycle path for undefined state);}if (start ON_RESTART || finish ON_RESTART) {throw new IllegalArgumentException(Cant 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_RESUMEif (finish start) {if (start ON_START finish ON_STOP) {// A case when we from start to stop state soon, we dont need to go// through the resumed, paused state.mLifecycleSequence.add(ON_STOP);} else {// 会走到这里的逻辑将 ON_START 与 ON_RESUME 添加到数组for (int i start 1; i finish; i) {mLifecycleSequence.add(i);}}} else { // finish start, cant just cycle downif (start ON_PAUSE finish ON_RESUME) {// Special case when we can just directly go to resumed state.mLifecycleSequence.add(ON_RESUME);} else if (start ON_STOP finish ON_START) {// Restart and go to required state.// Go to stopped state first.for (int i start 1; i ON_STOP; i) {mLifecycleSequence.add(i);}// RestartmLifecycleSequence.add(ON_RESTART);// Go to required statefor (int i ON_START; i finish; i) {mLifecycleSequence.add(i);}} else {// Relaunch and go to required state// Go to destroyed state first.for (int i start 1; i ON_DESTROY; i) {mLifecycleSequence.add(i);}// Go to required statefor (int i ON_CREATE; i finish; i) {mLifecycleSequence.add(i);}}}// Remove last transition in case we want to perform it with some specific params.if (excludeLastState mLifecycleSequence.size() ! 0) {mLifecycleSequence.remove(mLifecycleSequence.size() - 1);}return mLifecycleSequence;}根据上面分析此时的start为ON_CREATE(值为1)而finish的值为ON_RESUME(值为2).因此执行完getLifecyclePath后会得到一个包含了ON_START与ON_RESUME的数组。 接下来看performLifecycleSequence中的代码 /** Transition the client through previously initialized state sequence. *//***Activity的生命周期就是在这里进行的一个相关方法的调用。这里的成员变量mTransactionHandler是一个ClientTransactionHandler对象在ClientTransactionHandler中这些方法都是抽象方法这里执行的是ClientTransactionHandler的实现类ActivityThread中的handleLaunchActivity方法*/private void performLifecycleSequence(ActivityClientRecord r, IntArray path,ClientTransaction transaction) {//通过mHelper调用getLifecyclePath返回的path是ON_STARTfinal int size path.size();//遍历数组执行Activity的生命周期for (int i 0, state; i size; i) {state path.get(i);if (DEBUG_RESOLVER) {Slog.d(TAG, tId(transaction) Transitioning activity: getShortActivityName(r.token, mTransactionHandler) to state: getStateName(state));}switch (state) {case ON_CREATE:mTransactionHandler.handleLaunchActivity(r, mPendingActions,null /* customIntent */);break;case ON_START:mTransactionHandler.handleStartActivity(r, mPendingActions,null /* activityOptions */);break;case ON_RESUME:mTransactionHandler.handleResumeActivity(r, false /* finalStateRequest */,r.isForward, LIFECYCLER_RESUME_ACTIVITY);break;case ON_PAUSE:mTransactionHandler.handlePauseActivity(r, false /* finished */,false /* userLeaving */, 0 /* configChanges */, mPendingActions,LIFECYCLER_PAUSE_ACTIVITY);break;case ON_STOP:mTransactionHandler.handleStopActivity(r, 0 /* configChanges */,mPendingActions, false /* finalStateRequest */,LIFECYCLER_STOP_ACTIVITY);break;case ON_DESTROY:mTransactionHandler.handleDestroyActivity(r, false /* finishing */,0 /* configChanges */, false /* getNonConfigInstance */,performLifecycleSequence. cycling to: path.get(size - 1));break;case ON_RESTART:mTransactionHandler.performRestartActivity(r, false /* start */);break;default:throw new IllegalArgumentException(Unexpected lifecycle state: state);}}}
}在performLifecycleSequence方法中则是遍历了这个数组。因为此时的数组中只有ON_START与ON_RESUME两个值因此这里分别先后执行了mTransactionHandler.handleStartActivity与mTransactionHandler.handleResumeActivity即调用了ApplicationThread的handleStartActivity与handleResumeActivity来执行Activity的onStart与onResume的生命周期。
Activity启动核心实现——Activity的创建与生命周期的执行
Activity的启动是在服务端通过添加一个LaunchActivityItem到ClientTransaction中实现的然后通过IApplicationThread跨进程将ClientTransaction传到了客户端来执行的。客户端通过遍历ClientTransaction中的所有ClientTransactionItem并执行了它的execute方法进而来执行Activity的创建过程。那接下来看LaunchActivityItem的execute方法调用后到底是如何执行的。
frameworks/base/core/java/android/app/servertransaction/LaunchActivityItem.javaOverridepublic void execute(ClientTransactionHandler client, IBinder token,PendingTransactionActions pendingActions) {Trace.traceBegin(TRACE_TAG_ACTIVITY_MANAGER, activityStart);ActivityClientRecord r client.getLaunchingActivity(token);client.handleLaunchActivity(r, pendingActions, null /* customIntent */);Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER);}LaunchActivityItem的execute方法调用了ClientTransactionHandler的handleLaunchActivity而这里的ClientTransactionHandler就是ActivityThread。ActivityThread中的handleLaunchActivity的源码如下
frameworks/base/core/java/android/app/ActivityThread.javaOverridepublic Activity handleLaunchActivity(ActivityClientRecord r,PendingTransactionActions pendingActions, Intent customIntent) {// If we are getting ready to gc after going to the background, well// we are back active so skip it.unscheduleGcIdler();mSomeActivitiesChanged true;if (r.profilerInfo ! null) {mProfiler.setProfiler(r.profilerInfo);mProfiler.startProfiling();}if (r.mPendingFixedRotationAdjustments ! null) {// The rotation adjustments must be applied before handling configuration, so process// level display metrics can be adjusted.overrideApplicationDisplayAdjustments(r.token, adjustments -adjustments.setFixedRotationAdjustments(r.mPendingFixedRotationAdjustments));}// Make sure we are running with the most recent config.mConfigurationController.handleConfigurationChanged(null, null);if (localLOGV) Slog.v(TAG, Handling launch of r);// Initialize before creating the activityif (ThreadedRenderer.sRendererEnabled (r.activityInfo.flags ActivityInfo.FLAG_HARDWARE_ACCELERATED) ! 0) {HardwareRenderer.preload();}//创建WindowManagerServerWindowManagerGlobal.initialize();// Hint the GraphicsEnvironment that an activity is launching on the process.GraphicsEnvironment.hintActivityLaunch();//通过反射创建指定的Activity并回调Activity的PerformCreate方法执行onCreatefinal Activity a performLaunchActivity(r, customIntent);if (a ! null) {r.createdConfig new Configuration(mConfigurationController.getConfiguration());reportSizeConfigurations(r);if (!r.activity.mFinished pendingActions ! null) {pendingActions.setOldState(r.state);pendingActions.setRestoreInstanceState(true);pendingActions.setCallOnPostCreate(true);}} else {// If there was an error, for any reason, tell the activity manager to stop us.ActivityClient.getInstance().finishActivity(r.token, Activity.RESULT_CANCELED,null /* resultData */, Activity.DONT_FINISH_TASK_WITH_ACTIVITY);}return a;}在handleLaunchActivity方法中首先去初始化WindowManagerGlobal紧接着调用了performLaunchActivity并返回了一个Activity实例那么Activity的实例化必定是在performLaunchActivity中完成的。
Activity的实例化与onCreate的调用
看下performLaunchActivity的源码
frameworks/base/core/java/android/app/ActivityThread.javaprivate Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {ActivityInfo aInfo r.activityInfo;if (r.packageInfo null) {r.packageInfo getPackageInfo(aInfo.applicationInfo, r.compatInfo,Context.CONTEXT_INCLUDE_CODE);}ComponentName component r.intent.getComponent();if (component null) {component r.intent.resolveActivity(mInitialApplication.getPackageManager());r.intent.setComponent(component);}if (r.activityInfo.targetActivity ! null) {component new ComponentName(r.activityInfo.packageName,r.activityInfo.targetActivity);}ContextImpl appContext createBaseContextForActivity(r);Activity activity null;try {//反射创建Activityjava.lang.ClassLoader cl appContext.getClassLoader();activity mInstrumentation.newActivity(cl, component.getClassName(), r.intent);StrictMode.incrementExpectedActivityCount(activity.getClass());r.intent.setExtrasClassLoader(cl);r.intent.prepareToEnterProcess(isProtectedComponent(r.activityInfo),appContext.getAttributionSource());if (r.state ! null) {r.state.setClassLoader(cl);}} catch (Exception e) {if (!mInstrumentation.onException(activity, e)) {throw new RuntimeException(Unable to instantiate activity component : e.toString(), e);}}try {//如果没有Application则进行创建Application app r.packageInfo.makeApplication(false, mInstrumentation);if (localLOGV) Slog.v(TAG, Performing launch of r);if (localLOGV) Slog.v(TAG, r : app app , appName app.getPackageName() , pkg r.packageInfo.getPackageName() , comp r.intent.getComponent().toShortString() , dir r.packageInfo.getAppDir());// updatePendingActivityConfiguration() reads from mActivities to update// ActivityClientRecord which runs in a different thread. Protect modifications to// mActivities to avoid race.synchronized (mResourcesManager) {mActivities.put(r.token, r);}if (activity ! null) {CharSequence title r.activityInfo.loadLabel(appContext.getPackageManager());Configuration config new Configuration(mConfigurationController.getCompatConfiguration());if (r.overrideConfig ! null) {config.updateFrom(r.overrideConfig);}if (DEBUG_CONFIGURATION) Slog.v(TAG, Launching activity r.activityInfo.name with config config);Window window null;if (r.mPendingRemoveWindow ! null r.mPreserveWindow) {window r.mPendingRemoveWindow;r.mPendingRemoveWindow null;r.mPendingRemoveWindowManager null;}// Activity resources must be initialized with the same loaders as the// application context.//加载资源appContext.getResources().addLoaders(app.getResources().getLoaders().toArray(new ResourcesLoader[0]));appContext.setOuterContext(activity);//调用attach方法,会在这个方法中创建Activity的PhoneWindow,并绑定对应的WindowManageractivity.attach(appContext, this, getInstrumentation(), r.token,r.ident, app, r.intent, r.activityInfo, title, r.parent,r.embeddedID, r.lastNonConfigurationInstances, config,r.referrer, r.voiceInteractor, window, r.configCallback,r.assistToken, r.shareableActivityToken);if (customIntent ! null) {activity.mIntent customIntent;}r.lastNonConfigurationInstances null;checkAndBlockForNetworkAccess();activity.mStartedActivity false;int theme r.activityInfo.getThemeResource();if (theme ! 0) {activity.setTheme(theme);}if (r.mActivityOptions ! null) {activity.mPendingOptions r.mActivityOptions;r.mActivityOptions null;}activity.mLaunchedFromBubble r.mLaunchedFromBubble;activity.mCalled false;// Assigning the activity to the record before calling onCreate() allows// ActivityThread#getActivity() lookup for the callbacks triggered from// ActivityLifecycleCallbacks#onActivityCreated() or// ActivityLifecycleCallback#onActivityPostCreated().r.activity activity;//回调onCreate方法if (r.isPersistable()) {mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);} else {mInstrumentation.callActivityOnCreate(activity, r.state);}if (!activity.mCalled) {throw new SuperNotCalledException(Activity r.intent.getComponent().toShortString() did not call through to super.onCreate());}mLastReportedWindowingMode.put(activity.getActivityToken(),config.windowConfiguration.getWindowingMode());}//设置当前状态r.setState(ON_CREATE);} catch (SuperNotCalledException e) {throw e;} catch (Exception e) {if (!mInstrumentation.onException(activity, e)) {throw new RuntimeException(Unable to start activity component : e.toString(), e);}}return activity;}这个方法中的主要逻辑可以分为两部分第一部分是实例化Activity第二部分是执行Activity的onCreate的生命周期。先看第一部分通过Instrumentation的newActivity获取到一个Activity实例newActivity的参数传入了一个ClassLoader和Activity的className。因此这里实例化Activity的过程一定是通过反射实现的。查看Instrumentation的newActivity方法如下 public Activity newActivity(ClassLoader cl, String className,Intent intent)throws InstantiationException, IllegalAccessException,ClassNotFoundException {String pkg intent ! null intent.getComponent() ! null? intent.getComponent().getPackageName() : null;return getFactory(pkg).instantiateActivity(cl, className, intent);}private AppComponentFactory getFactory(String pkg) {if (pkg null) {Log.e(TAG, No pkg specified, disabling AppComponentFactory);return AppComponentFactory.DEFAULT;}if (mThread null) {Log.e(TAG, Uninitialized ActivityThread, likely app-created Instrumentation, disabling AppComponentFactory, new Throwable());return AppComponentFactory.DEFAULT;}LoadedApk apk mThread.peekPackageInfo(pkg, true);// This is in the case of starting up android.if (apk null) apk mThread.getSystemContext().mPackageInfo;return apk.getAppFactory();}通过代码可知通过getFactory(pkg)方法得到的是AppComponentFactory对象进入AppComponentFactory.java里面查看instantiateActivity方法 public NonNull Activity instantiateActivity(NonNull ClassLoader cl, NonNull String className,Nullable Intent intent)throws InstantiationException, IllegalAccessException, ClassNotFoundException {return (Activity) cl.loadClass(className).newInstance();}所以送上面代码可以知道在ActivityThread的performLaunchActivity 方法里面Instrumentation通过newActivity实例化了Activity接着调用了Activity的attach方法。 UnsupportedAppUsage(maxTargetSdk Build.VERSION_CODES.R, trackingBug 170729553)final void attach(Context context, ActivityThread aThread,Instrumentation instr, IBinder token, int ident,Application application, Intent intent, ActivityInfo info,CharSequence title, Activity parent, String id,NonConfigurationInstances lastNonConfigurationInstances,Configuration config, String referrer, IVoiceInteractor voiceInteractor,Window window, ActivityConfigCallback activityConfigCallback, IBinder assistToken,IBinder shareableActivityToken) {attachBaseContext(context);mFragments.attachHost(null /*parent*/);//实例化PhoneWindowActivity中持有PhoneWindowmWindow new PhoneWindow(this, window, activityConfigCallback);mWindow.setWindowControllerCallback(mWindowControllerCallback);//将Activity自身设置到PhoneWindowmWindow.setCallback(this);mWindow.setOnWindowDismissedCallback(this);mWindow.getLayoutInflater().setPrivateFactory(this);if (info.softInputMode ! WindowManager.LayoutParams.SOFT_INPUT_STATE_UNSPECIFIED) {mWindow.setSoftInputMode(info.softInputMode);}if (info.uiOptions ! 0) {mWindow.setUiOptions(info.uiOptions);}mUiThread Thread.currentThread();mMainThread aThread;mInstrumentation instr;mToken token;mAssistToken assistToken;mShareableActivityToken shareableActivityToken;mIdent ident;mApplication application;mIntent intent;mReferrer referrer;mComponent intent.getComponent();mActivityInfo info;mTitle title;mParent parent;mEmbeddedID id;mLastNonConfigurationInstances lastNonConfigurationInstances;if (voiceInteractor ! null) {if (lastNonConfigurationInstances ! null) {mVoiceInteractor lastNonConfigurationInstances.voiceInteractor;} else {mVoiceInteractor new VoiceInteractor(voiceInteractor, this, this,Looper.myLooper());}}//将PhoneWindow关联到WindowManagermWindow.setWindowManager((WindowManager)context.getSystemService(Context.WINDOW_SERVICE),mToken, mComponent.flattenToString(),(info.flags ActivityInfo.FLAG_HARDWARE_ACCELERATED) ! 0);if (mParent ! null) {mWindow.setContainer(mParent.getWindow());}//在Activity中持有windowManagermWindowManager mWindow.getWindowManager();mCurrentConfig config;mWindow.setColorMode(info.colorMode);mWindow.setPreferMinimalPostProcessing((info.flags ActivityInfo.FLAG_PREFER_MINIMAL_POST_PROCESSING) ! 0);setAutofillOptions(application.getAutofillOptions());setContentCaptureOptions(application.getContentCaptureOptions());}调用了attach方法之后接着通过Instrumentation执行了Activity的callActivityOnCreate方法代码如下 public void callActivityOnCreate(Activity activity, Bundle icicle,PersistableBundle persistentState) {prePerformCreate(activity);activity.performCreate(icicle, persistentState);postPerformCreate(activity);}在Activity的callActivityOnCreate方法中最终会调用到Activity的onCreate方法。
onStart方法的执行
在前面我们分析了Activity后会执行oncreate,onStart,onResume方法这些生命周期方法。onStart是通过ActivityThread的handleStartActivity来执行的。其源码如下 Overridepublic void handleStartActivity(ActivityClientRecord r,PendingTransactionActions pendingActions, ActivityOptions activityOptions) {final Activity activity r.activity;if (!r.stopped) {throw new IllegalStateException(Cant start activity that is not stopped.);}if (r.activity.mFinished) {// TODO(lifecycler): How can this happen?return;}unscheduleGcIdler();if (activityOptions ! null) {activity.mPendingOptions activityOptions;}// Start//调用Activity的performStart进而执行onStartactivity.performStart(handleStartActivity);//将生命周期状态设置为on_startr.setState(ON_START);if (pendingActions null) {// No more work to do.return;}// Restore instance stateif (pendingActions.shouldRestoreInstanceState()) {if (r.isPersistable()) {if (r.state ! null || r.persistentState ! null) {mInstrumentation.callActivityOnRestoreInstanceState(activity, r.state,r.persistentState);}} else if (r.state ! null) {mInstrumentation.callActivityOnRestoreInstanceState(activity, r.state);}}// Call postOnCreate()if (pendingActions.shouldCallOnPostCreate()) {activity.mCalled false;if (r.isPersistable()) {mInstrumentation.callActivityOnPostCreate(activity, r.state,r.persistentState);} else {mInstrumentation.callActivityOnPostCreate(activity, r.state);}if (!activity.mCalled) {throw new SuperNotCalledException(Activity r.intent.getComponent().toShortString() did not call through to super.onPostCreate());}}updateVisibility(r, true /* show */);mSomeActivitiesChanged true;}handleStartActivity的逻辑比较简单就是调用了Activity的performStart方法进而调用了onStart方法。
onResume 方法的调用
onResume方法是通过ActivityThread的handleResumeActivity来执行的。 源码如下 Overridepublic void handleResumeActivity(ActivityClientRecord r, boolean finalStateRequest,boolean isForward, String reason) {// If we are getting ready to gc after going to the background, well// we are back active so skip it.unscheduleGcIdler();mSomeActivitiesChanged true;// TODO Push resumeArgs into the activity for consideration// skip below steps for double-resume and r.mFinish true case.if (!performResumeActivity(r, finalStateRequest, reason)) {return;}if (mActivitiesToBeDestroyed.containsKey(r.token)) {// Although the activity is resumed, it is going to be destroyed. So the following// UI operations are unnecessary and also prevents exception because its token may// be gone that window manager cannot recognize it. All necessary cleanup actions// performed below will be done while handling destruction.return;}final Activity a r.activity;if (localLOGV) {Slog.v(TAG, Resume r started activity: a.mStartedActivity , hideForNow: r.hideForNow , finished: a.mFinished);}final int forwardBit isForward? WindowManager.LayoutParams.SOFT_INPUT_IS_FORWARD_NAVIGATION : 0;// If the window hasnt yet been added to the window manager,// and this guy didnt finish itself or start another activity,// then go ahead and add the window.boolean willBeVisible !a.mStartedActivity;if (!willBeVisible) {willBeVisible ActivityClient.getInstance().willActivityBeVisible(a.getActivityToken());}if (r.window null !a.mFinished willBeVisible) {//获取PhoneWindowr.window r.activity.getWindow();//获取DecorViewView decor r.window.getDecorView();//设置DecorView不可见decor.setVisibility(View.INVISIBLE);//获取WindowManagerViewManager wm a.getWindowManager();//获取window的属性参数WindowManager.LayoutParams l r.window.getAttributes();a.mDecor decor;l.type WindowManager.LayoutParams.TYPE_BASE_APPLICATION;l.softInputMode | forwardBit;if (r.mPreserveWindow) {a.mWindowAdded true;r.mPreserveWindow false;// Normally the ViewRoot sets up callbacks with the Activity// in addView-ViewRootImpl#setView. If we are instead reusing// the decor view we have to notify the view root that the// callbacks may have changed.ViewRootImpl impl decor.getViewRootImpl();if (impl ! null) {impl.notifyChildRebuilt();}}if (a.mVisibleFromClient) {if (!a.mWindowAdded) {a.mWindowAdded true;//通过WindowManager将DecorView添加到窗口wm.addView(decor, l);} else {// The activity will get a callback for this {link LayoutParams} change// earlier. However, at that time the decor will not be set (this is set// in this method), so no action will be taken. This call ensures the// callback occurs with the decor set.a.onWindowAttributesChanged(l);}}// If the window has already been added, but during resume// we started another activity, then dont yet make the// window visible.} else if (!willBeVisible) {if (localLOGV) Slog.v(TAG, Launch r mStartedActivity set);r.hideForNow true;}// Get rid of anything left hanging around.cleanUpPendingRemoveWindows(r, false /* force */);// The window is now visible if it has been added, we are not// simply finishing, and we are not starting another activity.if (!r.activity.mFinished willBeVisible r.activity.mDecor ! null !r.hideForNow) {if (localLOGV) Slog.v(TAG, Resuming r with isForward isForward);ViewRootImpl impl r.window.getDecorView().getViewRootImpl();WindowManager.LayoutParams l impl ! null? impl.mWindowAttributes : r.window.getAttributes();if ((l.softInputMode WindowManager.LayoutParams.SOFT_INPUT_IS_FORWARD_NAVIGATION)! forwardBit) {l.softInputMode (l.softInputMode (~WindowManager.LayoutParams.SOFT_INPUT_IS_FORWARD_NAVIGATION))| forwardBit;if (r.activity.mVisibleFromClient) {ViewManager wm a.getWindowManager();View decor r.window.getDecorView();wm.updateViewLayout(decor, l);}}r.activity.mVisibleFromServer true;mNumVisibleActivities;if (r.activity.mVisibleFromClient) {r.activity.makeVisible();}}r.nextIdle mNewActivities;mNewActivities r;if (localLOGV) Slog.v(TAG, Scheduling idle handler for r);Looper.myQueue().addIdleHandler(new Idler());}handleResumeActivity方法中的逻辑比较复杂但核心主要有两点 1、调用performResumeActivity执行onResume的生命周期 2、将DecorView添加到Window中。 先来看performResumeActivity方法其源码如下 VisibleForTestingpublic boolean performResumeActivity(ActivityClientRecord r, boolean finalStateRequest,String reason) {if (localLOGV) {Slog.v(TAG, Performing resume of r finished r.activity.mFinished);}if (r.activity.mFinished) {//如果activity已经finish状态直接return falsereturn false;}if (r.getLifecycleState() ON_RESUME) {if (!finalStateRequest) {final RuntimeException e new IllegalStateException(Trying to resume activity which is already resumed);Slog.e(TAG, e.getMessage(), e);Slog.e(TAG, r.getStateString());// TODO(lifecycler): A double resume request is possible when an activity// receives two consequent transactions with relaunch requests and resumed// final state requests and the second relaunch is omitted. We still try to// handle two resume requests for the final state. For cases other than this// one, we dont expect it to happen.}//如果已经是resume状态直接return false,避免重复执行return false;}if (finalStateRequest) {r.hideForNow false;r.activity.mStartedActivity false;}try {r.activity.onStateNotSaved();r.activity.mFragments.noteStateNotSaved();checkAndBlockForNetworkAccess();if (r.pendingIntents ! null) {deliverNewIntents(r, r.pendingIntents);r.pendingIntents null;}if (r.pendingResults ! null) {deliverResults(r, r.pendingResults, reason);r.pendingResults null;}//执行activity的performResume进而执行onResumer.activity.performResume(r.startsNotResumed, reason);r.state null;r.persistentState null;//设置Activity的状态为ON_RESUMEr.setState(ON_RESUME);reportTopResumedActivityChanged(r, r.isTopResumedActivity, topWhenResuming);} catch (Exception e) {if (!mInstrumentation.onException(r.activity, e)) {throw new RuntimeException(Unable to resume activity r.intent.getComponent().toShortString() : e.toString(), e);}}return true;}在performResumeActivity中先对Activity的状态进行了判断如果符合状态则会调用Activity的performResume方法进而执行Activity的onResume。 在完成了performResume的调用后performResumeActivity方法中接着执行了将DecorView添加到Window的过程代码如上所示可以看到核心就是wm.addView(decor,1)这行代码通过ViewManager的addView方法将DecorView添加到了窗口中。窗口的添加过程会完成DecorView的布局、测量与绘制。当完成窗口的添加后Activity的View才被显示出来且有了宽度。
四、根Activity的启动
根应用进程的创建
在第二节中讲到ActivityStackSupervisor.startSpecificActivity()启动会判断进程是否存在如果不存在则创建进程。我们下面就根据这个逻辑来分信息如果进程不存在会调用mService.startProcessAsync()方法具体代码如下
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.//发布消息以启动进程以避免在持有ATMS锁的情况下调用AMS可能出现的死锁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);}}使用ActivityTaskManagerService的mH(继承handler)发送了一个消息消息中第一个此参数是ActivityManagerInternal::startProcess,ActivityManagerInternal的实现是AMS的内部类LocalServvice,LocalService的startProcess方法调用了AMS的startProcessLocked方法那么我们就看AMS的startProcessLocked方法这里应该就是创建进程了: 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 */,null /* ABI override */, null /* entryPoint */,null /* entryPointArgs */, null /* crashHandler */);}
这里调用了ProcessList.startProcessLocked方法内部又多次调用了startProcessLocked不同的重载方法最后走到startProcess方法 private Process.ProcessStartResult startProcess(HostingRecord hostingRecord, String entryPoint,ProcessRecord app, int uid, int[] gids, int runtimeFlags, int zygotePolicyFlags,int mountExternal, String seInfo, String requiredAbi, String instructionSet,String invokeWith, long startTime) {try {Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, Start proc: app.processName);checkSlow(startTime, startProcess: asking zygote to start proc);final boolean isTopApp hostingRecord.isTopApp();if (isTopApp) {// Use has-foreground-activities as a temporary hint so the current scheduling// group wont be lost when the process is attaching. The actual state will be// refreshed when computing oom-adj.app.mState.setHasForegroundActivities(true);}MapString, PairString, Long pkgDataInfoMap;MapString, PairString, Long allowlistedAppDataInfoMap;boolean bindMountAppStorageDirs false;boolean bindMountAppsData mAppDataIsolationEnabled (UserHandle.isApp(app.uid) || UserHandle.isIsolated(app.uid)) mPlatformCompat.isChangeEnabled(APP_DATA_DIRECTORY_ISOLATION, app.info);// Get all packages belongs to the same shared uid. sharedPackages is empty array// if it doesnt have shared uid.final PackageManagerInternal pmInt mService.getPackageManagerInternal();final String[] sharedPackages pmInt.getSharedUserPackagesForPackage(app.info.packageName, app.userId);final String[] targetPackagesList sharedPackages.length 0? new String[]{app.info.packageName} : sharedPackages;pkgDataInfoMap getPackageAppDataInfoMap(pmInt, targetPackagesList, uid);if (pkgDataInfoMap null) {// TODO(b/152760674): Handle inode 0 case properly, now we just give it a// tmp free pass.bindMountAppsData false;}// Remove all packages in pkgDataInfoMap from mAppDataIsolationAllowlistedApps, so// it wont be mounted twice.final SetString allowlistedApps new ArraySet(mAppDataIsolationAllowlistedApps);for (String pkg : targetPackagesList) {allowlistedApps.remove(pkg);}allowlistedAppDataInfoMap getPackageAppDataInfoMap(pmInt,allowlistedApps.toArray(new String[0]), uid);if (allowlistedAppDataInfoMap null) {// TODO(b/152760674): Handle inode 0 case properly, now we just give it a// tmp free pass.bindMountAppsData false;}int userId UserHandle.getUserId(uid);StorageManagerInternal storageManagerInternal LocalServices.getService(StorageManagerInternal.class);if (needsStorageDataIsolation(storageManagerInternal, app)) {// We will run prepareStorageDirs() after we trigger zygote fork, so it wont// slow down app starting speed as those dirs might not be cached.if (pkgDataInfoMap ! null storageManagerInternal.isFuseMounted(userId)) {bindMountAppStorageDirs true;} else {// Fuse is not mounted or inode 0,// so we wont mount it in zygote, but resume the mount after unlocking device.app.setBindMountPending(true);bindMountAppStorageDirs false;}}// If its an isolated process, it should not even mount its own app data directories,// since it has no access to them anyway.if (app.isolated) {pkgDataInfoMap null;allowlistedAppDataInfoMap null;}final Process.ProcessStartResult startResult;boolean regularZygote false;if (hostingRecord.usesWebviewZygote()) {startResult startWebView(entryPoint,app.processName, uid, uid, gids, runtimeFlags, mountExternal,app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet,app.info.dataDir, null, app.info.packageName,app.getDisabledCompatChanges(),new String[]{PROC_START_SEQ_IDENT app.getStartSeq()});} else if (hostingRecord.usesAppZygote()) {final AppZygote appZygote createAppZygoteForProcessIfNeeded(app);// We cant isolate app data and storage data as parent zygote already did that.startResult appZygote.getProcess().start(entryPoint,app.processName, uid, uid, gids, runtimeFlags, mountExternal,app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet,app.info.dataDir, null, app.info.packageName,/*zygotePolicyFlags*/ ZYGOTE_POLICY_FLAG_EMPTY, isTopApp,app.getDisabledCompatChanges(), pkgDataInfoMap, allowlistedAppDataInfoMap,false, false,new String[]{PROC_START_SEQ_IDENT app.getStartSeq()});} else {regularZygote true;startResult Process.start(entryPoint,app.processName, uid, uid, gids, runtimeFlags, mountExternal,app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet,app.info.dataDir, invokeWith, app.info.packageName, zygotePolicyFlags,isTopApp, app.getDisabledCompatChanges(), pkgDataInfoMap,allowlistedAppDataInfoMap, bindMountAppsData, bindMountAppStorageDirs,new String[]{PROC_START_SEQ_IDENT app.getStartSeq()});}if (!regularZygote) {// webview and app zygote dont have the permission to create the nodesif (Process.createProcessGroup(uid, startResult.pid) 0) {Slog.e(ActivityManagerService.TAG, Unable to create process group for app.processName ( startResult.pid ));}}// This runs after Process.start() as this method may block app process starting time// if dir is not cached. Running this method after Process.start() can make it// cache the dir asynchronously, so zygote can use it without waiting for it.if (bindMountAppStorageDirs) {storageManagerInternal.prepareStorageDirs(userId, pkgDataInfoMap.keySet(),app.processName);}checkSlow(startTime, startProcess: returned from zygote!);return startResult;} finally {Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);}}调用了Process.start方法代码如下 public static ProcessStartResult start(NonNull final String processClass,Nullable final String niceName,int uid, int gid, Nullable int[] gids,int runtimeFlags,int mountExternal,int targetSdkVersion,Nullable String seInfo,NonNull String abi,Nullable String instructionSet,Nullable String appDataDir,Nullable String invokeWith,Nullable String packageName,int zygotePolicyFlags,boolean isTopApp,Nullable long[] disabledCompatChanges,Nullable MapString, PairString, LongpkgDataInfoMap,Nullable MapString, PairString, LongwhitelistedDataInfoMap,boolean bindMountAppsData,boolean bindMountAppStorageDirs,Nullable String[] zygoteArgs) {return ZYGOTE_PROCESS.start(processClass, niceName, uid, gid, gids,runtimeFlags, mountExternal, targetSdkVersion, seInfo,abi, instructionSet, appDataDir, invokeWith, packageName,zygotePolicyFlags, isTopApp, disabledCompatChanges,pkgDataInfoMap, whitelistedDataInfoMap, bindMountAppsData,bindMountAppStorageDirs, zygoteArgs);}ZYGOTE_PROCESS是用于保持与Zygote进程的通信状态发送socket请求与Zygote进程通信。我们知道其内部主要做了1、Zygote通过fork创建了一个新的进程2、在新建的进程中创建Binder线程池。3、通过反射获取了ActivityThread类并执行了main方法
根Activity的启动
ActivityThread的main方法。具体代码如下 public static void main(String[] args) {Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, ActivityThreadMain);// Install selective syscall interception//安全选择性的系统调用拦截AndroidOs.install();// CloseGuard defaults to true and can be quite spammy. We// disable it here, but selectively enable it later (via// StrictMode) on debug builds, but using DropBox, not logs.CloseGuard.setEnabled(false);Environment.initForCurrentUser();// Make sure TrustedCertificateStore looks in the right place for CA certificatesfinal File configDir Environment.getUserConfigDirectory(UserHandle.myUserId());TrustedCertificateStore.setDefaultUserDirectory(configDir);// Call per-process mainline module initialization.initializeMainlineModules();Process.setArgV0(pre-initialized);//1、创建MainLooperLooper.prepareMainLooper();// Find the value for {link #PROC_START_SEQ_IDENT} if provided on the command line.// It will be in the format seq114long startSeq 0;if (args ! null) {for (int i args.length - 1; i 0; --i) {if (args[i] ! null args[i].startsWith(PROC_START_SEQ_IDENT)) {startSeq Long.parseLong(args[i].substring(PROC_START_SEQ_IDENT.length()));}}}//之前SystemServer调用attach传入的是true这里到应用进程传入false就行//2、创建ActivityThreadActivityThread thread new ActivityThread();//3、调用attach方法thread.attach(false, startSeq);if (sMainThreadHandler null) {sMainThreadHandler thread.getHandler();}if (false) {Looper.myLooper().setMessageLogging(newLogPrinter(Log.DEBUG, ActivityThread));}// End of event ActivityThreadMain.Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);//一直循环保障程序一直执行如果退出说明程序关闭Looper.loop();//因为主线程的Looper是不能退出的退出就无法接收事件了一旦意外退出就会抛出异常throw new RuntimeException(Main thread loop unexpectedly exited);}在main方法里面主要做了三件事1、创建mainLooper,2、创建ActivityThread实例3、调用了attach方法。创建ActivityThread实例同时会创建ApplicationThread实例ApplicationThread实例是ActivityThread实例的属性。然后调用了attach方法 UnsupportedAppUsageprivate void attach(boolean system, long startSeq) {sCurrentActivityThread this;mConfigurationController new ConfigurationController(this);mSystemThread system;//传递过来的system参数是true,startSeq 0//ActivityThread.main方法传递过来的system参数为falseif (!system) {android.ddm.DdmHandleAppName.setAppName(pre-initialized,UserHandle.myUserId());RuntimeInit.setApplicationObject(mAppThread.asBinder());//获取AMS的本地代理类final IActivityManager mgr ActivityManager.getService();try {//通过Binder调用AMS的attachApplication方法把ApplicationThread实例关联到AMS中mgr.attachApplication(mAppThread, startSeq);} catch (RemoteException ex) {throw ex.rethrowFromSystemServer();}// Watch for getting close to heap limit.BinderInternal.addGcWatcher(new Runnable() {Override public void run() {if (!mSomeActivitiesChanged) {return;}Runtime runtime Runtime.getRuntime();long dalvikMax runtime.maxMemory();long dalvikUsed runtime.totalMemory() - runtime.freeMemory();if (dalvikUsed ((3*dalvikMax)/4)) {if (DEBUG_MEMORY_TRIM) Slog.d(TAG, Dalvik max (dalvikMax/1024) total (runtime.totalMemory()/1024) used (dalvikUsed/1024));mSomeActivitiesChanged false;try {ActivityTaskManager.getService().releaseSomeActivities(mAppThread);} catch (RemoteException e) {throw e.rethrowFromSystemServer();}}}});} else {// Dont set application object here -- if the system crashes,// we cant display an alert, we just want to die die die.android.ddm.DdmHandleAppName.setAppName(system_process,UserHandle.myUserId());try {//创建了ContextImpl还执行了application的onCreate方法mInstrumentation new Instrumentation();mInstrumentation.basicInit(this);ContextImpl context ContextImpl.createAppContext(this, getSystemContext().mPackageInfo);mInitialApplication context.mPackageInfo.makeApplication(true, null);mInitialApplication.onCreate();} catch (Exception e) {throw new RuntimeException(Unable to instantiate Application(): e.toString(), e);}}//为ViewRootImpl设置配置更新回调//当系统资源配置(如:系统字体)发生变化时通知系统配置发生变化ViewRootImpl.ConfigChangedCallback configChangedCallback (Configuration globalConfig) - {synchronized (mResourcesManager) {// We need to apply this change to the resources immediately, because upon returning// the view hierarchy will be informed about it.if (mResourcesManager.applyConfigurationToResources(globalConfig,null /* compat */,mInitialApplication.getResources().getDisplayAdjustments())) {mConfigurationController.updateLocaleListFromAppContext(mInitialApplication.getApplicationContext());// This actually changed the resources! Tell everyone about it.final Configuration updatedConfig mConfigurationController.updatePendingConfiguration(globalConfig);if (updatedConfig ! null) {sendMessage(H.CONFIGURATION_CHANGED, globalConfig);mPendingConfiguration updatedConfig;}}}};ViewRootImpl.addConfigCallback(configChangedCallback);}根据ActivityThread.main方法中传递过来的参数得知system参数为false,所以会执行(!system)里面的内容。可以看到获取AMS的本地代理类对象然后调用attachApplication方法就是IPC的走到AMS的attachApplication方法 Overridepublic final void attachApplication(IApplicationThread thread, long startSeq) {if (thread null) {throw new SecurityException(Invalid application interface);}synchronized (this) {int callingPid Binder.getCallingPid();final int callingUid Binder.getCallingUid();final long origId Binder.clearCallingIdentity();attachApplicationLocked(thread, callingPid, callingUid, startSeq);Binder.restoreCallingIdentity(origId);}}在attachApplication方法中调用了attachApplicationLock()方法 /***该方法主要做了两件事1、调用ApplicationThread的bindApplication()方法去初始化Application,又是一次跨进程调用2、通过makeActive方法赋值IApplicationThread3、通过ATMS去启动目标Activity*/GuardedBy(this)private boolean attachApplicationLocked(NonNull IApplicationThread thread,int pid, int callingUid, long startSeq) {// Find the application record that is being attached... either via// the pid if we are running in multiple processes, or just pull the// next app record if we are emulating process with anonymous threads.ProcessRecord app;long startTime SystemClock.uptimeMillis();long bindApplicationTimeMillis;if (pid ! MY_PID pid 0) {synchronized (mPidsSelfLocked) {app mPidsSelfLocked.get(pid);}if (app ! null (app.getStartUid() ! callingUid || app.getStartSeq() ! startSeq)) {String processName null;final ProcessRecord pending mProcessList.mPendingStarts.get(startSeq);if (pending ! null) {processName pending.processName;}final String msg attachApplicationLocked process: processName startSeq: startSeq pid: pid belongs to another existing app: app.processName startSeq: app.getStartSeq();Slog.wtf(TAG, msg);// SafetyNet logging for b/131105245.EventLog.writeEvent(0x534e4554, 131105245, app.getStartUid(), msg);// If there is already an app occupying that pid that hasnt been cleaned upcleanUpApplicationRecordLocked(app, pid, false, false, -1,true /*replacingPid*/, false /* fromBinderDied */);removePidLocked(pid, app);app null;}} else {app null;}// Its possible that process called attachApplication before we got a chance to// update the internal state.if (app null startSeq 0) {final ProcessRecord pending mProcessList.mPendingStarts.get(startSeq);if (pending ! null pending.getStartUid() callingUid pending.getStartSeq() startSeq mProcessList.handleProcessStartedLocked(pending, pid,pending.isUsingWrapper(), startSeq, true)) {app pending;}}if (app null) {Slog.w(TAG, No pending application record for pid pid (IApplicationThread thread ); dropping process);EventLogTags.writeAmDropProcess(pid);if (pid 0 pid ! MY_PID) {killProcessQuiet(pid);//TODO: killProcessGroup(app.info.uid, pid);// We cant log the app kill info for this process since we dont// know who it is, so just skip the logging.} else {try {thread.scheduleExit();} catch (Exception e) {// Ignore exceptions.}}return false;}// If this application record is still attached to a previous// process, clean it up now.if (app.getThread() ! null) {handleAppDiedLocked(app, pid, true, true, false /* fromBinderDied */);}// Tell the process all about itself.if (DEBUG_ALL) Slog.v(TAG, Binding process pid pid to record app);final String processName app.processName;try {AppDeathRecipient adr new AppDeathRecipient(app, pid, thread);thread.asBinder().linkToDeath(adr, 0);app.setDeathRecipient(adr);} catch (RemoteException e) {app.resetPackageList(mProcessStats);mProcessList.startProcessLocked(app,new HostingRecord(link fail, processName),ZYGOTE_POLICY_FLAG_EMPTY);return false;}EventLogTags.writeAmProcBound(app.userId, pid, app.processName);synchronized (mProcLock) {app.mState.setCurAdj(ProcessList.INVALID_ADJ);app.mState.setSetAdj(ProcessList.INVALID_ADJ);app.mState.setVerifiedAdj(ProcessList.INVALID_ADJ);mOomAdjuster.setAttachingSchedGroupLSP(app);app.mState.setForcingToImportant(null);updateProcessForegroundLocked(app, false, 0, false);app.mState.setHasShownUi(false);app.mState.setCached(false);app.setDebugging(false);app.setKilledByAm(false);app.setKilled(false);// We carefully use the same state that PackageManager uses for// filtering, since we use this flag to decide if we need to install// providers when user is unlocked laterapp.setUnlocked(StorageManager.isUserKeyUnlocked(app.userId));}mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);boolean normalMode mProcessesReady || isAllowedWhileBooting(app.info);ListProviderInfo providers normalMode? mCpHelper.generateApplicationProvidersLocked(app): null;if (providers ! null mCpHelper.checkAppInLaunchingProvidersLocked(app)) {Message msg mHandler.obtainMessage(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG);msg.obj app;mHandler.sendMessageDelayed(msg,ContentResolver.CONTENT_PROVIDER_PUBLISH_TIMEOUT_MILLIS);}checkTime(startTime, attachApplicationLocked: before bindApplication);if (!normalMode) {Slog.i(TAG, Launching preboot mode app: app);}if (DEBUG_ALL) Slog.v(TAG, New app record app thread thread.asBinder() pid pid);final BackupRecord backupTarget mBackupTargets.get(app.userId);try {int testMode ApplicationThreadConstants.DEBUG_OFF;if (mDebugApp ! null mDebugApp.equals(processName)) {testMode mWaitForDebugger? ApplicationThreadConstants.DEBUG_WAIT: ApplicationThreadConstants.DEBUG_ON;app.setDebugging(true);if (mDebugTransient) {mDebugApp mOrigDebugApp;mWaitForDebugger mOrigWaitForDebugger;}}boolean enableTrackAllocation false;synchronized (mProcLock) {if (mTrackAllocationApp ! null mTrackAllocationApp.equals(processName)) {enableTrackAllocation true;mTrackAllocationApp null;}}// If the app is being launched for restore or full backup, set it up speciallyboolean isRestrictedBackupMode false;if (backupTarget ! null backupTarget.appInfo.packageName.equals(processName)) {isRestrictedBackupMode backupTarget.appInfo.uid FIRST_APPLICATION_UID ((backupTarget.backupMode BackupRecord.RESTORE)|| (backupTarget.backupMode BackupRecord.RESTORE_FULL)|| (backupTarget.backupMode BackupRecord.BACKUP_FULL));}final ActiveInstrumentation instr app.getActiveInstrumentation();if (instr ! null) {notifyPackageUse(instr.mClass.getPackageName(),PackageManager.NOTIFY_PACKAGE_USE_INSTRUMENTATION);}ProtoLog.v(WM_DEBUG_CONFIGURATION, Binding proc %s with config %s,processName, app.getWindowProcessController().getConfiguration());ApplicationInfo appInfo instr ! null ? instr.mTargetInfo : app.info;app.setCompat(compatibilityInfoForPackage(appInfo));ProfilerInfo profilerInfo mAppProfiler.setupProfilerInfoLocked(thread, app, instr);// We deprecated Build.SERIAL and it is not accessible to// Instant Apps and target APIs higher than O MR1. Since access to the serial// is now behind a permission we push down the value.final String buildSerial (!appInfo.isInstantApp() appInfo.targetSdkVersion Build.VERSION_CODES.P)? sTheRealBuildSerial : Build.UNKNOWN;// Figure out whether the app needs to run in autofill compat mode.AutofillOptions autofillOptions null;if (UserHandle.getAppId(app.info.uid) Process.FIRST_APPLICATION_UID) {final AutofillManagerInternal afm LocalServices.getService(AutofillManagerInternal.class);if (afm ! null) {autofillOptions afm.getAutofillOptions(app.info.packageName, app.info.longVersionCode, app.userId);}}ContentCaptureOptions contentCaptureOptions null;if (UserHandle.getAppId(app.info.uid) Process.FIRST_APPLICATION_UID) {final ContentCaptureManagerInternal ccm LocalServices.getService(ContentCaptureManagerInternal.class);if (ccm ! null) {contentCaptureOptions ccm.getOptionsForPackage(app.userId,app.info.packageName);}}SharedMemory serializedSystemFontMap null;final FontManagerInternal fm LocalServices.getService(FontManagerInternal.class);if (fm ! null) {serializedSystemFontMap fm.getSerializedSystemFontMap();}checkTime(startTime, attachApplicationLocked: immediately before bindApplication);bindApplicationTimeMillis SystemClock.elapsedRealtime();mAtmInternal.preBindApplication(app.getWindowProcessController());final ActiveInstrumentation instr2 app.getActiveInstrumentation();if (mPlatformCompat ! null) {mPlatformCompat.resetReporting(app.info);}final ProviderInfoList providerList ProviderInfoList.fromList(providers);if (app.getIsolatedEntryPoint() ! null) {// This is an isolated process which should just call an entry point instead of// being bound to an application.thread.runIsolatedEntryPoint(app.getIsolatedEntryPoint(), app.getIsolatedEntryPointArgs());} else if (instr2 ! null) {//IPC操作调用ApplicationThread的bindapplication去初始化Applicationthread.bindApplication(processName, appInfo, providerList,instr2.mClass,profilerInfo, instr2.mArguments,instr2.mWatcher,instr2.mUiAutomationConnection, testMode,mBinderTransactionTrackingEnabled, enableTrackAllocation,isRestrictedBackupMode || !normalMode, app.isPersistent(),new Configuration(app.getWindowProcessController().getConfiguration()),app.getCompat(), getCommonServicesLocked(app.isolated),mCoreSettingsObserver.getCoreSettingsLocked(),buildSerial, autofillOptions, contentCaptureOptions,app.getDisabledCompatChanges(), serializedSystemFontMap);} else {thread.bindApplication(processName, appInfo, providerList, null, profilerInfo,null, null, null, testMode,mBinderTransactionTrackingEnabled, enableTrackAllocation,isRestrictedBackupMode || !normalMode, app.isPersistent(),new Configuration(app.getWindowProcessController().getConfiguration()),app.getCompat(), getCommonServicesLocked(app.isolated),mCoreSettingsObserver.getCoreSettingsLocked(),buildSerial, autofillOptions, contentCaptureOptions,app.getDisabledCompatChanges(), serializedSystemFontMap);}if (profilerInfo ! null) {profilerInfo.closeFd();profilerInfo null;}// Make app active after binding application or client may be running requests (e.g// starting activities) before it is ready.synchronized (mProcLock) {//赋值IApplicationThreadapp.makeActive(thread, mProcessStats);checkTime(startTime, attachApplicationLocked: immediately after bindApplication);}updateLruProcessLocked(app, false, null);checkTime(startTime, attachApplicationLocked: after updateLruProcessLocked);final long now SystemClock.uptimeMillis();synchronized (mAppProfiler.mProfilerLock) {app.mProfile.setLastRequestedGc(now);app.mProfile.setLastLowMemory(now);}} catch (Exception e) {// We need kill the process group here. (b/148588589)Slog.wtf(TAG, Exception thrown during bind of app, e);app.resetPackageList(mProcessStats);app.unlinkDeathRecipient();app.killLocked(error during bind, ApplicationExitInfo.REASON_INITIALIZATION_FAILURE,true);handleAppDiedLocked(app, pid, false, true, false /* fromBinderDied */);return false;}// Remove this record from the list of starting applications.mPersistentStartingProcesses.remove(app);if (DEBUG_PROCESSES mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,Attach application locked removing on hold: app);mProcessesOnHold.remove(app);boolean badApp false;boolean didSomething false;// See if the top visible activity is waiting to run in this process...if (normalMode) {try {//通过ATMS去启动ActivitydidSomething mAtmInternal.attachApplication(app.getWindowProcessController());} catch (Exception e) {Slog.wtf(TAG, Exception thrown launching activities in app, e);badApp true;}}// Find any services that should be running in this process...if (!badApp) {try {didSomething | mServices.attachApplicationLocked(app, processName);checkTime(startTime, attachApplicationLocked: after mServices.attachApplicationLocked);} catch (Exception e) {Slog.wtf(TAG, Exception thrown starting services in app, e);badApp true;}}// Check if a next-broadcast receiver is in this process...if (!badApp isPendingBroadcastProcessLocked(pid)) {try {didSomething | sendPendingBroadcastsLocked(app);checkTime(startTime, attachApplicationLocked: after sendPendingBroadcastsLocked);} catch (Exception e) {// If the app died trying to launch the receiver we declare it badSlog.wtf(TAG, Exception thrown dispatching broadcasts in app, e);badApp true;}}// Check whether the next backup agent is in this process...if (!badApp backupTarget ! null backupTarget.app app) {if (DEBUG_BACKUP) Slog.v(TAG_BACKUP,New app is backup target, launching agent for app);notifyPackageUse(backupTarget.appInfo.packageName,PackageManager.NOTIFY_PACKAGE_USE_BACKUP);try {thread.scheduleCreateBackupAgent(backupTarget.appInfo,compatibilityInfoForPackage(backupTarget.appInfo),backupTarget.backupMode, backupTarget.userId, backupTarget.operationType);} catch (Exception e) {Slog.wtf(TAG, Exception thrown creating backup agent in app, e);badApp true;}}if (badApp) {app.killLocked(error during init, ApplicationExitInfo.REASON_INITIALIZATION_FAILURE,true);handleAppDiedLocked(app, pid, false, true, false /* fromBinderDied */);return false;}if (!didSomething) {updateOomAdjLocked(app, OomAdjuster.OOM_ADJ_REASON_PROCESS_BEGIN);checkTime(startTime, attachApplicationLocked: after updateOomAdjLocked);}FrameworkStatsLog.write(FrameworkStatsLog.PROCESS_START_TIME,app.info.uid,pid,app.info.packageName,FrameworkStatsLog.PROCESS_START_TIME__TYPE__COLD,app.getStartTime(),(int) (bindApplicationTimeMillis - app.getStartTime()),(int) (SystemClock.elapsedRealtime() - app.getStartTime()),app.getHostingRecord().getType(),(app.getHostingRecord().getName() ! null ? app.getHostingRecord().getName() : ));return true;}
在attachApplicationLocked方法中主要做了三件事 1、调用IApplicationThread的bindApplication方法IPC操作创建绑定Application 2、通过makeActive方法赋值IApplicationThread 3、通过ATMS启动根Activity 先看makeActive方法 GuardedBy({mService, mProcLock})public void makeActive(IApplicationThread thread, ProcessStatsService tracker) {mProfile.onProcessActive(thread, tracker);mThread thread;mWindowProcessController.setThread(thread);}可以看到使用 mWindowProcessController.setThread(thread)确实完成了IApplicationThread的赋值。这样就可以依据IApplicationThread是否为空判断进程是否存在。 再看创建绑定Application的过程IApplicationThread的bindApplication方法实现客户端ApplicationThread的bindApplication方法它有使用H转移到了ActivityThread的handleBindApplication方法。 /*该函数主要做了三件事1、创建Instrumentation2、使用loadedApk创建一个application不过最终还是使用的Instrumentation利用反射创建的Application类3、使用Instrumentation初始化Application**/UnsupportedAppUsageprivate void handleBindApplication(AppBindData data) {// Register the UI Thread as a sensitive thread to the runtime.VMRuntime.registerSensitiveThread();// In the case the stack depth property exists, pass it down to the runtime.String property SystemProperties.get(debug.allocTracker.stackDepth);if (property.length() ! 0) {VMDebug.setAllocTrackerStackDepth(Integer.parseInt(property));}if (data.trackAllocation) {DdmVmInternal.setRecentAllocationsTrackingEnabled(true);}// Note when this process has started.Process.setStartTimes(SystemClock.elapsedRealtime(), SystemClock.uptimeMillis());AppCompatCallbacks.install(data.disabledCompatChanges);// Let libcore handle any compat changes after installing the list of compat changes.AppSpecializationHooks.handleCompatChangesBeforeBindingApplication();mBoundApplication data;mConfigurationController.setConfiguration(data.config);mConfigurationController.setCompatConfiguration(data.config);mConfiguration mConfigurationController.getConfiguration();mProfiler new Profiler();String agent null;if (data.initProfilerInfo ! null) {mProfiler.profileFile data.initProfilerInfo.profileFile;mProfiler.profileFd data.initProfilerInfo.profileFd;mProfiler.samplingInterval data.initProfilerInfo.samplingInterval;mProfiler.autoStopProfiler data.initProfilerInfo.autoStopProfiler;mProfiler.streamingOutput data.initProfilerInfo.streamingOutput;if (data.initProfilerInfo.attachAgentDuringBind) {agent data.initProfilerInfo.agent;}}// send up app name; do this *before* waiting for debugger//发送应用程序名称在等待调试器之前执行此操作Process.setArgV0(data.processName);android.ddm.DdmHandleAppName.setAppName(data.processName,data.appInfo.packageName,UserHandle.myUserId());VMRuntime.setProcessPackageName(data.appInfo.packageName);// Pass data directory path to ART. This is used for caching information and// should be set before any application code is loaded.VMRuntime.setProcessDataDirectory(data.appInfo.dataDir);if (mProfiler.profileFd ! null) {mProfiler.startProfiling();}// If the app is Honeycomb MR1 or earlier, switch its AsyncTask// implementation to use the pool executor. Normally, we use the// serialized executor as the default. This has to happen in the// main thread so the main looper is set right.if (data.appInfo.targetSdkVersion android.os.Build.VERSION_CODES.HONEYCOMB_MR1) {AsyncTask.setDefaultExecutor(AsyncTask.THREAD_POOL_EXECUTOR);}// Let the util.*Array classes maintain undefined for apps targeting Pie or earlier.UtilConfig.setThrowExceptionForUpperArrayOutOfBounds(data.appInfo.targetSdkVersion Build.VERSION_CODES.Q);Message.updateCheckRecycle(data.appInfo.targetSdkVersion);// Supply the targetSdkVersion to the UI rendering module, which may// need it in cases where it does not have access to the appInfo.android.graphics.Compatibility.setTargetSdkVersion(data.appInfo.targetSdkVersion);/** Before spawning a new process, reset the time zone to be the system time zone.* This needs to be done because the system time zone could have changed after the* the spawning of this process. Without doing this this process would have the incorrect* system time zone.*/TimeZone.setDefault(null);/** Set the LocaleList. This may change once we create the App Context.*/LocaleList.setDefault(data.config.getLocales());if (Typeface.ENABLE_LAZY_TYPEFACE_INITIALIZATION) {try {Typeface.setSystemFontMap(data.mSerializedSystemFontMap);} catch (IOException | ErrnoException e) {Slog.e(TAG, Failed to parse serialized system font map);Typeface.loadPreinstalledSystemFontMap();}}synchronized (mResourcesManager) {/** Update the system configuration since its preloaded and might not* reflect configuration changes. The configuration object passed* in AppBindData can be safely assumed to be up to date*/mResourcesManager.applyConfigurationToResources(data.config, data.compatInfo);mCurDefaultDisplayDpi data.config.densityDpi;// This calls mResourcesManager so keep it within the synchronized block.mConfigurationController.applyCompatConfiguration();}data.info getPackageInfoNoCheck(data.appInfo, data.compatInfo);if (agent ! null) {handleAttachAgent(agent, data.info);}/*** Switch this process to density compatibility mode if needed.*/if ((data.appInfo.flagsApplicationInfo.FLAG_SUPPORTS_SCREEN_DENSITIES) 0) {mDensityCompatMode true;Bitmap.setDefaultDensity(DisplayMetrics.DENSITY_DEFAULT);}mConfigurationController.updateDefaultDensity(data.config.densityDpi);// mCoreSettings is only updated from the main thread, while this function is only called// from main thread as well, so no need to lock here.final String use24HourSetting mCoreSettings.getString(Settings.System.TIME_12_24);Boolean is24Hr null;if (use24HourSetting ! null) {is24Hr 24.equals(use24HourSetting) ? Boolean.TRUE : Boolean.FALSE;}// null : use locale default for 12/24 hour formatting,// false : use 12 hour format,// true : use 24 hour format.DateFormat.set24HourTimePref(is24Hr);updateDebugViewAttributeState();StrictMode.initThreadDefaults(data.appInfo);StrictMode.initVmDefaults(data.appInfo);if (data.debugMode ! ApplicationThreadConstants.DEBUG_OFF) {// XXX should have option to change the port.Debug.changeDebugPort(8100);if (data.debugMode ApplicationThreadConstants.DEBUG_WAIT) {Slog.w(TAG, Application data.info.getPackageName() is waiting for the debugger on port 8100...);IActivityManager mgr ActivityManager.getService();try {mgr.showWaitingForDebugger(mAppThread, true);} catch (RemoteException ex) {throw ex.rethrowFromSystemServer();}Debug.waitForDebugger();try {mgr.showWaitingForDebugger(mAppThread, false);} catch (RemoteException ex) {throw ex.rethrowFromSystemServer();}} else {Slog.w(TAG, Application data.info.getPackageName() can be debugged on port 8100...);}}// Allow binder tracing, and application-generated systrace messages if were profileable.boolean isAppDebuggable (data.appInfo.flags ApplicationInfo.FLAG_DEBUGGABLE) ! 0;boolean isAppProfileable isAppDebuggable || data.appInfo.isProfileable();Trace.setAppTracingAllowed(isAppProfileable);if ((isAppProfileable || Build.IS_DEBUGGABLE) data.enableBinderTracking) {Binder.enableTracing();}// Initialize heap profiling.if (isAppProfileable || Build.IS_DEBUGGABLE) {nInitZygoteChildHeapProfiling();}// Allow renderer debugging features if were debuggable.HardwareRenderer.setDebuggingEnabled(isAppDebuggable || Build.IS_DEBUGGABLE);HardwareRenderer.setPackageName(data.appInfo.packageName);// Pass the current context to HardwareRendererHardwareRenderer.setContextForInit(getSystemContext());// Instrumentation info affects the class loader, so load it before// setting up the app context.final InstrumentationInfo ii;if (data.instrumentationName ! null) {ii prepareInstrumentation(data);} else {ii null;}final ContextImpl appContext ContextImpl.createAppContext(this, data.info);mConfigurationController.updateLocaleListFromAppContext(appContext);// Initialize the default http proxy in this process.Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, Setup proxies);try {// In pre-boot mode (doing initial launch to collect password), not all system is up.// This includes the connectivity service, so trying to obtain ConnectivityManager at// that point would return null. Check whether the ConnectivityService is available, and// avoid crashing with a NullPointerException if it is not.final IBinder b ServiceManager.getService(Context.CONNECTIVITY_SERVICE);if (b ! null) {final ConnectivityManager cm appContext.getSystemService(ConnectivityManager.class);Proxy.setHttpProxyConfiguration(cm.getDefaultProxy());}} finally {Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);}if (!Process.isIsolated()) {final int oldMask StrictMode.allowThreadDiskWritesMask();try {setupGraphicsSupport(appContext);} finally {StrictMode.setThreadPolicyMask(oldMask);}} else {HardwareRenderer.setIsolatedProcess(true);}// Install the Network Security Config Provider. This must happen before the application// code is loaded to prevent issues with instances of TLS objects being created before// the provider is installed.Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, NetworkSecurityConfigProvider.install);NetworkSecurityConfigProvider.install(appContext);Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);// Continue loading instrumentation.if (ii ! null) {initInstrumentation(ii, data, appContext);} else {mInstrumentation new Instrumentation();mInstrumentation.basicInit(this);}if ((data.appInfo.flagsApplicationInfo.FLAG_LARGE_HEAP) ! 0) {dalvik.system.VMRuntime.getRuntime().clearGrowthLimit();} else {// Small heap, clamp to the current growth limit and let the heap release// pages after the growth limit to the non growth limit capacity. b/18387825dalvik.system.VMRuntime.getRuntime().clampGrowthLimit();}// Allow disk access during application and provider setup. This could// block processing ordered broadcasts, but later processing would// probably end up doing the same disk access.Application app;final StrictMode.ThreadPolicy savedPolicy StrictMode.allowThreadDiskWrites();final StrictMode.ThreadPolicy writesAllowedPolicy StrictMode.getThreadPolicy();try {// If the app is being launched for full backup or restore, bring it up in// a restricted environment with the base application class.//创建applicationapp data.info.makeApplication(data.restrictedBackupMode, null);// Propagate autofill compat stateapp.setAutofillOptions(data.autofillOptions);// Propagate Content Capture optionsapp.setContentCaptureOptions(data.contentCaptureOptions);sendMessage(H.SET_CONTENT_CAPTURE_OPTIONS_CALLBACK, data.appInfo.packageName);mInitialApplication app;final boolean updateHttpProxy;synchronized (this) {updateHttpProxy mUpdateHttpProxyOnBind;// This synchronized block ensures that any subsequent call to updateHttpProxy()// will see a non-null mInitialApplication.}if (updateHttpProxy) {ActivityThread.updateHttpProxy(app);}// dont bring up providers in restricted mode; they may depend on the// apps custom Application classif (!data.restrictedBackupMode) {if (!ArrayUtils.isEmpty(data.providers)) {installContentProviders(app, data.providers);}}// Do this after providers, since instrumentation tests generally start their// test thread at this point, and we dont want that racing.try {mInstrumentation.onCreate(data.instrumentationArgs);} catch (Exception e) {throw new RuntimeException(Exception thrown in onCreate() of data.instrumentationName : e.toString(), e);}try {//调用application的onCreate方法mInstrumentation.callApplicationOnCreate(app);} catch (Exception e) {if (!mInstrumentation.onException(app, e)) {throw new RuntimeException(Unable to create application app.getClass().getName() : e.toString(), e);}}} finally {// If the app targets O-MR1, or doesnt change the thread policy// during startup, clobber the policy to maintain behavior of b/36951662if (data.appInfo.targetSdkVersion Build.VERSION_CODES.O_MR1|| StrictMode.getThreadPolicy().equals(writesAllowedPolicy)) {StrictMode.setThreadPolicy(savedPolicy);}}// Preload fonts resourcesFontsContract.setApplicationContextForResources(appContext);if (!Process.isIsolated()) {try {final ApplicationInfo info getPackageManager().getApplicationInfo(data.appInfo.packageName,PackageManager.GET_META_DATA /*flags*/,UserHandle.myUserId());if (info.metaData ! null) {final int preloadedFontsResource info.metaData.getInt(ApplicationInfo.METADATA_PRELOADED_FONTS, 0);if (preloadedFontsResource ! 0) {data.info.getResources().preloadFonts(preloadedFontsResource);}}} catch (RemoteException e) {throw e.rethrowFromSystemServer();}}}
主要就是创建Application,并且调用生命周期onCreate方法。发现在前面介绍的ActivityThread的performLaunchActivity方法中也有同样的操作只不过会先判断Application是否已存在。也就是说。正常情况下Application的初始化是在handleBindApplication方法中并且是创建进程后调用的。performLaunchActivity中只有一个i安策异常情况Application不存在时才会创建 创建Application后内部会attach方法attach内部会调用attachBaseContext方法atttachBaseContext方法时我们接触到的一个方法接着才是onCreate方法 再来看根Activity的启动回到上面的AMS的attachApplicationLocked方法调用了mAtmInternal.attachApplication方法mAtmInternal是ActivityTaskManagerInternal实例具体实现是在ActivityTaskManagerService的内部类LocalService HotPath(caller HotPath.PROCESS_CHANGE)Overridepublic boolean attachApplication(WindowProcessController wpc) throws RemoteException {synchronized (mGlobalLockWithoutBoost) {if (Trace.isTagEnabled(TRACE_TAG_WINDOW_MANAGER)) {Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, attachApplication: wpc.mName);}try {return mRootWindowContainer.attachApplication(wpc);} finally {Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);}}}mRootWindowContainer是RootWindowContainer的实例看下它的attachApplication方法boolean attachApplication(WindowProcessController app) throws RemoteException {boolean didSomething false;for (int displayNdx getChildCount() - 1; displayNdx 0; --displayNdx) {mTmpRemoteException null;mTmpBoolean false; // Set to true if an activity was started.final DisplayContent display getChildAt(displayNdx);display.forAllRootTasks(rootTask - {if (mTmpRemoteException ! null) {return;}if (rootTask.getVisibility(null /* starting */) TASK_FRAGMENT_VISIBILITY_INVISIBLE) {return;}final PooledFunction c PooledLambda.obtainFunction(RootWindowContainer::startActivityForAttachedApplicationIfNeeded, this,PooledLambda.__(ActivityRecord.class), app,rootTask.topRunningActivity());rootTask.forAllActivities(c);c.recycle();});if (mTmpRemoteException ! null) {throw mTmpRemoteException;}didSomething | mTmpBoolean;}if (!didSomething) {ensureActivitiesVisible(null, 0, false /* preserve_windows */);}return didSomething;}遍历activity栈此时理论上应该只有一个根Activity然后调用mStackSupervisor.realStartActivityLocked方法。 我们发现根Activity在启动前需要创建应用进程然后走到ActivityThread的main方法开启主线程循环初始化并绑定Application赋值IApplicationThread,最后真正的启动过程和普通Activity是一致的。
下面是Activity 的启动流程图