关于Activity的源码分析拖延了太久的时间,由于最近工作繁忙,加上Activity启动源码非常复杂,涉及的内容很多,所以花费了很长是时间才来写这篇源码分析,希望这篇分析能让我们很容易的理解Activity的启动流程,能解决我们在使用Activity过程中遇到的问题,这样就达到了我们对于源码分析的目的了。下一篇我们介绍Activity的finish过程。
Activity启动模式简介: 我们知道Activity启动模式有四种,每一种都有不同的操作,直接影响我们App的设计,为了帮助我们理解源码,我们先分析一下这四种模式。这四种模式包括:standard, singleTop, singleTask 和 singleInstance。
(下面内容来自:Activity启动模式图文详解:standard, singleTop, singleTask 以及 singleInstance )
standard :标准模式,也是默认模式。这种模式是每次你调用startActivity时都会创建一个Activity实例,不管你之前有没有创建过。
singleTop :从名字可以分析出是顶部单例,也就是如果你要启动的Activity在任务栈的顶部,则不会在创建新的Activity实例,而是调用Activity的onNewIntent方法,如果你要启动的Activity不存在或者存在但是不在任务栈的栈顶,那么也会创建新的Activity实例并且放置到栈顶位置。因此如果你需要处理Intent中的参数,那么需要在onCreate方法和onNewIntent方法中都要处理。
singleTask :从名字看是单例模式,这个单例不是栈单例,而是系统单例,也就是如果系统中存在了该Activity,那么在调用startActivity时并不会重新创建一个Activity,而是将持有这个Activity的任务移动到顶部位置,并且调用onNewIntent方法,同时在这个栈中的该Activity上面的Activity都会被弹出栈并且被销毁,如果系统中不存在则会创建新的Activity,并且将这个Activity放置到一个新的任务栈中的底部(root)位置。
但是,同一个应用中,我们正常使用中同一个应用中的Activity启动却不是这样,启动的具有该属性的Activity会被放到栈的顶部,而不是放到root(底部)位置,如果需要像上面描述一样放到root位置,那么需要在AndroidManifest文件中配置Activity时添加taskAffinity 属性,例如:
1 2 3 4 5 <activity android:name =".SingleTaskActivity" android:label ="singleTask launchMode" android:launchMode ="singleTask" android:taskAffinity ="" >
在不同的应用启动Activity,如果两个应用启动具有该属性的Activity就会创建一个新的任务,并且将该Activity放置到该任务的底部位置。除非用该属性的Activity所在的应用已经存在了,新创建该属性Activity后会将其放置到顶部位置。如果在其他的任务中存在了该属性的Activity,整个任务都会被移到顶部位置,并且该Activity上面的所有Activity都会被销毁,用户需要按back键遍历栈中的Activity才能回到调用者。
singleInstance :单例模式,这个模式和singleTask很相似,不同的是:持有这个Activity的任务只有一个Activity,即这个单例本身。如果这个Activity启动另一个Activity的时候会自动创建一个任务栈,并且将新启动的Activity放到该新创建的任务栈中。不过结果很怪异,当具有该模式的Activity启动另一个Activity或者另一个Activity启动具有该模式的Activity时本来需要创建一个新的任务,但是任务管理中只显示了一个(最后被移到顶部的那个),导致后台只显示一个,我们不能切换到之前的任务中。如果想切换唯一办法就是回到Launcher重新点击应用,但是显示另个一任务后,第一个任务就会被隐藏了。也就是切换后还是只能显示一个任务。如果想要解决仍然需要设置taskAffinity 属性,例如:
1 2 3 4 5 <activity android:name =".SingleTaskActivity" android:label ="singleTask launchMode" android:launchMode ="singleTask" android:taskAffinity ="" >
这样就正常了,这种模式很少使用,除非想Launcher这种只有一个Activity,或者100%确定只有一个Activity。
Activity源码解析 要了解Activity启动的过程不仅要知道代码流程,也要知道设计流程,我们先看代码流程,分析完成后我们再重新看一下设计流程,来帮助我们记忆源码流程。因为篇幅比较长,我们下面分为两个部分分析。
第一部分:
Step1.startActivityForResult: Activity的启动一般有了两种方式,一种是需要返回结果的,一种是不需要返回结果的。这里的函数和我们上面时序图中的不一样,其实最终调用的方法是这个,另外还有几个参数不同的方法,其实是一样的,我们看最终调用代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 public void startActivityForResult (@RequiresPermission Intent intent, int requestCode, @Nullable Bundle options) { if (mParent == null ) { ... Instrumentation.ActivityResult ar = mInstrumentation.execStartActivity( this , mMainThread.getApplicationThread(), mToken, this , intent, requestCode, options); if (ar != null ) { mMainThread.sendActivityResult( mToken, mEmbeddedID, requestCode, ar.getResultCode(), ar.getResultData()); } ... } else { ... } }
直接启动时参数requestCode为-1,这里执行调用Instrumentation.execStartActivity方法,后面执行ActivityThread.sendActivityResult返回结果,这个方法我们后面会分析,这里不再分析,我们先看启动的方法:
Step2.Instrumentation.execStartActivity 1 2 3 4 5 6 7 8 9 10 11 12 13 14 public ActivityResult execStartActivity ( Context who, IBinder contextThread, IBinder token, Activity target, Intent intent, int requestCode, Bundle options) { ... int result = ActivityManagerNative.getDefault() .startActivity(whoThread, who.getBasePackageName(), intent, intent.resolveTypeIfNeeded(who.getContentResolver()), token, target != null ? target.mEmbeddedID : null , requestCode, 0 , null , options); ... return null ; }
这个方法传入有个参数target,从上面代码可知传入的是this,也就是调用启动Activity方法的Activity,我们称之为调用者或者源Activity。这里主要是调用startActivity方法,这里的ActivityManagerNative.getDefault()我们在前面的文字介绍过是ActivityManagerProxy。
Step3.ActivityManagerProxy.startActivity 1 2 3 4 5 6 7 8 9 public int startActivity (IApplicationThread caller, String callingPackage, Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, int startFlags, ProfilerInfo profilerInfo, Bundle options) throws RemoteException { ... mRemote.transact(START_ACTIVITY_TRANSACTION, data, reply, 0 ); ... return result; }
最终调用AMS(ActivityManagerService)的startActivity方法。
Step4.AMS.startActivity 1 2 3 4 5 6 7 public final int startActivity (IApplicationThread caller, String callingPackage, Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, int startFlags, ProfilerInfo profilerInfo, Bundle bOptions) { return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo, resultWho, requestCode, startFlags, profilerInfo, bOptions, UserHandle.getCallingUserId()); }
然后调用startActivityAsUser方法。
Step5.AMS.startActivityAsUser 1 2 3 4 5 6 7 8 9 public final int startActivityAsUser (IApplicationThread caller, String callingPackage, Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) { ... return mActivityStarter.startActivityMayWait(caller, -1 , callingPackage, intent, resolvedType, null , null , resultTo, resultWho, requestCode, startFlags, profilerInfo, null , null , bOptions, false , userId, null , null ); }
调用ActivityStarter.startActivityMayWait方法。
Step6.ActivityStarter.startActivityMayWait 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 final int startActivityMayWait (IApplicationThread caller, int callingUid, String callingPackage, Intent intent, String resolvedType, IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor, IBinder resultTo, String resultWho, int requestCode, int startFlags, ProfilerInfo profilerInfo, IActivityManager.WaitResult outResult, Configuration config, Bundle bOptions, boolean ignoreTargetSecurity, int userId, IActivityContainer iContainer, TaskRecord inTask) { ... boolean componentSpecified = intent.getComponent() != null ; ... ... synchronized (mService) { ... final ActivityRecord[] outRecord = new ActivityRecord [1 ]; int res = startActivityLocked(caller, intent, ephemeralIntent, resolvedType, aInfo, rInfo, voiceSession, voiceInteractor, resultTo, resultWho, requestCode, callingPid, callingUid, callingPackage, realCallingPid, realCallingUid, startFlags, options, ignoreTargetSecurity, componentSpecified, outRecord, container, inTask); ... return res; } }
这里主要是收集Intent的内容,进行判断整理,然后调用startActivityLocked方法。
Step7.startActivityLocked 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 final int startActivityLocked (IApplicationThread caller, Intent intent, Intent ephemeralIntent, String resolvedType, ActivityInfo aInfo, ResolveInfo rInfo, IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor, IBinder resultTo, String resultWho, int requestCode, int callingPid, int callingUid, String callingPackage, int realCallingPid, int realCallingUid, int startFlags, ActivityOptions options, boolean ignoreTargetSecurity, boolean componentSpecified, ActivityRecord[] outActivity, ActivityStackSupervisor.ActivityContainer container, TaskRecord inTask) { int err = ActivityManager.START_SUCCESS; ProcessRecord callerApp = null ; if (caller != null ) { callerApp = mService.getRecordForAppLocked(caller); if (callerApp != null ) { callingPid = callerApp.pid; callingUid = callerApp.info.uid; } else { ... } } ... ActivityRecord sourceRecord = null ; ActivityRecord resultRecord = null ; if (resultTo != null ) { sourceRecord = mSupervisor.isInAnyStackLocked(resultTo); if (sourceRecord != null ) { if (requestCode >= 0 && !sourceRecord.finishing) { resultRecord = sourceRecord; } } } final int launchFlags = intent.getFlags(); if ((launchFlags & Intent.FLAG_ACTIVITY_FORWARD_RESULT) != 0 && sourceRecord != null ) { if (requestCode >= 0 ) { ActivityOptions.abort(options); return ActivityManager.START_FORWARD_AND_REQUEST_CONFLICT; } resultRecord = sourceRecord.resultTo; if (resultRecord != null && !resultRecord.isInStackLocked()) { resultRecord = null ; } ... requestCode = sourceRecord.requestCode; ... if (resultRecord != null ) { resultRecord.removeResultsLocked(sourceRecord, resultWho, requestCode); } ... } ... final ActivityStack resultStack = resultRecord == null ? null : resultRecord.task.stack; if (err != START_SUCCESS) { if (resultRecord != null ) { resultStack.sendActivityResultLocked( -1 , resultRecord, resultWho, requestCode, RESULT_CANCELED, null ); } ActivityOptions.abort(options); return err; } ... if (abort) { if (resultRecord != null ) { resultStack.sendActivityResultLocked(-1 , resultRecord, resultWho, requestCode, RESULT_CANCELED, null ); } ActivityOptions.abort(options); return START_SUCCESS; } ActivityRecord r = new ActivityRecord (mService, callerApp, callingUid, callingPackage, intent, resolvedType, aInfo, mService.mConfiguration, resultRecord, resultWho, requestCode, componentSpecified, voiceSession != null , mSupervisor, container, options, sourceRecord); if (outActivity != null ) { outActivity[0 ] = r; } ... final ActivityStack stack = mSupervisor.mFocusedStack; if (voiceSession == null && (stack.mResumedActivity == null || stack.mResumedActivity.info.applicationInfo.uid != callingUid)) { if (!mService.checkAppSwitchAllowedLocked(callingPid, callingUid, realCallingPid, realCallingUid, "Activity start" )) { PendingActivityLaunch pal = new PendingActivityLaunch (r, sourceRecord, startFlags, stack, callerApp); mPendingActivityLaunches.add(pal); ActivityOptions.abort(options); return ActivityManager.START_SWITCHES_CANCELED; } } if (mService.mDidAppSwitch) { mService.mAppSwitchesAllowedTime = 0 ; } else { mService.mDidAppSwitch = true ; } doPendingActivityLaunchesLocked(false ); try { ... err = startActivityUnchecked(r, sourceRecord, voiceSession, voiceInteractor, startFlags, true , options, inTask); } finally { mService.mWindowManager.continueSurfaceLayout(); } postStartActivityUncheckedProcessing(r, err, stack.mStackId, mSourceRecord, mTargetStack); return err; }
上面代码注释比较详细,有一点我们提一下就是FLAG_ACTIVITY_FORWARD_RESULT标签,也就是我们在开发中遇到的一种情况,ActivityA启动ActivityB,ActivityB启动ActivityC,C返回结果让A接收,我们平时不知道怎么处理,通过上面源码我们看到可以设置这个标签,就可以完成我们需要的操作。
上面我们在启动失败的时候回直接返回结果,中断操作,调用ActivityStack.sendActivityResultLocked方法。
Step8.ActivityStack.sendActivityResultLocked 1 2 3 4 5 6 7 8 9 10 11 12 13 void sendActivityResultLocked (int callingUid, ActivityRecord r, String resultWho, int requestCode, int resultCode, Intent data) { ... if (mResumedActivity == r && r.app != null && r.app.thread != null ) { try { ... r.app.thread.scheduleSendResult(r.appToken, list); return ; } ... } ... }
这里会调用ApplicationThreadProxy.scheduleSendResult方法。
Step9.ApplicationThreadProxy.scheduleSendResult 1 2 3 4 5 6 7 public final void scheduleSendResult (IBinder token, List<ResultInfo> results) throws RemoteException { ... mRemote.transact(SCHEDULE_SEND_RESULT_TRANSACTION, data, null , IBinder.FLAG_ONEWAY); data.recycle(); }
这个我们之前在上一章分析广播的时候讲过的,最终会调用ActivityThread.scheduleSendResult方法。
Step10.ActivityThread.scheduleSendResult 1 2 3 4 public final void scheduleSendResult (IBinder token, List<ResultInfo> results) { ... sendMessage(H.SEND_RESULT, res); }
这里通过Handler发送消息到ActivityThread.H.handleMessage中进行处理。然后调用handleSendResult方法
Step12.ActivityThread.handleSendResult 1 2 3 4 5 6 7 8 9 10 11 12 private void handleSendResult (ResultData res) { ... if (r != null ) { final boolean resumed = !r.paused; ... deliverResults(r, res.results); if (resumed) { r.activity.performResume(); r.activity.mTemporaryPause = false ; } } }
这里调用deliverResults方法分发结果,分发完成如果需要复用的,则调用复用方法,这个我们后面会介绍到。
Step13.ActivityThread.deliverResults 1 2 3 4 5 6 7 8 9 private void deliverResults (ActivityClientRecord r, List<ResultInfo> results) { final int N = results.size(); for (int i = 0 ; i < N; i++) { ... r.activity.dispatchActivityResult(ri.mResultWho, ri.mRequestCode, ri.mResultCode, ri.mData); ... } }
这里调用Activity.dispatchActivityResult方法分发结果。
Step14.Activity.dispatchActivityResult 1 2 3 4 5 6 void dispatchActivityResult (String who, int requestCode, int resultCode, Intent data) { .... onActivityResult(requestCode, resultCode, data); ... }
这里会调用onActivityResult方法,返回结果,其他的情况这里不介绍了,自己分析一下就好了。到此结果返回就完成了,我们接着分析,再回到Step7,这个方法中有几个发送返回结果的调用,其实调用都是一样的,接着我们分析下面的代码,调用doPendingActivityLaunchesLocked方法,后面还有startActivityUnchecked方法和postStartActivityUncheckedProcessing方法,其实这两个方法也是重复调用,也就是doPendingActivityLaunchesLocked里面也调用了这两个方法,因此我们只分析一次就好了。我们从doPendingActivityLaunchesLocked方法开始分析。
Step16.ActivityStarter.doPendingActivityLaunchesLocked 1 2 3 4 5 6 7 8 9 10 11 12 13 final void doPendingActivityLaunchesLocked (boolean doResume) { while (!mPendingActivityLaunches.isEmpty()) { final PendingActivityLaunch pal = mPendingActivityLaunches.remove(0 ); final boolean resume = doResume && mPendingActivityLaunches.isEmpty(); ... final int result = startActivityUnchecked( pal.r, pal.sourceRecord, null , null , pal.startFlags, resume, null , null ); ... } }
这里我们看到了调用了startActivityUnchecked方法和postStartActivityUncheckedProcessing方法,主要的处理都在startActivityUnchecked方法中,所以下面我们主要看startActivityUnchecked方法,这个方法调用结束启动也就结束了。
Step17.ActivityStarter.startActivityUnchecked 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 private int startActivityUnchecked (final ActivityRecord r, ActivityRecord sourceRecord, IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor, int startFlags, boolean doResume, ActivityOptions options, TaskRecord inTask) { setInitialState(r, options, inTask, doResume, startFlags, sourceRecord, voiceSession, voiceInteractor); computeLaunchingTaskFlags(); computeSourceStack(); mIntent.setFlags(mLaunchFlags); mReusedActivity = getReusableIntentActivity(); ... if (mReusedActivity != null ) { ... if (mStartActivity.task == null ) { mStartActivity.task = mReusedActivity.task; } ... if ((mLaunchFlags & FLAG_ACTIVITY_CLEAR_TOP) != 0 || mLaunchSingleInstance || mLaunchSingleTask) { final ActivityRecord top = mReusedActivity.task.performClearTaskForReuseLocked( mStartActivity, mLaunchFlags); if (top != null ) { ... top.deliverNewIntentLocked(mCallingUid, mStartActivity.intent, mStartActivity.launchedFromPackage); } } sendPowerHintForLaunchStartIfNeeded(false ); mReusedActivity = setTargetStackAndMoveToFrontIfNeeded(mReusedActivity); if ((mStartFlags & START_FLAG_ONLY_IF_NEEDED) != 0 ) { resumeTargetStackIfNeeded(); return START_RETURN_INTENT_TO_CALLER; } setTaskFromIntentActivity(mReusedActivity); if (!mAddingToTask && mReuseTask == null ) { resumeTargetStackIfNeeded(); return START_TASK_TO_FRONT; } } if (mStartActivity.packageName == null ) { if (mStartActivity.resultTo != null && mStartActivity.resultTo.task.stack != null ) { mStartActivity.resultTo.task.stack.sendActivityResultLocked( -1 , mStartActivity.resultTo, mStartActivity.resultWho, mStartActivity.requestCode, RESULT_CANCELED, null ); } ActivityOptions.abort(mOptions); return START_CLASS_NOT_FOUND; } final ActivityStack topStack = mSupervisor.mFocusedStack; final ActivityRecord top = topStack.topRunningNonDelayedActivityLocked(mNotTop); ... if (dontStart) { ... topStack.mLastPausedActivity = null ; if (mDoResume) { mSupervisor.resumeFocusedStackTopActivityLocked(); } ... top.deliverNewIntentLocked( mCallingUid, mStartActivity.intent, mStartActivity.launchedFromPackage); ... return START_DELIVERED_TO_TOP; } boolean newTask = false ; final TaskRecord taskToAffiliate = (mLaunchTaskBehind && mSourceRecord != null ) ? mSourceRecord.task : null ; if (mStartActivity.resultTo == null && mInTask == null && !mAddingToTask && (mLaunchFlags & FLAG_ACTIVITY_NEW_TASK) != 0 ) { newTask = true ; setTaskFromReuseOrCreateNewTask(taskToAffiliate); ... } else if (mSourceRecord != null ) { ... final int result = setTaskFromSourceRecord(); ... } else if (mInTask != null ) { ... final int result = setTaskFromInTask(); ... } else { ... setTaskToCurrentTopOrCreateNewTask(); } ... mTargetStack.startActivityLocked(mStartActivity, newTask, mKeepCurTransition, mOptions); if (mDoResume) { if (!mLaunchTaskBehind) { mService.setFocusedActivityLocked(mStartActivity, "startedActivity" ); } final ActivityRecord topTaskActivity = mStartActivity.task.topRunningActivityLocked(); ... mSupervisor.resumeFocusedStackTopActivityLocked(mTargetStack, mStartActivity, mOptions); ... } else { mTargetStack.addRecentActivityLocked(mStartActivity); } mSupervisor.updateUserStackLocked(mStartActivity.userId, mTargetStack); ... return START_SUCCESS; }
Activity的启动最核心的东西就在这个方法中,所以这个方法会很复杂,里面调用了很多方法,每个方法分析都会比较复杂,在这个方法最后返回成功,也就是Activity的启动结束标志。下面我们具体分析每一步的具体内容,让我们彻底了解Activity的启动流程。
Step18.ActivityStarter.setInitialState 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 private void setInitialState (ActivityRecord r, ActivityOptions options, TaskRecord inTask, boolean doResume, int startFlags, ActivityRecord sourceRecord, IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) { reset(); mStartActivity = r; ... mLaunchSingleTop = r.launchMode == LAUNCH_SINGLE_TOP; mLaunchSingleInstance = r.launchMode == LAUNCH_SINGLE_INSTANCE; mLaunchSingleTask = r.launchMode == LAUNCH_SINGLE_TASK; mLaunchFlags = adjustLaunchFlagsToDocumentMode( r, mLaunchSingleInstance, mLaunchSingleTask, mIntent.getFlags()); mLaunchTaskBehind = r.mLaunchTaskBehind && !mLaunchSingleTask && !mLaunchSingleInstance && (mLaunchFlags & FLAG_ACTIVITY_NEW_DOCUMENT) != 0 ; sendNewTaskResultRequestIfNeeded(); ... mSupervisor.mUserLeaving = (mLaunchFlags & FLAG_ACTIVITY_NO_USER_ACTION) == 0 ; ... if (mOptions != null && mOptions.getLaunchTaskId() != -1 && mOptions.getTaskOverlay()) { r.mTaskOverlay = true ; final TaskRecord task = mSupervisor.anyTaskForIdLocked(mOptions.getLaunchTaskId()); final ActivityRecord top = task != null ? task.getTopActivity() : null ; ... } mNotTop = (mLaunchFlags & FLAG_ACTIVITY_PREVIOUS_IS_TOP) != 0 ? r : null ; ... }
这个方法里面主要是数据初始化,判断启动模式,获取启动标签,为启动Activity做准备。
Step19.ActivityStarter.adjustLaunchFlagsToDocumentMode 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 private int adjustLaunchFlagsToDocumentMode (ActivityRecord r, boolean launchSingleInstance, boolean launchSingleTask, int launchFlags) { if ((launchFlags & Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0 && (launchSingleInstance || launchSingleTask)) { launchFlags &= ~(Intent.FLAG_ACTIVITY_NEW_DOCUMENT | FLAG_ACTIVITY_MULTIPLE_TASK); } else { ... } return launchFlags; }
这个方法主要是判断启动标签,这里有个提示,就是如果动态设置的标签和AndroidManifest里面配置的冲突,那么以Manifest文件中为准。
Step20.ActivityStarter.sendNewTaskResultRequestIfNeeded 1 2 3 4 5 6 7 8 9 10 private void sendNewTaskResultRequestIfNeeded () { if (mStartActivity.resultTo != null && (mLaunchFlags & FLAG_ACTIVITY_NEW_TASK) != 0 && mStartActivity.resultTo.task.stack != null ) { ... mStartActivity.resultTo.task.stack.sendActivityResultLocked(-1 , mStartActivity.resultTo, mStartActivity.resultWho, mStartActivity.requestCode, RESULT_CANCELED, null ); ... } }
这里又调用了上面第8步的过程–sendActivityResultLocked方法,这里就不再介绍了,没记住的可以回去看8-14步就可以了。
Step21.ActivityStack.sendActivityResultLocked 1 2 3 4 5 6 7 8 void sendActivityResultLocked (int callingUid, ActivityRecord r, String resultWho, int requestCode, int resultCode, Intent data) { ... r.app.thread.scheduleSendResult(r.appToken, list); ... }
这个过程和上面9-15一样,所以不再讲解。
Step23.ActivityStackSupervisor.anyTaskForIdLocked 调用下面代码。
Step24.ActivityStackSupervisor.anyTaskForIdLocked 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 TaskRecord anyTaskForIdLocked (int id, boolean restoreFromRecents, int stackId) { int numDisplays = mActivityDisplays.size(); for (int displayNdx = 0 ; displayNdx < numDisplays; ++displayNdx) { ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; for (int stackNdx = stacks.size() - 1 ; stackNdx >= 0 ; --stackNdx) { ActivityStack stack = stacks.get(stackNdx); TaskRecord task = stack.taskForIdLocked(id); if (task != null ) { return task; } } } TaskRecord task = mRecentTasks.taskForIdLocked(id); ... return task; }
这个方法主要是根据任务栈id查找所有屏幕显示的任务列表中是否存在该id对应的任务,如果有直接返回,如果没有从最近任务中查找,没有直接返回null,如果有则调用restoreRecentTaskLocked方法存储该任务。
Step25.ActivityStackSupervisor.restoreRecentTaskLocked 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 private boolean restoreRecentTaskLocked (TaskRecord task, int stackId) { if (stackId == INVALID_STACK_ID) { stackId = task.getLaunchStackId(); } else if (stackId == DOCKED_STACK_ID && !task.canGoInDockedStack()) { ... } else if (stackId == FREEFORM_WORKSPACE_STACK_ID && mService.mUserController.shouldConfirmCredentials(task.userId)) { ... } if (task.stack != null ) { if (task.stack.mStackId == stackId) { return true ; } task.stack.removeTask(task, "restoreRecentTaskLocked" , REMOVE_TASK_MODE_MOVING); } ... stack.addTask(task, false , "restoreRecentTask" ); ... return true ; }
Step26.ActivityStack.removeTask 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 void removeTask (TaskRecord task, String reason, int mode) { if (mode == REMOVE_TASK_MODE_DESTROYING) { mStackSupervisor.removeLockedTaskLocked(task); ... } final ActivityRecord r = mResumedActivity; if (r != null && r.task == task) { mResumedActivity = null ; } final int taskNdx = mTaskHistory.indexOf(task); final int topTaskNdx = mTaskHistory.size() - 1 ; if (task.isOverHomeStack() && taskNdx < topTaskNdx) { final TaskRecord nextTask = mTaskHistory.get(taskNdx + 1 ); ... } mTaskHistory.remove(task); updateTaskMovement(task, true ); if (mode == REMOVE_TASK_MODE_DESTROYING && task.mActivities.isEmpty()) { ... if (task.autoRemoveFromRecents() || isVoiceSession) { ... } } if (mTaskHistory.isEmpty()) { ... } task.stack = null ; }
从当前栈中移除传入的任务。
Step27.ActivityStack.addTask 1 2 3 4 5 6 7 8 9 10 11 void addTask (final TaskRecord task, final boolean toTop, String reason) { final ActivityStack prevStack = preAddTask(task, reason, toTop); task.stack = this ; if (toTop) { insertTaskAtTop(task, null ); } else { mTaskHistory.add(0 , task); updateTaskMovement(task, false ); } postAddTask(task, prevStack); }
将任务插入到栈中,这里面有个insertTaskAtTop我们后面再讲。
Step28.ActivityStater.computeLaunchingTaskFlags 这个方法主要是对于mLauncherFlags的处理,这里就不再贴代码。
Step29.ActivityStater.computeSourceStack 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 private void computeSourceStack () { if (mSourceRecord == null ) { mSourceStack = null ; return ; } if (!mSourceRecord.finishing) { mSourceStack = mSourceRecord.task.stack; return ; } ... if ((mLaunchFlags & FLAG_ACTIVITY_NEW_TASK) == 0 ) { Slog.w(TAG, "startActivity called from finishing " + mSourceRecord + "; forcing " + "Intent.FLAG_ACTIVITY_NEW_TASK for: " + mIntent); mLaunchFlags |= FLAG_ACTIVITY_NEW_TASK; mNewTaskInfo = mSourceRecord.info; mNewTaskIntent = mSourceRecord.task.intent; } mSourceRecord = null ; mSourceStack = null ; }
这里主要是获取mSourceStack是否存在。
Step30.ActivityStater.getReusableIntentActivity 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 private ActivityRecord getReusableIntentActivity () { boolean putIntoExistingTask = ((mLaunchFlags & FLAG_ACTIVITY_NEW_TASK) != 0 && (mLaunchFlags & FLAG_ACTIVITY_MULTIPLE_TASK) == 0 ) || mLaunchSingleInstance || mLaunchSingleTask; ... ActivityRecord intentActivity = null ; if (mOptions != null && mOptions.getLaunchTaskId() != -1 ) { final TaskRecord task = mSupervisor.anyTaskForIdLocked(mOptions.getLaunchTaskId()); intentActivity = task != null ? task.getTopActivity() : null ; } else if (putIntoExistingTask) { if (mLaunchSingleInstance) { intentActivity = mSupervisor.findActivityLocked(mIntent, mStartActivity.info, false ); } else if ((mLaunchFlags & FLAG_ACTIVITY_LAUNCH_ADJACENT) != 0 ) { intentActivity = mSupervisor.findActivityLocked(mIntent, mStartActivity.info, !mLaunchSingleTask); } else { intentActivity = mSupervisor.findTaskLocked(mStartActivity); } } return intentActivity; }
这里是获取一个可复用的Activity,可能存在,也可能为null。
Step31.ActivityStackSupervisor.anyTaskForIdLocked 这里方法和上面23一样,所以不在讲解,我们接着看36步。
Step36.ActivityStackSupervisor.findActivityLocked 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 ActivityRecord findActivityLocked (Intent intent, ActivityInfo info, boolean compareIntentFilters) { for (int displayNdx = mActivityDisplays.size() - 1 ; displayNdx >= 0 ; --displayNdx) { final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; for (int stackNdx = stacks.size() - 1 ; stackNdx >= 0 ; --stackNdx) { final ActivityRecord ar = stacks.get(stackNdx) .findActivityLocked(intent, info, compareIntentFilters); if (ar != null ) { return ar; } } } return null ; }
根据for循环来查找对应的Activity。
Step37.ActivityStack.findActivityLocked 1 2 3 4 5 6 7 8 9 10 ActivityRecord findActivityLocked (Intent intent, ActivityInfo info, boolean compareIntentFilters) { ... for (int taskNdx = mTaskHistory.size() - 1 ; taskNdx >= 0 ; --taskNdx) { ... } return null ; }
从栈顶开始,返回第一个与该要启动的Activity相同的Activity,如果没有则返回空
Step38.ActivityStackSupervisor.findTaskLocked 1 2 3 4 5 6 7 8 9 10 11 12 13 14 ActivityRecord findTaskLocked (ActivityRecord r) { ... for (int displayNdx = mActivityDisplays.size() - 1 ; displayNdx >= 0 ; --displayNdx) { final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; for (int stackNdx = stacks.size() - 1 ; stackNdx >= 0 ; --stackNdx) { ... stack.findTaskLocked(r, mTmpFindTaskResult); .. } } if (DEBUG_TASKS && mTmpFindTaskResult.r == null ) Slog.d(TAG_TASKS, "No task found" ); return mTmpFindTaskResult.r; }
这里考虑到了分屏,查找所有屏幕上是否存在对应的Activity。
Step39.ActivityStack.findTaskLocked 这个方法没有太复杂的东西,所以不再贴代码,主要根据传入的参数查找存在该Activity的task。
1 2 3 4 5 ActivityRecord performClearTaskForReuseLocked (ActivityRecord newR, int launchFlags) { ... final ActivityRecord result = performClearTaskLocked(newR, launchFlags); ... }
调用performClearTaskLocked方法:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 final ActivityRecord performClearTaskLocked (ActivityRecord newR, int launchFlags) { int numActivities = mActivities.size(); for (int activityNdx = numActivities - 1 ; activityNdx >= 0 ; --activityNdx) { ActivityRecord r = mActivities.get(activityNdx); if (r.finishing) { continue ; } if (r.realActivity.equals(newR.realActivity)) { final ActivityRecord ret = r; for (++activityNdx; activityNdx < numActivities; ++activityNdx) { r = mActivities.get(activityNdx); if (r.finishing) { continue ; } ... if (stack != null && stack.finishActivityLocked( r, Activity.RESULT_CANCELED, null , "clear-task-stack" , false )) { --activityNdx; --numActivities; } } ... } } return null ; }
这里主要是要清理可复用Activity栈中该Activity顶部的Activity,清理调用ActivityStack.finishActivityLocked方法进行清理,这个方法我们在下一章Activity的finish过程再讲。
Step43.ActivityRecord.deliverNewIntentLocked 1 2 3 4 5 6 7 final void deliverNewIntentLocked (int callingUid, Intent intent, String referrer) { ... app.thread.scheduleNewIntent( ar, appToken, state == ActivityState.PAUSED ); ... }
清理完成后,该可复用Activity就会到达栈顶,此时要调用onNewIntent方法,调用过程就是上面scheduleNewIntent开始,后面的步骤和上面10-15基本一样所以不再详细讲解,其实从广播到Activity启动声明周期或者内部方法的调用都是一样的过程,你只要熟悉一个方法的过程,所有方法的过程就全部都会了,所以这里还是比较容易学习的。
Step52.ActivityStarter.setTargetStackAndMoveToFrontIfNeeded 如果可复用的Activity存在那么就要设置并且将其移到最前面来,也就是栈顶。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 private ActivityRecord setTargetStackAndMoveToFrontIfNeeded (ActivityRecord intentActivity) { mTargetStack = intentActivity.task.stack; ... final ActivityStack focusStack = mSupervisor.getFocusedStack(); ActivityRecord curTop = (focusStack == null ) ? null : focusStack.topRunningNonDelayedActivityLocked(mNotTop); if (curTop != null && (curTop.task != intentActivity.task || curTop.task != focusStack.topTask()) && !mAvoidMoveToFront) { mStartActivity.intent.addFlags(Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT); if (mSourceRecord == null || (mSourceStack.topActivity() != null && mSourceStack.topActivity().task == mSourceRecord.task)) { ... final boolean willClearTask = (mLaunchFlags & (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_CLEAR_TASK)) == (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_CLEAR_TASK); if (!willClearTask) { final ActivityStack launchStack = getLaunchStack( mStartActivity, mLaunchFlags, mStartActivity.task, mOptions); if (launchStack == null || launchStack == mTargetStack) { mTargetStack.moveTaskToFrontLocked( intentActivity.task, mNoAnimation, mOptions, mStartActivity.appTimeTracker, "bringingFoundTaskToFront" ); mMovedToFront = true ; } else if (launchStack.mStackId == DOCKED_STACK_ID || launchStack.mStackId == FULLSCREEN_WORKSPACE_STACK_ID) { if ((mLaunchFlags & FLAG_ACTIVITY_LAUNCH_ADJACENT) != 0 ) { mSupervisor.moveTaskToStackLocked(intentActivity.task.taskId, launchStack.mStackId, ON_TOP, FORCE_FOCUS, "launchToSide" , ANIMATE); } else { mTargetStack.moveTaskToFrontLocked(intentActivity.task, mNoAnimation, mOptions, mStartActivity.appTimeTracker, "bringToFrontInsteadOfAdjacentLaunch" ); } ... } } ... return intentActivity; }
这里相对操作复杂,就是如果满足上面三个条件,就要将目标任务移动到前台来,这里调用了两个方法:mTargetStack.moveTaskToFrontLocked和mSupervisor.moveTaskToStackLocked。我们先看第一个:
Step53.ActivityStack.moveTaskToFrontLocked 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 final void moveTaskToFrontLocked (TaskRecord tr, boolean noAnimation, ActivityOptions options, AppTimeTracker timeTracker, String reason) { ... insertTaskAtTop(tr, null ); ... addRecentActivityLocked(top); ... ActivityRecord r = topRunningActivityLocked(); mService.setFocusedActivityLocked(r, reason); ... mStackSupervisor.resumeFocusedStackTopActivityLocked(); ... }
这里有几个操作:将任务插入到顶部,将最顶部的Activity描述对象放到最近任务的列表中,获取顶部运行的Activity并将其设置为聚焦Activity,我们一个一个分析。
Step54.ActivityStack.insertTaskAtTop 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 private void insertTaskAtTop (TaskRecord task, ActivityRecord newActivity) { boolean isLastTaskOverHome = false ; if (task.isOverHomeStack()) { final TaskRecord nextTask = getNextTask(task); if (nextTask != null ) { nextTask.setTaskToReturnTo(task.getTaskToReturnTo()); } else { isLastTaskOverHome = true ; } } if (isOnHomeDisplay()) { ActivityStack lastStack = mStackSupervisor.getLastStack(); final boolean fromHome = lastStack.isHomeStack(); if (!isHomeStack() && (fromHome || topTask() != task)) { int returnToType = isLastTaskOverHome ? task.getTaskToReturnTo() : APPLICATION_ACTIVITY_TYPE; if (fromHome && StackId.allowTopTaskToReturnHome(mStackId)) { returnToType = lastStack.topTask() == null ? HOME_ACTIVITY_TYPE : lastStack.topTask().taskType; } task.setTaskToReturnTo(returnToType); } } else { task.setTaskToReturnTo(APPLICATION_ACTIVITY_TYPE); } mTaskHistory.remove(task); int taskNdx = mTaskHistory.size(); final boolean notShownWhenLocked = (newActivity != null && (newActivity.info.flags & FLAG_SHOW_FOR_ALL_USERS) == 0 ) || (newActivity == null && task.topRunningActivityLocked() == null ); if (!mStackSupervisor.isCurrentProfileLocked(task.userId) && notShownWhenLocked) { while (--taskNdx >= 0 ) { final TaskRecord tmpTask = mTaskHistory.get(taskNdx); if (!mStackSupervisor.isCurrentProfileLocked(tmpTask.userId) || tmpTask.topRunningActivityLocked() == null ) { break ; } } ++taskNdx; } mTaskHistory.add(taskNdx, task); updateTaskMovement(task, true ); }
这里面主要是要考虑插入的任务是不是当前用户的任务,如果不是要依次查找非当前用户任务位置,然后将其放置到非当前用户任务的顶部位置。55步是将其添加到最近任务记录中。56步是获取顶部运行的Activity的描述对象。
Step57.ActivityManagerService.setFocusedActivityLocked 1 2 3 4 5 6 7 8 9 boolean setFocusedActivityLocked (ActivityRecord r, String reason) { ... if (mStackSupervisor.moveActivityStackToFront(r, reason + " setFocusedActivity" )) { mWindowManager.setFocusedApp(r.appToken, true ); } ... return true ; }
这里主要是通过调用ActivityStackSupervisor.moveActivityStackToFront方法移动焦点到新的Activity。
Step58.ActivityStackSupervisor.moveActivityStackToFront 1 2 3 4 5 6 7 boolean moveActivityStackToFront (ActivityRecord r, String reason) { ... task.stack.moveToFront(reason, task); return true ; }
Step59.ActivityStack.moveToFront 1 2 3 4 5 6 7 void moveToFront (String reason, TaskRecord task) { ... mStackSupervisor.setFocusStackUnchecked(reason, this ); ... insertTaskAtTop(task, null ); ... }
将任务移动到顶部,方法讲过了看上面的代码分析。
Step60.ActivityStackSupervisor.resumeFocusedStackTopActivityLocked 1 2 3 boolean resumeFocusedStackTopActivityLocked () { return resumeFocusedStackTopActivityLocked(null , null , null ); }
Step61.ActivityStackSupervisor.resumeFocusedStackTopActivityLocked 1 2 3 4 5 6 7 8 9 10 11 12 boolean resumeFocusedStackTopActivityLocked ( ActivityStack targetStack, ActivityRecord target, ActivityOptions targetOptions) { if (targetStack != null && isFocusedStack(targetStack)) { return targetStack.resumeTopActivityUncheckedLocked(target, targetOptions); } final ActivityRecord r = mFocusedStack.topRunningActivityLocked(); if (r == null || r.state != RESUMED) { mFocusedStack.resumeTopActivityUncheckedLocked(null , null ); } return false ; }
Step62.ActivityStack.resumeTopActivityUncheckedLocked 1 2 3 4 5 boolean resumeTopActivityUncheckedLocked (ActivityRecord prev, ActivityOptions options) { ... result = resumeTopActivityInnerLocked(prev, options); ... }
最终调用resumeTopActivityInnerLocked方法来进行处理,这个比较复杂,我们放到第二部分分析。我们回到前面接着分析。
Step63.ActivityStackSupervisor.moveTaskToStackLocked 1 2 3 4 5 boolean moveTaskToStackLocked (int taskId, int stackId, boolean toTop, boolean forceFocus, String reason, boolean animate) { return moveTaskToStackLocked(taskId, stackId, toTop, forceFocus, reason, animate, false ); }
Step64.ActivityStackSupervisor.moveTaskToStackLocked 1 2 3 4 5 6 7 8 boolean moveTaskToStackLocked (int taskId, int stackId, boolean toTop, boolean forceFocus, String reason, boolean animate, boolean deferResume) { final TaskRecord task = anyTaskForIdLocked(taskId); ... resumeFocusedStackTopActivityLocked(); ... }
第一个方法我们前面已经分析过了,这里不再提,第二个方法我们上面Step60已经分析过了。
1 2 3 4 5 6 private void resumeTargetStackIfNeeded () { ... mSupervisor.resumeFocusedStackTopActivityLocked(mTargetStack, null , mOptions); ... }
这里就是上面64中的方法也就是60步。
Step66.ActivityStarter.setTaskFromIntentActivity 这个方法主要是目标ActivityRecord对象中获取task。代码不多,可以自己看看。
Step68.ActivityStarter.setTaskFromReuseOrCreateNewTask 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 private void setTaskFromReuseOrCreateNewTask (TaskRecord taskToAffiliate) { mTargetStack = computeStackFocus(mStartActivity, true , mLaunchBounds, mLaunchFlags, mOptions); if (mReuseTask == null ) { final TaskRecord task = mTargetStack.createTaskRecord( mSupervisor.getNextTaskIdForUserLocked(mStartActivity.userId), mNewTaskInfo != null ? mNewTaskInfo : mStartActivity.info, mNewTaskIntent != null ? mNewTaskIntent : mIntent, mVoiceSession, mVoiceInteractor, !mLaunchTaskBehind ); mStartActivity.setTask(task, taskToAffiliate); ... } else { mStartActivity.setTask(mReuseTask, taskToAffiliate); } }
如果没有可复用的任务就需要创建新的任务,并且添加,如果有就直接添加。
Step71.ActivityStack.startActivityLocked 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 final void startActivityLocked (ActivityRecord r, boolean newTask, boolean keepCurTransition, ActivityOptions options) { TaskRecord rTask = r.task; final int taskId = rTask.taskId; if (!r.mLaunchTaskBehind && (taskForIdLocked(taskId) == null || newTask)) { insertTaskAtTop(rTask, r); mWindowManager.moveTaskToTop(taskId); } task.addActivityToTop(r); task.setFrontOfTask(); ... }
这里就是将Activity放到栈顶,然后显示。
Step72.ActivityStack.addRecentActivityLocked 这个方法在55步分析过不再分析。
这里是第一部分的,因此启动过程很复杂所以时序图很多,只能分两部分来讲,很多的代码没有分析,需要的可以去忘得coding拉取代码来看,里面有注释。
第二部分:
这一部分是上面过程的中间一段过程,由于东西比较多,时序图没法画了,所以提取出来单独分析,主要是ActivityStack.resumeTopActivityInnerLocked方法。
Step1.ActivityStack.resumeTopActivityInnerLocked 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 private boolean resumeTopActivityInnerLocked (ActivityRecord prev, ActivityOptions options) { ... final ActivityRecord next = topRunningActivityLocked(); final boolean userLeaving = mStackSupervisor.mUserLeaving; mStackSupervisor.mUserLeaving = false ; final TaskRecord prevTask = prev != null ? prev.task : null ; if (next == null ) { ... if (!mFullscreen && adjustFocusToNextFocusableStackLocked(returnTaskType, reason)) { return mStackSupervisor.resumeFocusedStackTopActivityLocked( mStackSupervisor.getFocusedStack(), prev, null ); } ... boolean pausing = mStackSupervisor.pauseBackStacks(userLeaving, next, dontWaitForPause); if (mResumedActivity != null ) { if (DEBUG_STATES) Slog.d(TAG_STATES, "resumeTopActivityLocked: Pausing " + mResumedActivity); pausing |= startPausingLocked(userLeaving, false , next, dontWaitForPause); } ... if (mService.isSleepingLocked() && mLastNoHistoryActivity != null && !mLastNoHistoryActivity.finishing) { ... requestFinishActivityLocked(mLastNoHistoryActivity.appToken, Activity.RESULT_CANCELED, null , "resume-no-history" , false ); ... } ... next.app.thread.scheduleSendResult(next.appToken, a); ... next.app.thread.scheduleNewIntent( next.newIntents, next.appToken, false ); ... next.app.thread.scheduleResumeActivity(next.appToken, next.app.repProcState, mService.isNextTransitionForward(), resumeAnimOptions); ... mStackSupervisor.startSpecificActivityLocked(next, true , false ); ... requestFinishActivityLocked(next.appToken, Activity.RESULT_CANCELED, null , "resume-exception" , true ); ... mStackSupervisor.startSpecificActivityLocked(next, true , true ); } ... return true ; }
这个函数代码量很大,我只留下了核心的一些来分析,其他的可以对照源码进行分析。
Step2.ActivityStack.adjustFocusToNextFocusableStackLocked 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 private boolean adjustFocusToNextFocusableStackLocked (int taskToReturnTo, String reason) { final ActivityStack stack = getNextFocusableStackLocked(); final String myReason = reason + " adjustFocusToNextFocusableStack" ; if (stack == null ) { return false ; } final ActivityRecord top = stack.topRunningActivityLocked(); if (stack.isHomeStack() && (top == null || !top.visible)) { return mStackSupervisor.moveHomeStackTaskToTop(taskToReturnTo, reason); } return mService.setFocusedActivityLocked(top, myReason); }
这里是获取下一个能够获取焦点的栈,比如最近任务或者Launcher,如果获取不到返回false,如果存在,那么获取该栈的顶部Activity,如果是HomeStack也就是Launcher栈或者最近任务栈,并且顶部Activity没有显示或者不存在则显示Launcher或者最近任务界面。否则设置到AMS中作为焦点Activity,这个函数我们讲过了。
步骤3里的函数我们也分析过了,这里也不再分析,我们开始分析第四步。
Step4.ActivityStackSupervisor.pauseBackStacks 1 2 3 4 5 6 7 8 9 10 11 12 13 boolean pauseBackStacks (boolean userLeaving, ActivityRecord resuming, boolean dontWait) { boolean someActivityPaused = false ; for (int displayNdx = mActivityDisplays.size() - 1 ; displayNdx >= 0 ; --displayNdx) { ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; for (int stackNdx = stacks.size() - 1 ; stackNdx >= 0 ; --stackNdx) { ... someActivityPaused |= stack.startPausingLocked(userLeaving, false , resuming, dontWait); ... } } return someActivityPaused; }
通过for循环暂停所有后台栈中的Activity
Step5.ActivityStack.startPausingLocked 1 2 3 4 5 6 7 final boolean startPausingLocked (boolean userLeaving, boolean uiSleeping, ActivityRecord resuming, boolean dontWait) { if (mPausingActivity != null ) { ... completePauseLocked(false , resuming); ... }
如果需要暂停的Activity不为空,那么要完成暂停操作。
Step6.ActivityStack.completePauseLocked 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 private void completePauseLocked (boolean resumeNext, ActivityRecord resuming) { ActivityRecord prev = mPausingActivity; if (prev != null ) { prev.state = ActivityState.PAUSED; if (prev.finishing) { prev = finishCurrentActivityLocked(prev, FINISH_AFTER_VISIBLE, false ); } else if (prev.app != null ) { ... if (prev.deferRelaunchUntilPaused) { if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Re-launching after pause: " + prev); relaunchActivityLocked(prev, prev.configChangeFlags, false , prev.preserveWindowOnDeferredRelaunch); } ... } ... } ... }
finish的过程我们下一章再分析,我们下面分析一个核心的函数relaunchActivityLocked,由于下面会涉及Activity的启动,因此我们通过这个函数直接来分析。
Step7.ActivityStack.relaunchActivityLocked 1 2 3 4 5 6 7 8 private void relaunchActivityLocked ( ActivityRecord r, int changes, boolean andResume, boolean preserveWindow) { ... r.app.thread.scheduleRelaunchActivity(r.appToken, results, newIntents, changes, !andResume, new Configuration (mService.mConfiguration), new Configuration (r.task.mOverrideConfig), preserveWindow); ... }
看到什么代码应该很熟悉了,调用ApplicationThreadProxy.scheduleRelaunchActivity方法然后通过Binder调用ApplicationThread.scheduleRelaunchActivity函数。我这里的图就省略了中间的过程。但是要知道这个过程。
Step8.ApplicationThread.scheduleRelaunchActivity 1 2 3 4 5 6 7 public final void scheduleRelaunchActivity (IBinder token, List<ResultInfo> pendingResults, List<ReferrerIntent> pendingNewIntents, int configChanges, boolean notResumed, Configuration config, Configuration overrideConfig, boolean preserveWindow) { requestRelaunchActivity(token, pendingResults, pendingNewIntents, configChanges, notResumed, config, overrideConfig, true , preserveWindow); }
Step9.ActivityThread.requestRelaunchActivity 1 2 3 4 5 6 7 8 public final void requestRelaunchActivity (IBinder token, List<ResultInfo> pendingResults, List<ReferrerIntent> pendingNewIntents, int configChanges, boolean notResumed, Configuration config, Configuration overrideConfig, boolean fromServer, boolean preserveWindow) { ... sendMessage(H.RELAUNCH_ACTIVITY, target); ... }
这个过程应该很熟悉了,所以这里不再多解释。后面就直接分析过程了。这里回到ActivityThread.H的handleMessage方法中,然后调用ActivityThread.handleRelaunchActivity方法。
Step10.ActivityThread.handleRelaunchActivity 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 private void handleRelaunchActivity (ActivityClientRecord tmp) { ... if (!r.paused) { performPauseActivity(r.token, false , r.isPreHoneycomb(), "handleRelaunchActivity" ); } if (r.state == null && !r.stopped && !r.isPreHoneycomb()) { callCallActivityOnSaveInstanceState(r); } handleDestroyActivity(r.token, false , configChanges, true ); ... handleLaunchActivity(r, currentIntent, "handleRelaunchActivity" ); ... }
这里performPauseActivity会根据12-17步一直执行到Activity.onPause方法。 callCallActivityOnSaveInstanceState方法会执行18-21步骤最终执行Activity.onSaveInstanceState方法。 handleDestroyActivity方法会执行到Activity.onDestroy方法。 这些过程都很简单跟着代码走一下就都知道了,过程基本相同。
Step23.ActivityThread.handleLaunchActivity 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 private void handleLaunchActivity (ActivityClientRecord r, Intent customIntent, String reason) { ... handleConfigurationChanged(null , null ); ... Activity a = performLaunchActivity(r, customIntent); if (a != null ) { ... handleResumeActivity(r.token, false , r.isForward, !r.activity.mFinished && !r.startsNotResumed, r.lastProcessedSeq, reason); if (!r.activity.mFinished && r.startsNotResumed) { ... performPauseActivityIfNeeded(r, reason); ... } else { ... } }
上面代码中handleConfigurationChanged方法最终会调用Activity.onConfigurationChanged方法。handleResumeActivity方法最终会调用Activity.onResume方法。最主要还是看performLaunchActivity方法。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 private Activity performLaunchActivity (ActivityClientRecord r, Intent customIntent) { ... Activity activity = null ; try { java.lang.ClassLoader cl = r.packageInfo.getClassLoader(); activity = mInstrumentation.newActivity( cl, component.getClassName(), r.intent); ... try { Application app = r.packageInfo.makeApplication(false , mInstrumentation); if (activity != null ) { ... activity.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); ... int theme = r.activityInfo.getThemeResource(); if (theme != 0 ) { activity.setTheme(theme); } activity.mCalled = false ; if (r.isPersistable()) { mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState); } else { mInstrumentation.callActivityOnCreate(activity, r.state); } ... if (!r.activity.mFinished) { activity.performStart(); r.stopped = false ; } if (!r.activity.mFinished) { 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); } } ... } ... return activity; }
这个启动过程: 通过29步加载Activity, 然后通过31步创建Application, 在35步调用Application的onCreate方法, 37步调用Activity的attach方法, 38步设置主题, 39步调用Activity的onCreate方法, 42步调用Activity的onStart方法, 45步调用Activity的onRestoreInstanceState方法, 然后回到ActivityThread.handleLaunchActivity方法执行handleResumeActivity方法,也就是48步以后; 在调用onResume函数之前可能会先调用onNewIntent方法和onActivityResult方法,这样一来onResume函数之前的一个流程基本就出来了,由于代码比较简单,这里不再贴代码,自己跟着这个流程自己看看就知道了。
再看65步到67步,这个是从外面调用onActivityResult、onNewIntent和onResume方法的和第一部分的8-15步一样,可以参考前面的就好了。
最后68-70步其实还是会执行到handleLaunchActivity方法上来,所以这里就不再分析。
从整篇文章看,Activity的启动流程是非常复杂,可以说在四大组件中是最复杂的,但是里面很多过程是相同的,比如生命周期的每个方法的调用过程基本是一样的,因此看书谷歌工程师设计的巧妙,这样也有助于我们对于源码的学习,减少了我们对于源码的分析过程,博客写了很多,但是对于整个过程来说还是很多地方没有分析,想了解完整的过程的可以下载我的代码,里面有很全面的注释,然后自己对着上面的时序图来进行分析,过几遍也就熟悉了,我写这片博客也用了很长的时间,主要是中间总是有事,写写停停,时序图更改了好几次。中间也有一些问题,不过跟着源码走还是都能找到的。
代码地址: 直接拉取导入开发工具(Intellij idea或者Android studio)
Android_Framework_Source
注 Android开发群:192508518
微信公众账号:Code-MX
注:本文原创,转载请注明出处,多谢。