1、使用的是Android 7.1.2的源代码:
https://pan.baidu.com/s/1XcVD68cC_2wKtm8jJkdNQA
przv
2、感谢IT先森的系列博客:
Android应用进程创建流程大揭秘
Android四大组件之bindService源码实现详解
Android四大组件之Activity启动流程源码实现详解概要
Activity启动流程(一)发起端进程请求启动目标Activity
Activity启动流程(二)system_server进程处理启动Activity请求
Activity启动流程(三)-Activity Task调度算法复盘分析
Activity启动流程(四)-Pause前台显示Activity,Resume目标Activity
Activity启动流程(五)请求并创建目标Activity进程
Activity启动流程(六)注册目标Activity进程到system_server进程以及创建目标Activity进程Application
Activity启动流程(七)初始化目标Activity并执行相关生命周期流程
疑问:
设置启动模式? ActivityStack栈管理,根据启动模式来判断是否启动栈?
在ActivityStarter.startActivityUnChecked方法中进行处理
说实话,startActivityUnChecked函数中对栈处理的这部分内容我没看懂,就是了解了对于栈处理的内容在该函数中。
相关伪代码:
======system_server进程端======
AMS解析Intent
AMS.startActivity(...)
ActivityStarter.startActivityMayWait(...)
ResolveInfo rInfo = ASS.resolveIntent(...)//收集Intent所指向的Activity信息, 当存在多个可供选择的Activity,则直接向用户弹出resolveActivity
IPackageManager.Stub.resolveIntent(...)//通过PKMS实体查询
PMS.resolveIntent(...)
PMS.queryIntentActivitiesInternal(...)
PMS.chooseBestActivity(...)
ActivityInfo aInfo = ASS.resolveActivity(...) //根据获取的rInfo信息重新组装intent和设置启动的参数信息
ActivityStarter.startActivityLocked(...)
ActivityRecord r = new ActivityRecord(callerApp,intent,aInfo,mSupervisor,...)
appToken = new Token(this, _intent);
设置state为INITIALIZING
ActivityStarter.startActivityUnchecked(...)
//包括两方面内容:
//1、AMS对于Activity比较复杂的部分即Task任务栈和Stack的处理,其中会把目标Activity放置到栈顶端
//2、resumed相关操作
// 目标Activity所属Stack栈存在Resume状态的Activity时会执行其onPause方法,否则执行的就是其它Stack栈中的了
// 错误说法:启动一个Activity的时候最先被执行的是栈顶的Activity的onPause方法
ActivityStackSupervisor.resumeFocusedStackTopActivityLocked
ActivityStack.resumeTopActivityUncheckedLocked
ActivityStack.resumeTopActivityInnerLocked
ActivityStack.startPausingLocked
ApplicationThreadProxy.schedulePauseActivity
======发起端进程处理schedulePauseActivity======
ActivityThread.ApplicationThread.schedulePauseActivity
ActivityThread.H.handleMessage(case PAUSE_ACTIVITY)
ActivityThread.handlePauseActivity //1.指定前台Activity的onPause();2.通过AMP回调activityPaused()通知AMS
ActivityThread.performPauseActivity
ActivityThread.performPauseActivityIfNeeded
Instrumentation.callActivityOnPause
Activity.performPause
Activity.onPause()
ActivityManagerNative.getDefault().activityPaused(token);
======system_server进程端======
AMS.activityPaused
ActivityStack.activityPausedLocked
ActivityStack.completePauseLocked
ActivityStackSupervisor.resumeFocusedStackTopActivityLocked //又调用了resumeFocusedStackTopActivityLocked
ActivityStack.resumeTopActivityUncheckedLocked
ActivityStack.resumeTopActivityInnerLocked
ActivityStackSupervisor.startSpecificActivityLocked
AMS.startProcessLocked
AMS.startProcessLocked
AMS.newProcessRecordLocked
Activity在 AndroidManifest.xml 文件中定义Activity时,可以通过launchMode属性来指定这个Activity应该如何与任务进行关联,取值有如下四种,不同的启动模式在启动 Activity时会执行不同的逻辑,系统会按不同的启动模式将Activity存放到不同的 Activity 栈中:
//[ActivityInfo.java]
public class ActivityInfo extends ComponentInfo
implements Parcelable {
...
public static final int LAUNCH_MULTIPLE = 0;
public static final int LAUNCH_SINGLE_TOP = 1;
public static final int LAUNCH_SINGLE_TASK = 2;
public static final int LAUNCH_SINGLE_INSTANCE = 3;
...
}
Android Intent的FLAG标志详解:https://www.jianshu.com/p/537aa221eec4
Activity的flag常用值:
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
Android上进行多任务处理:
点击Home键,长按Home键或通过其它方式可以看到当前启动的任务。每个任务都具有自己的Activity堆栈。用户返回主屏幕并选择启动任务A的应用,现在,任务A进入前台,其堆栈中的所有三个Activity都完好如初,堆栈顶部的Activity恢复运行。此时,用户仍可通过以下方式切换到任务B:①转到主屏幕并选择启动该任务的应用图标 ②从最近的应用中选择该应用的任务。
了解任务和返回堆栈:
https://developer.android.google.cn/guide/components/activities/tasks-and-back-stack
疑问:使用intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK)的话,回到主屏幕,显示的还是只有主程序这一个Task啊?
答:因为没有使用 android:taskAffinity
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)
startActivityLocked方法的主要逻辑如下:
负责调度ActivityRecord和TaskRecord、resumed相关操作
该方法的具体作用:
大致代码:
ActivityStarter.startActivityUnchecked()
setInitialState() //给要启动的ActivityRecord(mStartActivity)等赋值ActivityRecord mStartActivity = r;
computeLaunchingTaskFlags() //根据launchMode和 Intent 中的 FLAG_ACTIVITY_NEW_TASK 等 flag 综合计算 Activity 的启动模式,结果保存在mLaunchFlags 中,计算的过程不仅要考虑目标 activity 的 launchMode ,也要考虑原来 Activity 的 launchMode 和 Intent 中所带着的 Flag
computeSourceStack() //根据发起方ActivityRecord:mSourceRecord来找到源任务栈:mSourceTask
getReusableIntentActivity() //查找可重用的Activity,只对启动模式LAUNCH_SINGLE_INSTANCE和LAUNCH_SINGLE_TASK或者FLAG_ACTIVITY_NEW_TASK不为0的Activity才有用,对于standard的activity,该方法永远返回null。
//if(mReusedActivity != null)
performClearTaskForReuseLocked() //遍历TaskRecord对象实例中的ActivityRecord列表,然后根据一定的规则清除可复用的activity上面的activity
//经过上面步骤后,不管是否进行了栈顶数据的清除,接下来就要将我们可以复用的Activity所在的TaskRecord移动到其所在的ActivityStack的顶部
setTargetStackAndMoveToFrontIfNeeded() //将复用ActivityRecord所属的TaskRecord和ActivityStack移动到顶端,必要时会进行task的清理工作
ActivityStack.moveTaskToFrontLocked()
setTaskFromIntentActivity()
...
//在同一个应用中从Activity A启动 Activity B不会走此分支
if (mStartActivity.resultTo == null && mInTask == null && !mAddingToTask
&& (mLaunchFlags & FLAG_ACTIVITY_NEW_TASK) != 0) {
··· ···
}else if(mSourceRecord != null){
// 不是新建task的,重用原activity的task
final int result = setTaskFromSourceRecord();
/*****************************************************************************/
//这里小伙们就不要关注排版问题了,主要是为了演示整个流程,各位就将就一下
private int setTaskFromSourceRecord() {
//获取启动Activity的任务栈
final TaskRecord sourceTask = mSourceRecord.task;
//此时的发起端Actiivty所在的TaskRecord就是处于sourceStack栈顶,所以sourceStack.topTask就是要启动的Activity所在的栈
//如果目标Activity不允许在屏幕上显示或者源任务栈和目标任务不在同一个栈
final boolean moveStackAllowed = sourceTask.stack.topTask() != sourceTask;
//获取当前要启动activity所属的ActivityStack栈
if (moveStackAllowed) {
//不会进入此分支
...
}
//目标ActivityStack为空
if (mTargetStack == null) {
mTargetStack = sourceTask.stack;//进入此分支
} else if (mTargetStack != sourceTask.stack) {
//把启动方的任务栈绑定到目标ActivityStack上
...
}
if (mDoResume) {
mTargetStack.moveToFront("sourceStackToFront");
}
//获取目标ActivityStack的顶部task
final TaskRecord topTask = mTargetStack.topTask();
if (topTask != sourceTask && !mAvoidMoveToFront) {
//不会走入此分支
}
//如果目标activity还没有加入到栈中,而且启动标志设置了CLEAR_TOP,那么我们将Activity添加到已经存在的任务栈中,并调用clear方法清空对应的activity
if (!mAddingToTask && (mLaunchFlags & FLAG_ACTIVITY_CLEAR_TOP) != 0) {
//很明显不会进入此分支
...
} else if (!mAddingToTask && (mLaunchFlags & FLAG_ACTIVITY_REORDER_TO_FRONT) != 0) {
//不会进入此分支
...
}
mStartActivity.setTask(sourceTask, null);//设置目标Activity B的Task为A Activity所属的Task
return START_SUCCESS;
}
/*****************************************************************************/
if (result != START_SUCCESS) {
return result;
}
} else if (mInTask != null) {
//启动时指定了目标栈(mInTask),ActivityRecord绑定到mInTask,此场景下不会进入此分支
...
} else {
//不会进入此分支,忽略
..,
}
...
/*把当前启动的Activity加入TaskRecord以及绑定WindowManagerService*/
mTargetStack.startActivityLocked(mStartActivity, newTask, mKeepCurTransition, mOptions);
/*****************************************************************************/
//这里小伙们就不要关注排版问题了,主要是为了演示整个流程,各位就将就一下
final void startActivityLocked( ActivityRecord r, //此时的r为目标Activity
boolean newTask, //newTask表示是否要创建Task,为true
boolean keepCurTransition,
ActivityOptions options)
{
TaskRecord rTask = r.task;
final int taskId = rTask.taskId;
if (!r.mLaunchTaskBehind && (taskForIdLocked(taskId) == null || newTask)) {
//不会进入此分支
...
}
TaskRecord task = null;
if (!newTask) {
//newTask为false会走入此分支
...
}
...
task = r.task;
//将Activity移动到Stack的顶端 ====== 重点
task.addActivityToTop(r);
task.setFrontOfTask();
r.putInHistory();
if (!isHomeStack() || numActivities() > 0) {
//会进入此分支,此时的ActivityStack不是HomeStack
//这个地方很重要
addConfigOverride(r, task);
} else {
//不会进入此分支
...
}
...
}
}
···
if (mDoResume) {
if (!mLaunchTaskBehind) {
/*
*设置当前focused,因为经过以上几步,启动的activity已经转移到
*栈顶端,这时候设置AMS当前focused的Activity
*另外调用这个函数也会有ActivityStack、Task栈的移动,即调用各自栈把当
*前正在启动的Activity所属的Task、ActivityStack移动到栈顶
*/
mService.setFocusedActivityLocked(mStartActivity, "startedActivity");
}
final ActivityRecord topTaskActivity = mStartActivity.task.topRunningActivityLocked();
if (!mTargetStack.isFocusable()//当前的目标Stack被设置成了焦点所以不会走此分支
|| (topTaskActivity != null && topTaskActivity.mTaskOverlay
&& mStartActivity != topTaskActivity)) {
...
} else {
//开始resume,详见 ======8========
mSupervisor.resumeFocusedStackTopActivityLocked(mTargetStack, mStartActivity,
mOptions);
}
} else {
mTargetStack.addRecentActivityLocked(mStartActivity);
}
return START_SUCCESS;
...
其中,computeLaunchingTaskFlags():根据发起端/目的端的launchMode和以及Intent中的携带的FLAG_ACTIVITY_NEW_TASK等flag综合计算activity的启动模式或者说调整启动目标Activiyt的启动模式。
在Activity Task调度算法复盘分析中分析了三种情况:
任务调度时会创建新task,并将新的ActivityRecord加入这个新的task,然后将task放入合适的Stack的栈顶
任务调度时会将新的ActivityRecord加入已有的task,然后将该ActivityRecord移动到Task顶端,然后将task放入合适的Stack的栈顶
任务调度时会先找到已有的相关task,并显示栈顶的Activity
Activity A 启动 Activity B的正常生命周期调度:
---> Activity A onCreate
---> Activity A onStart
---> Activity A onResume
---> Activity A onPause
---> Activity B onCreate
---> Activity B onStart
---> Activity B onResume
---> Activty A onStop
//[ActivityStarter.java]
private int startActivityUnchecked(final ActivityRecord r, //r是指本次的将要启动的Activity
ActivityRecord sourceRecord, //sourceRecord是指发起调用者
IVoiceInteractionSession voiceSession,
IVoiceInteractor voiceInteractor,
int startFlags, //startFlags取值为0
boolean doResume, //doResume的值为true
ActivityOptions options,
TaskRecord inTask) {
...
if (mDoResume) {
if (!mLaunchTaskBehind) {
/*
* 设置当前focused,因为经过以上几步,启动的activity已经转移到
* 栈顶端,这时候设置AMS当前focused的Activity
* 另外调用这个函数也会有ActivityStack、Task栈的移动,即调用各自栈把当
* 前正在启动的Activity所属的Task、ActivityStack移动到栈顶
*/
mService.setFocusedActivityLocked(mStartActivity, "startedActivity");
}
final ActivityRecord topTaskActivity = mStartActivity.task.topRunningActivityLocked(); //目标Activity
if (!mTargetStack.isFocusable()//当前的目标Stack被设置成了焦点所以不会走此分支
|| (topTaskActivity != null && topTaskActivity.mTaskOverlay
&& mStartActivity != topTaskActivity)) {
...
} else {
//开始resume
mSupervisor.resumeFocusedStackTopActivityLocked(mTargetStack, mStartActivity,
mOptions);
}
} else {
mTargetStack.addRecentActivityLocked(mStartActivity);
}
return START_SUCCESS;
...
}
//[ActivityStackSupervisor.java]
boolean resumeFocusedStackTopActivityLocked(
ActivityStack targetStack,
ActivityRecord target, //(1).由3.1传递过来的值为Activity B; (2).由5.2传递过来的值为Activity A
ActivityOptions targetOptions) {
if (targetStack != null && isFocusedStack(targetStack)) {
return targetStack.resumeTopActivityUncheckedLocked(target, targetOptions);
}
...
}
//[ActivityStack.java]
boolean resumeTopActivityUncheckedLocked(ActivityRecord prev, ActivityOptions options) {
if (mStackSupervisor.inResumeTopActivity) {
// Don't even start recursing.
return false;
}
boolean result = false;
try {
...
result = resumeTopActivityInnerLocked(prev, options);//prev:目标Activity的相关信息 options:额外附加信息
} finally {
mStackSupervisor.inResumeTopActivity = false;
}
return result;
}
//[ActivityStack.java]
private boolean resumeTopActivityInnerLocked(ActivityRecord prev, ActivityOptions options) {
if (!mService.mBooting && !mService.mBooted) {
// 如果系统还未启动完毕,那AMS还不能正常工作,所以也不能显示Activity,主要是为防止没有开机启动完成
return false;
}
//此处忽略
ActivityRecord parent = mActivityContainer.mParentActivity;
...
// 当前ActivityStack中可能存在一些正处于Intializing状态的ActivityRecord,
// 如果这些ActivityRecord不是位于栈顶,而且正在执行窗口启动动画,
// 那么,就需要取消这些Activity的启动动画。
mStackSupervisor.cancelInitializingActivities();
/*
找到第一个没有finishing的栈顶activity,通常指向了要启动的Activity目标组件
此场景下prev和next都是同一个,都指向了Activity B
*/
final ActivityRecord next = topRunningActivityLocked();
//这个变量是表示是否回调Activity中的onUserLeaveHint和onUserInteraction函数
final boolean userLeaving = mStackSupervisor.mUserLeaving;
mStackSupervisor.mUserLeaving = false;
final TaskRecord prevTask = prev != null ? prev.task : null;
if (next == null) {
//这个表示如果当前ActivityStack不存在待启动的Activity,那么会启动Launcher桌面
final String reason = "noMoreActivities";
final int returnTaskType = prevTask == null || !prevTask.isOverHomeStack()
? HOME_ACTIVITY_TYPE : prevTask.getTaskToReturnTo();
// 当前AS不是全屏显示,则需要将焦点切换到下一个待显示的AS
if (!mFullscreen && adjustFocusToNextFocusableStackLocked(returnTaskType, reason)) {
return mStackSupervisor.resumeFocusedStackTopActivityLocked(
mStackSupervisor.getFocusedStack(), prev, null);
}
ActivityOptions.abort(options);
// 默认情况下,Stack都是占据全屏的,所以,当前Stack如果没有要显示的Activity,则会要求显示桌面
return isOnHomeDisplay() &&
mStackSupervisor.resumeHomeStackTask(returnTaskType, prev, reason);
}
next.delayedResume = false;
//检查要启动的Activity 组件是否等于当前被激活的 Activity 组件,如果等于
//并且处于 RESUMED 状态,直接返回,我们前面演示的启动情况很显然不满足条件
if (mResumedActivity == next && next.state == ActivityState.RESUMED &&
mStackSupervisor.allResumedActivitiesComplete()) {
//当前正在显示的Activity正好就是下一个待显示的Activity,
// 那么,就中断对目标ActivityRecord的调度
mWindowManager.executeAppTransition();
mNoAnimActivities.clear();
ActivityOptions.abort(options);
return false;
}
final TaskRecord nextTask = next.task;
/*这个是对上一个resumed的Activity的相关处理
* 由于我们是第一次启动B Activity,所以不可能处于finish跳过此处
*/
if (prevTask != null && prevTask.stack == this &&
prevTask.isOverHomeStack() && prev.finishing && prev.frontOfTask) {
...
}
// 系统进入休眠状态,当前Stack的栈顶Activity已经处于Paused状态
// 那么,中断待显示Activity的相关调度(有点拗口,学习源码就是这么枯燥的事情)
if (mService.isSleepingOrShuttingDownLocked()
&& mLastPausedActivity == next
&& mStackSupervisor.allPausedActivitiesComplete()) {
mWindowManager.executeAppTransition();
mNoAnimActivities.clear();
ActivityOptions.abort(options);
return false;
}
...
/*
在ASS中存在很多的数据结构,用来统一管理ActivityRecord的状态
譬如mStoppingActivities记录了当前所有处于Stopping状态的ActivityRecord
mGoingToSleepActivities记录了当前所有要进入休眠状态的ActivityRecord
在某些场景下,待显示的ActivityRecord可能处于这些数组中,但需要从中剔除
*/
mStackSupervisor.mStoppingActivities.remove(next);
mStackSupervisor.mGoingToSleepActivities.remove(next);
next.sleeping = false;
mStackSupervisor.mWaitingVisibleActivities.remove(next);
// 如果当前ASS中还有ActivityRecord不是处于PAUSED, STOPPED或STOPPING这三个状态之一,
// 那么,需要先等这些ActivityRecord进入停止状态
if (!mStackSupervisor.allPausedActivitiesComplete()) {
return false;
}
/*****************************************************************************************************************
上述代码的作用:准备阶段,做一些初始化和可能的"异常"处理工作,在执行目标Activity的onCreate/onStart/onResume状态,还有很多障碍和初始化工作需要处理。比如系统要休眠时,当前启动目标Activity过程要中断;当ASS中有Activity处于Pausing状态时,要等相关的Activity执行完毕。
*****************************************************************************************************************/
//[ActivityStack.java]
/*
setLaunchSource设置待启动的Activity的信息
跟进setLaunchSource源码发现它最终会获取一个WakeLock,保证在显示Activity的过程中,系统不会进行休眠状态
*/
mStackSupervisor.setLaunchSource(next.info.applicationInfo.uid);
/*
目标Activity的启动参数中是否包含FLAG_RESUME_WHILE_PAUSING
如果存在FLAG_RESUME_WHILE_PAUSING的flag,表示可以在当前显示的发起端Activity执行Pausing时,
能同时进行Resume操作
即变量dontWaitForPause的取意就是不需要等到Activity执行Pause完毕
*/
final boolean dontWaitForPause = (next.info.flags & FLAG_RESUME_WHILE_PAUSING) != 0;
/*
这个是pause掉不是FocusedStack的其它ActivityStack的栈顶activity
对于不是当前focusStack的并且存在有mResumedActivity不为null的都要paused
譬如从Luncher启动一个新的App时会走入此分支(FLAG_ACTIVITY_NEW_TASK)
从5.2走过来,即已经pause Activity A时,没有需要要进行pause
*/
boolean pausing = mStackSupervisor.pauseBackStacks(userLeaving, true, dontWaitForPause);
/********************************************************************************/
//这里是为了演示使用
//ASS.java
boolean pauseBackStacks(boolean userLeaving, boolean 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) {
final ActivityStack stack = stacks.get(stackNdx);
if (!isFocusedStack(stack) && stack.mResumedActivity != null) {
someActivityPaused |= stack.startPausingLocked(userLeaving, false, resuming,
dontWait);
}
}
}
return someActivityPaused;
}
/********************************************************************************/
//从3.2走过来,此时要带入真实场景了,此时的mResumedActivity表示目标Stack栈中处于Resume状态的Activity,那么在此场景下就是Activity A,这个因该比较容易理解
//从5.2走过来,此时要带入真实场景了,此时的mResumedActivity表示目标Stack栈中处于Resume状态的Activity,通过前面的分析可以此时没有处于Resume状态的Activty了,所以不会走入此分支
if (mResumedActivity != null) {
// 当前resumed状态activity不为空,则需要先暂停该Activity
// pause当前栈的activity,即执行Activity的生命周期onPause
pausing |= startPausingLocked(userLeaving, false, true, dontWaitForPause);//-->进入这里
}
//从3.2走过来,当前有正在pause的Activity,尼玛按照我们场景Activity A启动Activity B,那不是到此就结束了啊,直接返回了,事实就是这样的,尼玛是不是走错片场了,后续你就知道了
//从5.2走过来,不会进入此分支
if (pausing) {
if (next.app != null && next.app.thread != null) {
mService.updateLruProcessLocked(next.app, true, null);
}
return true;
}
//检查要启动的Activity 组件是否等于当前被激活的 Activity 组件,如果等于
//并且处于 RESUMED 状态,直接返回,我们前面演示的启动情况很显然不满足条件
else if (mResumedActivity == next && next.state == ActivityState.RESUMED &&
mStackSupervisor.allResumedActivitiesComplete()) {
mWindowManager.executeAppTransition();
mNoAnimActivities.clear();
ActivityOptions.abort(options);
return true;
}
//3.2 不往下执行
//5.2 往下执行
··· ···
//[ActivityStack.java]
//对已经Pause的Activity继续处理,主要是通知WMS做进一步的处理
if (prev != null && prev != next) {
//prev是Activity A,next是Activity B
if (!mStackSupervisor.mWaitingVisibleActivities.contains(prev)
&& next != null && !next.nowVisible) {
mStackSupervisor.mWaitingVisibleActivities.add(prev);
} else {
if (prev.finishing) {
mWindowManager.setAppVisibility(prev.appToken, false);
} else {
}
}
}
try {
// 通过PackageManager修改待启动Package的状态
AppGlobals.getPackageManager().setPackageStoppedState(
next.packageName, false, next.userId); /* TODO: Verify if correct userid */
} catch (RemoteException e1) {
} catch (IllegalArgumentException e) {
}
...
ActivityStack lastStack = mStackSupervisor.getLastStack();
//next.app :ProcessRecord
//next.app.thread : IApplicationThread
if (next.app != null && next.app.thread != null) {
//如果目的端进程已经创建,即要启动的目标Activity所属进程已经存在
...
next.state = ActivityState.RESUMED;
mResumedActivity = next;
next.task.touchActiveTime();
mRecentTasks.addLocked(next.task);
mService.updateLruProcessLocked(next.app, true, null);
updateLRUListLocked(next);
mService.updateOomAdjLocked();
...
try {
...
next.sleeping = false;
mService.showUnsupportedZoomDialogIfNeededLocked(next);
mService.showAskCompatModeDialogLocked(next);
next.app.pendingUiClean = true;
next.app.forceProcessStateUpTo(mService.mTopProcessState);
next.clearOptionsLocked();
//执行目的端Activity的scheduleResumeActivity操作
next.app.thread.scheduleResumeActivity(next.appToken, next.app.repProcState,
mService.isNextTransitionForward(), resumeAnimOptions);
...
} catch (Exception e) {
...
}
try {
completeResumeLocked(next);
} catch (Exception e) {
//处理异常
requestFinishActivityLocked(next.appToken, Activity.RESULT_CANCELED, null,
"resume-exception", true);
return true;
}
} else {
//当目标Activity所属进程没有启动的时候,则会创建进程
if (!next.hasBeenLaunched) {
next.hasBeenLaunched = true;
} else {
if (SHOW_APP_STARTING_PREVIEW) {
next.showStartingWindow(null, true);
}
}
//创建目标Activity进程 -->到5.3
mStackSupervisor.startSpecificActivityLocked(next, true, true);
}
return true;
}
要显示的目标Activity已经做好入栈操作了,就是放在Stack的栈顶,可以通过ActivityStack.topRunningActivityLocked()找到它。
如果当前要Resume的目标Activity不是之前已经Resume的Activity,那么必须将Pause之前的Activity:
1)Pause其他任务栈的mResumedActivity,调用ASS.pauseBackStacks(之前resume的Activity在其他任务栈中)
2)Pause当前任务栈的mResumedActivity,调用 ActivityStack.startPausingLocked(“1)”最后也会调用到这个函数)
接下来,执行Pause ActivityA 的操作:
//[ActivityStack.java]
final boolean startPausingLocked(boolean userLeaving,
boolean uiSleeping, //此时传递进来的参数为false
boolean resuming,//此时传递进来的参数为true
boolean dontWait)
{
//判断当前的Stack栈中是否存在正在pausing的Activity
if (mPausingActivity != null) {
if (!mService.isSleepingLocked()) {
completePauseLocked(false);
}
}
//获取当前Stack栈中处于Resume状态的Activity,在我们当前的环境下就是Activity A了
ActivityRecord prev = mResumedActivity;
if (prev == null) {
if (!resuming) {
mStackSupervisor.resumeFocusedStackTopActivityLocked();
}
return false;
}
...
// 变更ActivityStack中pauseActivity的记录,此处是重点
mResumedActivity = null;
mPausingActivity = prev;
mLastPausedActivity = prev;
mLastNoHistoryActivity = (prev.intent.getFlags() & Intent.FLAG_ACTIVITY_NO_HISTORY) != 0
|| (prev.info.flags & ActivityInfo.FLAG_NO_HISTORY) != 0 ? prev : null;
prev.state = ActivityState.PAUSING;
prev.task.touchActiveTime();
clearLaunchTime(prev);
...
// 通知APP执行发起端的pause操作
if (prev.app != null && prev.app.thread != null) {
if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Enqueueing pending pause: " + prev);
try {
EventLog.writeEvent(EventLogTags.AM_PAUSE_ACTIVITY,
prev.userId, System.identityHashCode(prev),
prev.shortComponentName);
mService.updateUsageStats(prev, false);
prev.app.thread.schedulePauseActivity(prev.appToken, prev.finishing,
userLeaving, prev.configChangeFlags, dontWait);//-->进入Activity A的进程
} catch (Exception e) {
mPausingActivity = null;
mLastPausedActivity = null;
mLastNoHistoryActivity = null;
}
} else {
mPausingActivity = null;
mLastPausedActivity = null;
mLastNoHistoryActivity = null;
}
//获取锁,防止休眠
if (!uiSleeping && !mService.isSleepingOrShuttingDownLocked()) {
mStackSupervisor.acquireLaunchWakelock();
}
if (mPausingActivity != null) {
if (!uiSleeping) {
prev.pauseKeyDispatchingLocked();
} else if (DEBUG_PAUSE) {
}
if (dontWait) {
completePauseLocked(false);
return false;
} else {
//这个是经典的ANR埋雷,监控APP是否pause超时,时间只有500ms
Message msg = mHandler.obtainMessage(PAUSE_TIMEOUT_MSG);
msg.obj = prev;
prev.pauseTime = SystemClock.uptimeMillis();
mHandler.sendMessageDelayed(msg, PAUSE_TIMEOUT);
return true;
}
} else {
...
}
}
进入Activity A所在进程,处理Pause
//[ActivityThread.java]
private class ApplicationThread extends ApplicationThreadNative {
public final void schedulePauseActivity(IBinder token, boolean finished,
boolean userLeaving, int configChanges, boolean dontReport) {
int seq = getLifecycleSeq();
sendMessage(
finished ? H.PAUSE_ACTIVITY_FINISHING : H.PAUSE_ACTIVITY,
token,
(userLeaving ? USER_LEAVING : 0) | (dontReport ? DONT_REPORT : 0),
configChanges,
seq);//详见1.3.2
}
}
//ActivityThread.java
private class H extends Handler {
public void handleMessage(Message msg) {
switch (msg.what) {
...
case PAUSE_ACTIVITY: {
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityPause");
SomeArgs args = (SomeArgs) msg.obj;
handlePauseActivity((IBinder) args.arg1, false,
(args.argi1 & USER_LEAVING) != 0, args.argi2,
(args.argi1 & DONT_REPORT) != 0, args.argi3);//详见章节1.3.3
maybeSnapshot();
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
} break;
...
}
}
}
//[ActivityThread.java]
final ArrayMap<IBinder, ActivityClientRecord> mActivities = new ArrayMap<>();
private void handlePauseActivity(IBinder token, boolean finished,
boolean userLeaving, int configChanges, boolean dontReport, int seq) {
//获取需要
ActivityClientRecord r = mActivities.get(token);
if (r != null) {
if (userLeaving) {
performUserLeavingActivity(r);
}
r.activity.mConfigChangeFlags |= configChanges;
//执行Activity的onPause操作
performPauseActivity(token, finished, r.isPreHoneycomb(), "handlePauseActivity");//详见章节1.3.4
if (r.isPreHoneycomb()) {
QueuedWork.waitToFinish();
}
if (!dontReport) {
try {
//通知AMS已经Pause成功了
ActivityManagerNative.getDefault().activityPaused(token);
} catch (RemoteException ex) {
throw ex.rethrowFromSystemServer();
}
}
mSomeActivitiesChanged = true;
}
}
//[ActivityThread.java]
final Bundle performPauseActivity(IBinder token, boolean finished,
boolean saveState, String reason) {
ActivityClientRecord r = mActivities.get(token);
return r != null ? performPauseActivity(r, finished, saveState, reason) : null;
}
final Bundle performPauseActivity(ActivityClientRecord r, boolean finished,
boolean saveState, String reason) {
...
performPauseActivityIfNeeded(r, reason);
...
return !r.activity.mFinished && saveState ? r.state : null;
}
private void performPauseActivityIfNeeded(ActivityClientRecord r, String reason) {
if (r.paused) {
return;
}
try {
r.activity.mCalled = false;
mInstrumentation.callActivityOnPause(r.activity);
EventLog.writeEvent(LOG_AM_ON_PAUSE_CALLED, UserHandle.myUserId(),
r.activity.getComponentName().getClassName(), reason);
if (!r.activity.mCalled) {
...
}
} catch (SuperNotCalledException e) {
throw e;
} catch (Exception e) {
...
}
r.paused = true;
}
//[Instrumentation.java]
public void callActivityOnPause(Activity activity) {
activity.performPause();
}
//[Activity.java]
final void performPause() {
mDoReportFullyDrawn = false;
mFragments.dispatchPause();
mCalled = false;
onPause();//执行Activity的onPause方法
mResumed = false;
if (!mCalled && getApplicationInfo().targetSdkVersion
>= android.os.Build.VERSION_CODES.GINGERBREAD) {
throw new SuperNotCalledException(
"Activity " + mComponent.toShortString() +
" did not call through to super.onPause()");
}
mResumed = false;
}
目标Activity所属Stack栈存在Resume状态的Activity时会执行其onPause方法,否则执行的就是其它Stack栈中的了。
在 4.2 中可以看出,执行完 4.3 的ActivityThread.performPauseActivity之后,会执行 ActivityManagerNative.getDefault().activityPaused(token); 用来通知AMS已经Pause成功了。
//[AMS.java]
public final void activityPaused(IBinder token) {
final long origId = Binder.clearCallingIdentity();
synchronized(this) {
//获取已经pause的Activity所属Stack
ActivityStack stack = ActivityRecord.getStackLocked(token);
if (stack != null) {
stack.activityPausedLocked(token, false); //-->进入
}
}
Binder.restoreCallingIdentity(origId);
}
//[ActivityStack.java]
final void activityPausedLocked(IBinder token, boolean timeout) {
final ActivityRecord r = isInStackLocked(token);
if (r != null) {
mHandler.removeMessages(PAUSE_TIMEOUT_MSG, r);
if (mPausingActivity == r) {
completePauseLocked(true, null);//此处传入的参数为true
return;
} else {
...
}
}
mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
}
private void completePauseLocked(boolean resumeNext, ActivityRecord resuming) {
ActivityRecord prev = mPausingActivity;
...
if (resumeNext) {
final ActivityStack topStack = mStackSupervisor.getFocusedStack();
if (!mService.isSleepingOrShuttingDownLocked()) {
//会进入此分支
final ActivityStack topStack = mStackSupervisor.getFocusedStack();
//此时的prev为前台显示已经pause的Activity
mStackSupervisor.resumeFocusedStackTopActivityLocked(topStack, prev, null);
} else {
mStackSupervisor.checkReadyForSleepLocked();
ActivityRecord top = topStack.topRunningActivityLocked();
if (top == null || (prev != null && top != prev)) {
mStackSupervisor.resumeFocusedStackTopActivityLocked();
}
}
}
...
}
再次进入 “3.2、ActivityStack.resumeFocusedStackTopActivityLocked”
创建目标Activity进程:
//[ActivityStackSupervisor.java]
final ActivityManagerService mService;
void startSpecificActivityLocked(ActivityRecord r, //目标Activity相关信息
boolean andResume, //此时传递的参数值为true
boolean checkConfig) //此时传递的参数值为false
{
//检查目标Activity所属的应用进程是否创建,假如是冷启动的情况当然是木有创建的
ProcessRecord app = mService.getProcessRecordLocked(r.processName,
r.info.applicationInfo.uid, true);
r.task.stack.setLaunchTime(r);
/*
当目标Activity对应的App进程和进程对应的ApplicationThread被创建时,进入此分支,此时的我们是木有机会了
*/
if (app != null && app.thread != null) {
//
try {
/*
判断此Activity是否携带FLAG_MULTIPROCESS或者其对应的进程名是"android"
那"android"对应的进程到底是啥呢,其实它是system_server,这个是在zygote孵化它时指定的
*/
if ((r.info.flags&ActivityInfo.FLAG_MULTIPROCESS) == 0
|| !"android".equals(r.info.packageName)) {
app.addPackage(r.info.packageName, r.info.applicationInfo.versionCode,
mService.mProcessStats);
}
//正式启动目标Activity,开启生命周期
realStartActivityLocked(r, app, andResume, checkConfig);
return;
} catch (RemoteException e) {
...
}
}
//调用AMS开启startProcess处理流程
mService.startProcessLocked(r.processName, r.info.applicationInfo, true, 0,
"activity", r.intent.getComponent(), false, false, true);//详见章节2.2
}
final ProcessRecord startProcessLocked(String processName, //目标Activity对应的进程名,通常是包名
ApplicationInfo info, //Activity所属APP的application信息
boolean knownToBeDead, //true
int intentFlags, //0
String hostingType, //"activity"
ComponentName hostingName, //启动目标Activity时解析Intent时得到的ComponentName
boolean allowWhileBooting, //false
boolean isolated, //false 该进程是否是以隔离模式启动
boolean keepIfLarge //true) {
return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType,
hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge,
null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */,
null /* crashHandler */);
}
//[ActivityManagerService.java]
//这个参数够多的,真是够多的
final ProcessRecord startProcessLocked(String processName, //目标Activity对应的进程名,通常上是包名
ApplicationInfo info,//Activity所属App的Application信息
boolean knownToBeDead, //这个参数具体意义不明,传递过来的值为true
int intentFlags, //参数的值为0
String hostingType, //这个参数意义不明,参数值为"activity"
ComponentName hostingName,//启动目标Activity时解析intent时得到的
boolean allowWhileBooting, //是否允许在开启启动时,参数未false
boolean isolated, //参数为false,这个值的意思是该进程是否是隔离的
int isolatedUid, //指定隔离进程的UID
boolean keepIfLarge,//参数意义不明,传递的值为true
String abiOverride, //是否覆盖目标Activity所属app安装时的abi,abi通常影响so库的选择,取值为null
String entryPoint, //参数意义不明,取值为null
String[] entryPointArgs, //参数意义不明,取值为null
Runnable crashHandler) //参数意义不明,取值为null
{
...
ProcessRecord app;
if (!isolated) {
//当不是隔离进程时
/*
获取AMS中是否存在目标Activity所属进进程的ProcessRecord记录,在非isolated模式下AMS可以重用先前的ProcessRecord记录
这里小伙们肯定有个疑问就是为啥startSpecificActivityLocked中检查了一次,这里又检查一次,
而和startSpecificActivityLocked处理不同的是这里并没有因为ProcessRecord的存在而停止后续的脚步呢
好吗,此处的逻辑感觉有点不是很清晰啊
*/
app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
// 启动参数中,带有FLAG_FROM_BACKGROUND标志,表示进程需要后台启动
if ((intentFlags & Intent.FLAG_FROM_BACKGROUND) != 0) {
// 后台启动一个BadProcess,直接退出
if (mAppErrors.isBadProcessLocked(info)) {
return null;
}
} else {
//清理进程Crash消息
mAppErrors.resetProcessCrashTimeLocked(info);
if (mAppErrors.isBadProcessLocked(info)) {
// 前台启动,则需要将宿主进程从坏的进程中剔除
mAppErrors.clearBadProcessLocked(info);
if (app != null) {
app.bad = false;
}
}
}
} else {
app = null;
}
/*
此处涉及到了超自然现象,看注释的意思是对于大小核的架构的设备的话,此时使用cpuset将前台任务迁移到大核上
这个已经超过本人的能力范畴之外了,pass
*/
nativeMigrateToBoost();
mIsBoosted = true;
...
// 当进程已经被分配了PID时
if (app != null && app.pid > 0) {
// 进程还处于启动的过程中
if ((!knownToBeDead && !app.killed) || app.thread == null) {
app.addPackage(info.packageName, info.versionCode, mProcessStats);
return app;
}
/*
这个地方要怎么理解呢,可能前面目标Activity所属App进程被创建过
但是已经over了再启动时需要对其做一些清理工作
*/
killProcessGroup(app.uid, app.pid);
handleAppDiedLocked(app, true, true);
}
String hostingNameStr = hostingName != null
? hostingName.flattenToShortString() : null;
if (app == null) {
//在AMS中创建ProcessRecord信息记录
app = newProcessRecordLocked(info, processName, isolated, isolatedUid);//-->1 进入这里
if (app == null) {
return null;
}
//设置crashHandler
app.crashHandler = crashHandler;
} else {
app.addPackage(info.packageName, info.versionCode, mProcessStats);
}
// 如果系统还未启动,则需要将待启动进程先保持住,等系统启动后,再来启动这些进程
//final ArrayList mProcessesOnHold = new ArrayList();
if (!mProcessesReady
&& !isAllowedWhileBooting(info)
&& !allowWhileBooting) {
if (!mProcessesOnHold.contains(app)) {
mProcessesOnHold.add(app);
}
return app;
}
//又调用另外一个重载的startProcessLocked
startProcessLocked(
app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs);//2 -->进入这里
return (app.pid != 0) ? app : null;
}
首先判断是否是以isolated模式启动的目标Activity所属App进程,那么这个isolated模式是什么意思呢,网上说通过isolated来判断要启动的进程是否是隔离的,当为true时意味着这是一个隔离的进程(虽然这么说,但是本人是没有搞明白,这个隔离到底隔离的是啥,如果对此处有比较深入的小伙们可以告诉我)。
对于隔离的进程而言,每次启动都是独立的,不能复用已有的进程信息。如果要启动一个非隔离的进程,那么就需要区分进程是在前台启动还是后台启动,这是用户体验相关的设计。在AMS中维护了一个badProcesses的结构体,用于保存一些“坏进程”,什么才是“坏进程”呢?如果一个进程在一分钟内连续崩溃两次,那就变成了一个“坏进程”。对于后台启动的进程而言(即启动参数中带有FLAG_FROM_BACKGROUND标识),如果进程崩溃了,会造成用户使用的困惑,因为进程崩溃时,会弹出一个对话框,而后台启动的进程是没有任何操作界面的,这时候弹一个框,用户会觉得自己什么都没干,却弹出了一个对话框。所以,后台启动一个“坏进程”时,会直接退出。
当进程是在前台启动时,即便是一个"坏进程",那也应该宽恕这个进程以前的不良记录,因为这通常是用户通过界面主动要唤起的进程。本着用户是上帝的原则,还是得让用户达到启动进程的目的,即便这个进程可能再次崩溃。
接着判断目标Activity所对应的ProcessRecord是否创建,如果还没有创建这时候会调用AMS.newProcessRecord来创建一个新的ProcessRecord
接着调用AMS的另一个重载方法startProcessLocked继续目标Activity对应进程创建的处理流程
下一章见!这篇太长了!