前言
对于Android开发者而言,最经常接触的就是四大组件了,Activity、Service、BroadcastReceiver、ContentProvider,其中Activity是我们使用频率最多的,这四个都是通过ActivityManagerService(下文简称AMS)进行管理的,本文就分析AndroidFramework中是如何管理Activity、以及如何创建Activity的。ActivityManagerService(以下简称AMS)启动Activity过程之前,要先弄明白几个重要的类及概念。
1、ActivityRecord介绍
这个对应的就是应用开发过程AndroidManifest.xml以〈activity/>定义的各个Activity。这个表示的是Activity在AMS中的表示方式。下面介绍ActivityRecord一些重要的变量.
final class ActivityRecord {
/*表示AMS在创建ActivityRecord时候指定*/
final ActivityManagerService service; // owner
/*这个是和WindomMangerService通信的,該值会赋值给Activity中*/
final IApplicationToken.Stub appToken; // window manager token
/*这个描述是AndroidManifest.xml中定义activity相关信息*/
final ActivityInfo info; // all about me
/*这个描述是AndroidManifest.xml中定义application相关信息*/
final ApplicationInfo appInfo; // information about activity's app
。。。。。。。。
/*应用的包名*/
final String packageName; // the packageimplementing intent's component
final String processName; // process where this component wants torun
/**Activity亲和性,这上简单的描述就是该Activity应属于是哪个Task*/
final String taskAffinity; // as per ActivityInfo.taskAffinity
。。。。。。。
/**以下三个表示该Activity类型*/
static final int APPLICATION_ACTIVITY_TYPE= 0;
static final int HOME_ACTIVITY_TYPE = 1;
static final int RECENTS_ACTIVITY_TYPE = 2;
int mActivityType;
。。。。。。。
/**Activity属于哪个Task*/
TaskRecord task; // the task this is in.
/**通过startActivityForResult启动时,接收返回值的Activity*/
ActivityRecord resultTo; // who startedthis entry, so will get our reply
/**通过startActivityForResult启动时设置的requestCode*/
final int requestCode; // code given by requester (resultTo)
。。。。。。。
/*Activity所属的进程*/
ProcessRecord app; // ifnon-null, hosting application
/*表示Activity的当前状态, INITIALIZING,RESUMED,PAUSING,PAUSED,STOPPING,STOPPED,FINISHING,DESTROYING,DESTROYED
有这几种状态*/
ActivityState state; // current state we are in
/*标记是否为Task的root Activity,比如每个应用有一个mainActivity,一般
*情况下该main Activity即为对应Task的rootActivity*/
boolean frontOfTask; // isthis the root activity of its task?
/*标记该ActivityRecord是否已经stoped*/
boolean stopped; // isactivity pause finished?
/*标记ActivityRecord是否已经finishing,这在activity finish时置为true*/
boolean finishing; // activity in pending finish list?
boolean deferRelaunchUntilPaused; //relaunch of activity is being deferred until pause is
//completed
boolean visible; // does this activity's window need tobe shown?
boolean sleeping; // have we told the activity to sleep?
boolean nowVisible; // is thisactivity's window visible?
/*ActivityStack管理类*/
final ActivityStackSupervisormStackSupervisor;
2、TaskRecord介绍
这个是管理一个应用中ActivityRecord的容器,比如一个应用有很多的Activity,而这些Activity都是以Task栈方式进行管理,Task个人认为可以简单的认为一个应用,一个应用对应一个Task。下面说下TaskRecord一些重要的变量。
final class TaskRecord {
/*该Task的id*/
final int taskId; // Unique identifier for this task.
/*Task 亲合性,这个值可能会变化,这个值和ActivityRecord的taskAffinity对应*/
String affinity; // The affinity name for this task, ornull; may change identity.
/*这个值标记Task中rootActivity的亲和性,和第一次启动该Task的root ActivityRecord中的taskAffinity对应,但是该值后续不会改变*/
String rootAffinity; // Initial base affinity, or null; does notchange from initial root.
/**启动Task的Activity的intent*/
Intent intent; // The original intent that startedthe task.
IntentaffinityIntent; // Intent ofaffinity-moved activity that started this task.
int effectiveUid; // The current effective uid of theidentity of this task.
ComponentNameorigActivity; // The non-alias activity component of the intent.
ComponentNamerealActivity; // The actual activity component that started the task.
int numFullscreen; // Number of fullscreen activities.
。。。。。。。。。
/*这个即是用来保存一个Task中所有的 Activtiy,按栈的方式管理*/
/** List of all activitiesin the task arranged in history order */
finalArrayList<ActivityRecord> mActivities;
/** Current stack
*该Task所属的ActivityStack */
ActivityStack stack;
/** Takes on same set ofvalues as ActivityRecord.mActivityType
*task类型和ActivityRecord的mActivityType对应*/
int taskType;
/** Indication of what torun next when task exits. Use ActivityRecord types.
*ActivityRecord.APPLICATION_ACTIVITY_TYPE indicates to resume the task belowthis one in the
* task stack. */
private intmTaskToReturnTo = APPLICATION_ACTIVITY_TYPE;
/** If original intent didnot allow relinquishing task identity, save that information */
booleanmNeverRelinquishIdentity = true;
// Used in the unique casewhere we are clearing the task in order to reuse it. In that case we
// do not want to deletethe stack when the task goes empty.
private boolean mReuseTask= false;
//这是截屏相关的
private BitmapmLastThumbnail; // Last thumbnail captured for this item.
private final FilemLastThumbnailFile; // File containing last thumbnail.
。。。。。。。。
finalActivityManagerService mService;
// Whether or not thistask covers the entire screen; by default tasks are fullscreen.
boolean mFullscreen =true;
// Bounds of the Task.null for fullscreen tasks
//这是Task在屏幕显示区域
Rect mBounds = null;
。。。。。。。
}
3、ActivityStack介绍
这个是管理TaskRecord的容器,也是系统中多窗口的概念读者参考
http://blog.csdn.net/guoqifa29/article/details/54863237,目前在Android7.1.2上面有以下几个,这些定义在android.app.ActivityManager.StackId中。
/** Homeactivity stack ID.这个包括Launcher的Activity以及recentsAPP */
HOME_STACK_ID = FIRST_STATIC_STACK_ID;
/** ID ofstack where fullscreen activities are normally launched into. 这个即为我们应用启动的Activity所处于的ActivityStack*/
FULLSCREEN_WORKSPACE_STACK_ID = 1;
/** ID of stack where freeform/resizedactivities are normally launched into. */ FREEFORM_WORKSPACE_STACK_ID =FULLSCREEN_WORKSPACE_STACK_ID + 1;
/** ID of stack that occupies a dedicatedregion of the screen. 这个是分屏应用所处于的ActivityStack*/
DOCKED_STACK_ID = FREEFORM_WORKSPACE_STACK_ID+ 1;
/** ID of stack that always on top (alwaysvisible) when it exist.这个好像是画中画模式的Activity所处的 ActivityStack */
PINNED_STACK_ID = DOCKED_STACK_ID + 1;
/** Last static stack stack ID. */
LAST_STATIC_STACK_ID = PINNED_STACK_ID;
ActivityStack一些重要变量如下:
final classActivityStack {
。。。。。。。
/**Activity状态值*/
enum ActivityState {
INITIALIZING,
RESUMED,
PAUSING,
PAUSED,
STOPPING,
STOPPED,
FINISHING,
DESTROYING,
DESTROYED
}
。。。。。。。
final ActivityManagerService mService;
final WindowManagerService mWindowManager;
private final RecentTasks mRecentTasks;
/**
* The back history of all previous (andpossibly still
* running) activities. It contains #TaskRecord objects.
* 系统中的所有Task都保存在这里面,以栈的方式管理
*/
private final ArrayList<TaskRecord>mTaskHistory = new ArrayList<>();
/**
* Activities that specify No History mustbe removed once the user navigates away from them.
* If the device goes to sleep with such anactivity in the paused state then we save it here
* and finish it later if another activityreplaces it on wakeup.
*/
ActivityRecord mLastNoHistoryActivity =null;
/**
* Current activity that is resumed, ornull if there is none.
* 这个表示当前ActivityStack处于running中的activity
*/
ActivityRecord mResumedActivity = null;
/**
* When we are in the process of pausing anactivity, before starting the
* next one, this variable holds theactivity that is currently being paused.
* 一般是mResumedActivity赋值
* 这个表示此时正在pausing过程的activity
*/
ActivityRecord mPausingActivity = null;
/**
* This is the last activity that we putinto the paused state. This is
* used to determine if we need to do anactivity transition while sleeping,
* when we normally hold the top activitypaused.
*这个表示此时正在paused过程的activity
*/
ActivityRecord mLastPausedActivity = null;
/**
* This is the last activity that has beenstarted. It is only used to
* identify when multiple activities arestarted at once so that the user
* can be warned they may not be in theactivity they think they are.
*/
ActivityRecord mLastStartedActivity = null;
final int mStackId;
。。。。。。
/**在每个ActivityStack中保存着一份所有的ActivityStack*/
ArrayList<ActivityStack> mStacks;
/** The attached Display's uniqueidentifier, or -1 if detached */
int mDisplayId;
/** Run all ActivityStacks through this
*这个是管理ActivityStack的*/
final ActivityStackSupervisor mStackSupervisor;
4、ActivityStackSupervisor介绍
ActivityStackSupervisor这个是ActivityStack的管理类。以下几个比较重要的变量。读者看下。
/** The stack containing the launcherapp. Assumed to always be attached to
* Display.DEFAULT_DISPLAY. */
ActivityStack mHomeStack;
/** The stack currently receiving input orlaunching the next activity. */
ActivityStack mFocusedStack;
/** If this is the same as mFocusedStackthen the activity on the top of the focused stack has
* been resumed. If stacks are changingposition this will hold the old stack until the new
* stack becomes resumed after which itwill be set to mFocusedStack. */
private ActivityStack mLastFocusedStack;
Android7.1.1系统存在以上几个ActivityStack,以栈的方式管理ActivityStack,而不同的应用处于不同的ActivityStack,每个ActivityStack以栈的方式管理多个TaskRecord,而每个TaskRecord又以栈的方式管理多个ActivityRecord。可以用图一表示。
图一
5、ActivityThread介绍
final ApplicationThread mAppThread =new ApplicationThread();
这个是定义在ActivityThread中的变量,我们开发过程都一直说应用主线程,主线程即表示的是ActivityThread,一个应用它的主线程只有一个,应用中消息比如Acrivity的生命周期都是通过ActivityThread中的mAppThread这个进行分发。本文只是涉及ActivityManagerService其中Activity这一小部分,很多东西像WindowmanagerService的交互本文没有涉及。另外本文只是关注了ActivityStackID为HOME_STACK_ID的HomeStack和ActivityStack ID为FULLSCREEN_WORKSPACE_STACK_ID的FullscreenStack,像PINNED_STACK、FREEFORM_WORKSPACE_STACK、DOCKED_STACK这方面没有介绍。简单的认为只存在HomeStack和FullScreenStack两个ActivityStack这样有利于抓住主线。
在分析AMS启动Activty之前,大家有必要先弄明白下Android的启动模式,这样有利于弄明白代码。启动模式和Task的介绍可以参考点击打开链接
我们知道Android系统启动之后启动的第一个应用为Launcher那么我们以Launcher为例,结合代码分析AMS是如何启动一个Activity的,以下代码会忽略些和启动无关的代码,这样有利于我们抓住启动Activity这条主线。
从AMS启动过程我们知道在AMS中是通过函数startHomeActivityLocked启动Launcher的,我们先来看下Launcher应用中AndroidManifest.xml中关于HomeActivity的Activity定义(请看图二),其中的launchMode、clearTaskOnLaunch、android.intent.category.HOME重点关注。
图 二
代码如下:
/*函数主要作用为获取HomeActivity(即应用AndroidManifest.xml中有设置android.intent.category.HOME,下文中HomeActivity即指该Activty)中的intent以及ActivityInfo*/
boolean startHomeActivityLocked(int userId, String reason) {
if (mFactoryTest ==FactoryTest.FACTORY_TEST_LOW_LEVEL && mTopAction == null) {
。。。。。。。。。
return false;
}
//这边获取到的即为Launcher中AndroidManifest.xml有定义android.intent.category.HOME的Activity
Intent intent = getHomeIntent();
ActivityInfo aInfo =resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
if (aInfo != null) {
intent.setComponent(newComponentName(aInfo.applicationInfo.packageName, aInfo.name));
// Don't do this if the home app iscurrently being
// instrumented.
aInfo = new ActivityInfo(aInfo);
aInfo.applicationInfo =getAppInfoForUser(aInfo.applicationInfo, userId);
ProcessRecord app =getProcessRecordLocked(aInfo.processName,
aInfo.applicationInfo.uid,true);
/**因为是第一次启动Home 应用,所以对应的进程会null*/
if (app == null || app.instrumentationClass== null) {
intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
mActivityStarter.startHomeActivityLocked(intent, aInfo, reason);
}
} else {
Slog.wtf(TAG, "No home screen found for " + intent, newThrowable());
}
return true;
}
接下去mActivityStarter.startHomeActivityLocked代码如下:
void startHomeActivityLocked(Intent intent, ActivityInfo aInfo, String reason) {
/**这是把HomeActivity所属的HomeStack移动到前台,
*但是由于第一次启动HomeActivity还未创建,
*其中所属的TaskRecord、以及ActivityRecrod为null
*/
mSupervisor.moveHomeStackTaskToTop(ActivityRecord.HOME_ACTIVITY_TYPE,reason);
startActivityLocked(null /*caller*/,intent, null /*ephemeralIntent*/,
null /*resolvedType*/, aInfo,null /*rInfo*/, null /*voiceSession*/,
null /*voiceInteractor*/, null/*resultTo*/, null /*resultWho*/,
0 /*requestCode*/, 0/*callingPid*/, 0 /*callingUid*/, null /*callingPackage*/,
0 /*realCallingPid*/, 0/*realCallingUid*/, 0 /*startFlags*/, null /*options*/,
false /*ignoreTargetSecurity*/,false /*componentSpecified*/, null /*outActivity*/,
null /*container*/, null/*inTask*/);
if (mSupervisor.inResumeTopActivity) {
。。。。。。
mSupervisor.scheduleResumeTopActivities();
}
}
说明以下的代码我会删除一些对于第一次启动HOME应用不必要的代码,读者可以自行看源码进行分析,大家千万要自己对着代码分析,因为本文这个涉及太多,另外一个作者能力有限有些内容会表述不清楚,会遗漏一些细节,读者对着代码看就会比较清晰了
接下来部分是任何一个Activity的启动都会经历的流程。
Activity的启动过程
Activity启动过程可以概括以下几个步骤。
1、前期准备工作
2、计算Activity所属的Task、ActivityStack,及操作。
3、paused之前Activity、resumed当前启动的Activity过程
4、进程的创建
5、Activity初始化流程
接下去我会按照这几个步骤,对照着源码进行下会析。
一、前期准备工作
前期准备工作,其实就是初始化当前启动Activity相关的变量。我们进入ActivityStarter中的startActivityLocked(Android系统中任何Activity启动显示都会进入该函数)。代码如下:
final int startActivityLocked(
IApplicationThreadcaller/*表示启动者所属的应用主线程,在ActivityThread中定义*/,
Intent intent/*当前启动的Activity的Intent*/,
IntentephemeralIntent,/*当前启动的Activity的Intent的复本*/
String resolvedType,/*当前启动的Activity的resolvedType*/
ActivityInfoaInfo,/*当前启动的Activity的ActivityInfo(PackageManger解析获得)*/
ResolveInforInfo,/*当前启动的Activity的ResolveInfo */
IVoiceInteractionSessionvoiceSession,/*暂时忽略为null&/
IVoiceInteractorvoiceInteractor,/*暂时忽略为null*/
IBinderresultTo, String resultWho,
intrequestCode, /*通过startActivityForResult设置的值*/
intcallingPid, int callingUid,
String callingPackage,/*表示调用者即启动当前Activity所属的包名*/
int realCallingPid, int realCallingUid,int startFlags,
ActivityOptions options, booleanignoreTargetSecurity,
boolean componentSpecified,
ActivityRecord[]outActivity,
ActivityStackSupervisor.ActivityContainercontainer, TaskRecord inTask) {
int err = ActivityManager.START_SUCCESS;
ProcessRecord callerApp = null;
/*如果调用者不为null,查询是否已经创建了ProcessRecord,如果创建了,则
*设置调用者的callingpid、callingUid*/
if (caller != null) {
callerApp =mService.getRecordForAppLocked(caller);
if (callerApp != null) {
callingPid = callerApp.pid;
callingUid =callerApp.info.uid;
} else {
Slog.w(TAG, "Unable tofind app for caller " + caller
+ " (pid=" +callingPid + ") when starting: "
+ intent.toString());
err =ActivityManager.START_PERMISSION_DENIED;
}
}
final int userId = aInfo != null ?UserHandle.getUserId(aInfo.applicationInfo.uid) : 0;
if (err ==ActivityManager.START_SUCCESS) {
Slog.i(TAG, "START u" +userId + " {" + intent.toShortString(true, true, true, false)
+ "} from uid " +callingUid
+ " on display "+ (container == null ? (mSupervisor.mFocusedStack == null ?
Display.DEFAULT_DISPLAY :mSupervisor.mFocusedStack.mDisplayId) :
(container.mActivityDisplay== null ? Display.DEFAULT_DISPLAY :
container.mActivityDisplay.mDisplayId)));
}
ActivityRecord sourceRecord = null;
ActivityRecord resultRecord = null;
/**这边判断的是,当前启动方式是以startActivityForResult启动的,
*则保存调用者Activity在sourceRecord中,
*如果启动时候设置了requestCode并且大于是0,那么接收
*startActivityForResult返回值的Activity保存在resultRecord中。
*其实读者可以看出来,调用者和接收返回者的Activity是相同的
*举个例子:
*Activity A通过startActivityForResult启动B,并且requestCode>0
*那么此时sourceRecord和resultRecord都为A
*/
if (resultTo != null) {
sourceRecord =mSupervisor.isInAnyStackLocked(resultTo);
if (DEBUG_RESULTS)Slog.v(TAG_RESULTS,
"Will send result to" + resultTo + " " + sourceRecord);
if (sourceRecord != null) {
if (requestCode >= 0&& !sourceRecord.finishing) {
resultRecord =sourceRecord;
}
}
}
final int launchFlags =intent.getFlags();
/**
*FLAG_ACTIVITY_FORWARD_RESULT这个FLAG作用,举个例子:
*应用中存在有ActivityA,B,C,A以startActivityForResult方式启动了B,
* 此时B设置了FLAG_ACTIVITY_FORWARD_RESULT启动了C,注意此时B启动C
* 时requestCode不设置或者设置值要小于0,不然会报错。
* 那么原来在A中接收返回值从B返回的,但这时A接收的返回值变成从C返回。
*/
if ((launchFlags &Intent.FLAG_ACTIVITY_FORWARD_RESULT) != 0 && sourceRecord != null) {
// Transfer the result target fromthe source activity to the new
// one being started, including anyfailures.
if (requestCode >= 0) {
ActivityOptions.abort(options);
returnActivityManager.START_FORWARD_AND_REQUEST_CONFLICT;
}
resultRecord =sourceRecord.resultTo;
if (resultRecord != null &&!resultRecord.isInStackLocked()) {
resultRecord = null;
}
resultWho = sourceRecord.resultWho;
requestCode =sourceRecord.requestCode;
sourceRecord.resultTo = null;
if (resultRecord != null) {
resultRecord.removeResultsLocked(sourceRecord, resultWho, requestCode);
}
if (sourceRecord.launchedFromUid ==callingUid) {
// The new activity is beinglaunched from the same uid as the previous
// activity in the flow, and askingto forward its result back to the
// previous. In this case the activity is serving as atrampoline between
// the two, so we also want toupdate its launchedFromPackage to be the
// same as the previousactivity. Note that this is safe, sincewe know
// these two packages come fromthe same uid; the caller could just as
// well have supplied that samepackage name itself. This specifially
// deals with the case of anintent picker/chooser being launched in the app
// flow to redirect to anactivity picked by the user, where we want the final
// activity to consider it tohave been launched by the previous app activity.
callingPackage =sourceRecord.launchedFromPackage;
}
}
。。。。。。。
/**
*创建需要启动的Activity对应的ActvityRecord
*此时对应图一中AndroidManifest.xml中定义的HOME Activity
*/
ActivityRecord r = newActivityRecord(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;
}
。。。。。
/**
*这个是先启动延迟启动的Activity
*对于本文启动Launcher时应该是为null的
*/
doPendingActivityLaunchesLocked(false);
try {
/*windowmangerservice相关*/
mService.mWindowManager.deferSurfaceLayout();
err = startActivityUnchecked(r,sourceRecord, voiceSession, voiceInteractor, startFlags,
true, options, inTask);
}finally {
mService.mWindowManager.continueSurfaceLayout();
}
postStartActivityUncheckedProcessing(r,err, stack.mStackId, mSourceRecord, mTargetStack);
return err;
}
接下来进入ActivityStarter中的startActivityUnchecked,在该函数中做的事情挺多的,也是最复杂的一部分。本文分析以HOME应用启动为主线,不涉及到HOME应用相关的代码我会先标注,一些其它的分析是在比较复杂的情况下,读者可以对应着启动模式对应着分析,这样会比较深刻明白。该函数主要包含以下几个步骤
1、计算launchFlag
2、计算调用者的ActivityStack
3、检查是否存在复用的TaskRecord
4、对于存在复用的TaskRecord则进行相应的ActivityStack、TaskRecord的移动(这个比较复杂).
5、计算当前启动Activity所属的TaskRecord
6、把当前启动的Activity放到所属TaskRecord的栈顶
7、最后调用resumeFocusedStackTopActivityLocked创建正在启动的Activity、Paused当前resumed的Activity,以及resumed当前启动的Activity
HOME应用的launchMode为singleTask、以及设置了clearTaskOnLaunch为true,结合这两点我们开始分析。
startActivityUnchecked代码如下:
private intstartActivityUnchecked(final ActivityRecord r, ActivityRecord sourceRecord,
IVoiceInteractionSessionvoiceSession, IVoiceInteractor voiceInteractor,
int startFlags, boolean doResume,ActivityOptions options,
TaskRecord inTask){
/*初始化一些值,读者自己看下*/
setInitialState(r, options, inTask,doResume, startFlags,
sourceRecord,voiceSession, voiceInteractor);
/*计算当前启动Activity的是否要增加Intent.FLAG_ACTIVITY_NEW_TASK*/
computeLaunchingTaskFlags();
/*获取调用者的ActivityStack*/
computeSourceStack();
mIntent.setFlags(mLaunchFlags);
/**
*这边主要是判断当前启动的Activity是否存在可以利用的Task
* 当启动模式launchMode为singleTask、singleInstance,或者启动时
* Flag设置为FLAG_ACTIVITY_NEW_TASK并没设置FLAG_ACTIVITY_MULTIPLE_TASK
* 并且当前启动的Activity不是以startActivityForResult启动的,
* 满足以上情况才会寻找是否存在有复用的Task。
* 匹配规则:
* 1、对于启动模式为singleInstance,遍历所有ActivityStack和Task的堆栈中查找
*是否存在以当前启动Activity相同的Activity。
* 2、其它情况下,遍历所有ActivityStack和Task的堆栈,查找Task中intent变量 * 是否当前启动Activity相匹配,如果不存在,则去匹配task的亲和性(即
*在AndroidManifest中android:taskAffinity定义的。
*对于本文介绍启动Launcher应用mResuedActivity为null
*/
mReusedActivity =getReusableIntentActivity();
。。。。。。。
}
到这儿本章开头说的第一部分前期准备工作算是结束,我们总结下,前期准备工作主要做了什么:
1、在ActivityStarter的startActivityLocked计算调用者的PID和UID,得到调用者的Activity sourceRecord、以及接收返回值的Activity resultRecord。创建当前启动的Activity对应的ActivityRecord,并且在ActivityRecord保存当前启动的Activity保存调用者、接收返回值的Activity,让Activity有迹可寻。
2、在ActivityStarter的startActivityUnLocked中重置一些变量、对于调用者不为null情况下,得到调用者Activty所属的ActivityStack,接着判断对于当前启动的Activity,是否存在复用的Task,这部分主要是决定按何种方式启动Activity。
二、寻找Activity所属的Task、ActivityStack,及操作
寻找Task、ActivityStack可以大致可以分为两种情况。
1、 存在复用的Task情况。
2、 不存在复用Task情况。
接着第一章查找完复用Task之后的代码流程分析。
private int startActivityUnchecked(final ActivityRecord r, ActivityRecord sourceRecord,
IVoiceInteractionSessionvoiceSession, IVoiceInteractor voiceInteractor,
int startFlags, boolean doResume,ActivityOptions options,
TaskRecordinTask) {
。。。。。。。。。
final int preferredLaunchStackId = (mOptions != null) ?mOptions.getLaunchStackId() : ActivityManager.StackId.INVALID_STACK_ID;
/**
*表明当前的Task列表中存在有复用的Activity
*可能为相同的Activity或者具有相同的affinity的task
*如果是第一次启动某个应用或者从adb am中启动以及第一次启动Launcher
*那么复用的TaskRecord为null
*对于本文介绍启动Launcher应用中HOME Activity ,此时mResuedActivity为null
*读者可以先忽略这分支代码
*这边对应的是存在复用Task的情况
*/
if (mReusedActivity != null) {
/*由于对于系统刚启动时启动HOMEActivity,还不存在有task,此时mResusedActivity为null所以可以先忽略这部分代码
*这部分代码主要是对于存在复用的TaskRecord则进行相应的ActivityStack、 *TaskRecord的移动,以及对于启动过程中设置相关的FLAG进行处理
*/
// When theflags NEW_TASK and CLEAR_TASK are set, then the task gets reused but
// still needsto be a lock task mode violation since the task gets cleared out and
// the devicewould otherwise leave the locked task.
if (mSupervisor.isLockTaskModeViolation(
mReusedActivity.task,
(mLaunchFlags &(FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_CLEAR_TASK))
==(FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_CLEAR_TASK))) {
mSupervisor.showLockTaskToast();
Slog.e(TAG,"startActivityUnchecked: Attempt to violate Lock Task Mode");
returnSTART_RETURN_LOCK_TASK_MODE_VIOLATION;
}
//设置当前启动Activity的Task为复用的Task
if (mStartActivity.task == null) {
mStartActivity.task =mReusedActivity.task;
}
if (mReusedActivity.task.intent ==null) {
// This task was started because ofmovement of the activity based on affinity...
// Now that we are actually launchingit, we can assign the base intent.
mReusedActivity.task.setIntent(mStartActivity);
}
// This codepath leads to delivering a new intent, we want to make sure we schedule it
// as thefirst operation, in case the activity will be resumed as a result of later
//operations.
/*
*这边处理启动时设置FLAG_ACTIVITY_CLEAR_TOP时,要清除复用Task中存在与当前启动
*Activity相同的Activity之上的Activity
*举个例子:比如复用Task1中存在有Activity A,B,C,D,此时正在启动的Activity B,那么C**和D也要finish,另外此时如果B *为标准启动模式,并且没有设置FLAG_ACTIVITY_SINGLE_TOP,那么B也会finish。具体的读者可以跟进
*mReusedActivity.task.performClearTaskForReuseLocked看下。
*/
if ((mLaunchFlags &FLAG_ACTIVITY_CLEAR_TOP) != 0
|| mLaunchSingleInstance ||mLaunchSingleTask) {
// In this situation we want toremove all activities from the task up to the one
// being started. In most casesthis means we are resetting the task to its initial
// state.
final ActivityRecord top =mReusedActivity.task.performClearTaskForReuseLocked(
mStartActivity,mLaunchFlags);
if (top != null) {
if (top.frontOfTask) {
// Activity aliases maymean we use different intents for the top activity,
// so make sure thetask now has the identity of the new intent.
top.task.setIntent(mStartActivity);
}
ActivityStack.logStartActivity(AM_NEW_INTENT, mStartActivity, top.task);
if(shouldActivityBeBroughtToFront(mReusedActivity)) {
mStartActivity.intent.addFlags(Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT);
}
//这边调用Activity中的onNewIntent
top.deliverNewIntentLocked(mCallingUid, mStartActivity.intent,
mStartActivity.launchedFromPackage);
}
}
sendPowerHintForLaunchStartIfNeeded(false /* forceSend */);
//这边开始设置当前启动Activity所属的ActivityStack,如果需要要把Activity
//所属的Task、ActivityStack移动到前台,见下面分析。
mReusedActivity =setTargetStackAndMoveToFrontIfNeeded(mReusedActivity);
//对于复用Task情况下START_FLAG_ONLY_IF_NEEDED这个FLAG只是resumed
//具体这个Flag是啥意思不是很清楚,读者知道的可以告诉我下。
if ((mStartFlags &START_FLAG_ONLY_IF_NEEDED) != 0) {
// We don't need to start a newactivity, and the client said not to do anything
// if that is the case, so thisis it! And for paranoia, make sure wehave
// correctly resumed the topactivity.
resumeTargetStackIfNeeded();
returnSTART_RETURN_INTENT_TO_CALLER;
}
setTaskFromIntentActivity(mReusedActivity);
//如果不需要把当前启动的Activity增加到Task并且不存在复用Task
//那么仅仅进行resumed过程。
if (!mAddingToTask &&mReuseTask == null) {
// We didn't doanything... but it was needed (a.k.a.,client don't use that
// intent!) And for paranoia, make sure we have correctlyresumed the top activity.
resumeTargetStackIfNeeded();
return START_TASK_TO_FRONT;
}
}
我们看下setTargetStackAndMoveToFrontIfNeeded这个函数里面是怎么操作Task和stack的。代码如下:
private ActivityRecord setTargetStackAndMoveToFrontIfNeeded(ActivityRecord intentActivity){
//targetStack设置成复用task所属的stack
mTargetStack =intentActivity.task.stack;
mTargetStack.mLastPausedActivity =null;
// If the target task is not in thefront, then we need to bring it to the front...
// except... well, with SINGLE_TASK_LAUNCH it's notentirely clear. We'd like to have
// the same behavior as if a newinstance was being started, which means not bringing it
// to the front if the caller is notitself in the front.
final ActivityStack focusStack =mSupervisor.getFocusedStack();
//这边是当前前台的Task和复用task不同,那么需要进行Task的移动
if(shouldActivityBeBroughtToFront(intentActivity)) {
if (mSourceRecord == null ||(mSourceStack.topActivity() != null &&
mSourceStack.topActivity().task == mSourceRecord.task)) {
// We really do want to pushthis one into the user's face, right now.
if (mLaunchTaskBehind&& mSourceRecord != null) {
intentActivity.setTaskToAffiliateWith(mSourceRecord.task);
}
mMovedOtherTask = true;
// If the launch flags carryboth NEW_TASK and CLEAR_TASK, the task's activities
// will be cleared soon by ActivityStarterin setTaskFromIntentActivity().
// So no point resuming any ofthe activities here, it just wastes one extra
// resuming, plus enter ANDexit transitions.
// Here we only want to bringthe target stack forward. Transition will be applied
// to the new activity that'sstarted after the old ones are gone.
final boolean willClearTask =
(mLaunchFlags &(FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_CLEAR_TASK))
== (FLAG_ACTIVITY_NEW_TASK |FLAG_ACTIVITY_CLEAR_TASK);
/*如果FlagFLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_CLEAR_TASK设置这两个时候,它会 *在接下来的代码中ActivityStarterin setTaskFromIntentActivity().清除该Task(后面会分析到
*此处我们分析没有设置Flag的情况
*/
if (!willClearTask) {
//计算当前启动的Activity所属的stack
final ActivityStacklaunchStack = getLaunchStack(
mStartActivity,mLaunchFlags, mStartActivity.task, mOptions);
//如果当前启动的Activity即为复用Task所属的ActivityStack
if (launchStack == null ||launchStack == mTargetStack) {
// We onlywant to move to the front, if we aren't going to launch on a
// differentstack. If we launch on a different stack, we will put the
// task on topthere.
//这边就是进行相关task和activityStack的移动了,这个只是在Task所属的ActivityStack中 //的移动不涉及把Task移动到其它ActivityStack,见下面分析。
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) {
/*If we want to launch adjacent and mTargetStack is not the computed
*launch stack - move task to top of computed stack.
*这边是把复用的Task移动到其它的ActivityStack*/
mSupervisor.moveTaskToStackLocked(intentActivity.task.taskId,launchStack.mStackId,
ON_TOP, FORCE_FOCUS,"launchToSide",ANIMATE);
} else {
// TODO: Thisshould be reevaluated in MW v2.
// We choose to move task to front instead oflaunching it adjacent
// when specific stack was requestedexplicitly and it appeared to be
// adjacent stack, butFLAG_ACTIVITY_LAUNCH_ADJACENT was not set.
mTargetStack.moveTaskToFrontLocked(intentActivity.task, mNoAnimation,
mOptions,mStartActivity.appTimeTracker,
"bringToFrontInsteadOfAdjacentLaunch");
}
mMovedToFront = true;
}
mOptions = null;
}
updateTaskReturnToType(intentActivity.task, mLaunchFlags, focusStack);
}
}
//这边表示如果不需要Task移动,移动targetStack到前台,见下文分析。
if (!mMovedToFront &&mDoResume) {
if (DEBUG_TASKS) Slog.d(TAG_TASKS,"Bring to front target: " + mTargetStack
+ " from " +intentActivity);
mTargetStack.moveToFront("intentActivityFound");
}
mSupervisor.handleNonResizableTaskIfNeeded(intentActivity.task,INVALID_STACK_ID,
mTargetStack.mStackId);
// If the caller has requested that thetarget task be reset, then do so.
if ((mLaunchFlags &FLAG_ACTIVITY_RESET_TASK_IF_NEEDED) != 0) {
returnmTargetStack.resetTaskIfNeededLocked(intentActivity, mStartActivity);
}
return intentActivity;
}
我们进入ActivitityStack中的moveTaskToFrontLocked分析Task如何在所属的Activity移动。代码如下:
final void moveTaskToFrontLocked(TaskRecord tr, boolean noAnimation,
ActivityOptions options,
AppTimeTrackertimeTracker, String reason) {
final int numTasks= mTaskHistory.size();
final int index =mTaskHistory.indexOf(tr);
if (numTasks == 0 ||index < 0) {
// nothing to do!
if (noAnimation) {
ActivityOptions.abort(options);
} else {
updateTransitLocked(TRANSIT_TASK_TO_FRONT, options);
}
return;
}
。。。。。。
// Shift allactivities with this task up to the top
// of the stack,keeping them in the same internal order.
//这边就是把Task移动到ActivityStack的栈顶端
//代码比较简单不列了
insertTaskAtTop(tr,null);
。。。。。。。。。
// Set focus to the top running activity ofthis stack.
//这时候stack的topActivity应该是上一步已经移到栈顶
//复用的Task
ActivityRecord r =topRunningActivityLocked();
//更新AMS中的focusedActivity
//这边会把当前Activity所属的Stack移到栈顶,
//并且会更新ActivityStackSupervisor中的
//mLastFocusedStack、mFocusedStack这两个变量
mService.setFocusedActivityLocked(r, reason);
。。。。。。。。
//相应Activity状态的切换,这个后面章节会介绍
mStackSupervisor.resumeFocusedStackTopActivityLocked();
。。。。。。。。。。
}
经过上面的setTargetStackAndMoveToFrontIfNeeded这个函数之后,当前启动Activity复用的Task、以它所属的ActivityStack均已经移动到了栈顶。接着是调用setTaskFromIntentActivity,代码如下:
//这个主要是处理一些FLAG,
private void setTaskFromIntentActivity(ActivityRecordintentActivity) {
if ((mLaunchFlags& (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_CLEAR_TASK))
==(FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_CLEAR_TASK)) {
// The caller has requested to completely replace any existing taskwith its new
// activity. Well that should not be too hard...
//设置了FLAG_ACTIVITY_CLEAR_TASK复用的Task会finish所有的Activity,并且重新
//更新复用Task信息的当前启动的Activity
intentActivity.task.performClearTaskLocked();
intentActivity.task.setIntent(mStartActivity);
mReuseTask =intentActivity.task;
// When we clear the task - focus will be adjusted, which will bringanother task
// to top before we launch the activity we need. This will temporaryswap their
// mTaskToReturnTo values and we don't want to overwrite themaccidentally.
mMovedOtherTask =true;
} else if((mLaunchFlags & FLAG_ACTIVITY_CLEAR_TOP) != 0
||mLaunchSingleInstance || mLaunchSingleTask) {
ActivityRecord top =intentActivity.task.performClearTaskLocked(mStartActivity,
mLaunchFlags);
if (top == null) {
// A special case: we needto start the activity because it is not currently
// running, and the callerhas asked to clear the current task to have this
// activity at the top.
mAddingToTask= true;
// Now pretend like thisactivity is being started by the top of its task, so it
// is put in the rightplace.
mSourceRecord= intentActivity;
finalTaskRecord task = mSourceRecord.task;
if (task !=null && task.stack == null) {
// Target stack got cleared when we allactivities were removed above.
// Goahead and reset it.
mTargetStack = computeStackFocus(mSourceRecord, false /* newTask */,
null /* bounds */, mLaunchFlags, mOptions);
mTargetStack.addTask(task,
!mLaunchTaskBehind /* toTop */, "startActivityUnchecked");
}
}
} else if(mStartActivity.realActivity.equals(intentActivity.task.realActivity)) {
// In this case the top activity on the task is the same as the onebeing launched,
// so we take that as a request to bring the task to the foreground.If the top
// activity in the task is the root activity, deliver this newintent to it if it
// desires.
if (((mLaunchFlags& FLAG_ACTIVITY_SINGLE_TOP) != 0 || mLaunchSingleTop)
&&intentActivity.realActivity.equals(mStartActivity.realActivity)) {
ActivityStack.logStartActivity(AM_NEW_INTENT,mStartActivity,
intentActivity.task);
if(intentActivity.frontOfTask) {
intentActivity.task.setIntent(mStartActivity);
}
intentActivity.deliverNewIntentLocked(mCallingUid,mStartActivity.intent,
mStartActivity.launchedFromPackage);
} else if(!intentActivity.task.isSameIntentFilter(mStartActivity)) {
// In this case weare launching the root activity of the task, but with a
// different intent.We should start a new instance on top.
mAddingToTask= true;
mSourceRecord= intentActivity;
}
} else if((mLaunchFlags & FLAG_ACTIVITY_RESET_TASK_IF_NEEDED) == 0) {
// In this case anactivity is being launched in to an existing task, without
// resetting thattask. This is typically the situation of launching an activity
// from anotification or shortcut. We want to place the new activity on top of the
// current task.
mAddingToTask =true;
mSourceRecord =intentActivity;
} else if(!intentActivity.task.rootWasReset) {
// In this case weare launching into an existing task that has not yet been started
// from its frontdoor. The current task has been brought to the front. Ideally,
// we'd probablylike to place this new task at the bottom of its stack, but that's
// a little hardto do with the current organization of the code so for now we'll
// just drop it.
intentActivity.task.setIntent(mStartActivity);
}
}
接着上面分析完存在复用Task的操作之后,我们代码还得继续往下接着看代码:
private int startActivityUnchecked(final ActivityRecord r, ActivityRecord sourceRecord,
IVoiceInteractionSessionvoiceSession, IVoiceInteractor voiceInteractor,
int startFlags, boolean doResume,ActivityOptions options,
TaskRecordinTask) {
。。。。。。。。。
if (mReusedActivity != null){
。。。。。。。
}
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, Activity.RESULT_CANCELED, null);
}
ActivityOptions.abort(mOptions);
returnActivityManager.START_CLASS_NOT_FOUND;
}
// If the activity being launched isthe same as the one currently at the top, then
// we need to check if it should onlybe launched once.
/**
*对于系统刚启动HOME应用,此时FocusedStack即为HomeStack,
* 这个在AMS初始化中ActivityStackSupervisor的setWindowManager初始化完成
*/
final ActivityStack topStack =mSupervisor.mFocusedStack;
/**对于本文启动Launcher中的HOME Activity这时候TOP为nulll*/
final ActivityRecord top =topStack.topRunningNonDelayedActivityLocked(mNotTop);
/*这个是对于Flag设置了SINGLE_TOP的和launchmode为singleTOp和singleTask时候,对于当前启动的Activity在 *TaskRecord栈顶时候,调用onNewIntent*/
final boolean dontStart = top != null&& mStartActivity.resultTo == null
&&top.realActivity.equals(mStartActivity.realActivity)
&& top.userId == mStartActivity.userId
&& top.app != null &&top.app.thread != null
&& ((mLaunchFlags &Intent.FLAG_ACTIVITY_SINGLE_TOP) != 0
|| mLaunchSingleTop ||mLaunchSingleTask);
if (dontStart) {
ActivityStack.logStartActivity(EventLogTags.AM_NEW_INTENT, top,top.task);
// For paranoia, make sure we havecorrectly resumed the top activity.
topStack.mLastPausedActivity =null;
if (mDoResume) {
mSupervisor.resumeFocusedStackTopActivityLocked();
}
ActivityOptions.abort(mOptions);
if ((mStartFlags &ActivityManager.START_FLAG_ONLY_IF_NEEDED) != 0) {
// We don't need to start a newactivity, and the client said not to do
// anything if that is thecase, so this is it!
returnActivityManager.START_RETURN_INTENT_TO_CALLER;
}
top.deliverNewIntentLocked(mCallingUid,mStartActivity.intent,
mStartActivity.launchedFromPackage);
// Don't use mStartActivity.task toshow the toast. We're not starting a new activity
// but reusing 'top'. Fields inmStartActivity may not be fully initialized.
mSupervisor.handleNonResizableTaskIfNeeded(
top.task,preferredLaunchStackId, topStack.mStackId);
returnActivityManager.START_DELIVERED_TO_TOP;
}
boolean newTask = false;
final TaskRecord taskToAffiliate =(mLaunchTaskBehind && mSourceRecord != null)
? mSourceRecord.task : null;
// Should this be considered a newtask?
/**
*对于本文启动Launcher中的HOME Activity,需要创建TaskRecord,所以进入第
*一个if流程
*这这对应的是不存在复用Task的情况,需要重新创建一个Task
*/
if (mStartActivity.resultTo == null&& mInTask == null && !mAddingToTask
&&(mLaunchFlags & Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
newTask = true;
/*计算当前启动Activity所属的ActivityStack以及为它创建一个新的TaskRecord*/
setTaskFromReuseOrCreateNewTask(taskToAffiliate);
。。。。。。。。
}
}
。。。。 。。。
进入setTaskFromResuseOrCreateNewTask函数,代码如下:
private void setTaskFromReuseOrCreateNewTask(TaskRecord taskToAffiliate) {
/*这就是计算当前启动的Activity所属的ActivityStack
*对于本文介绍的启动Launcher中的HomeActivity,它对应
* 的ActivityStack为HomeStack
*/
mTargetStack = computeStackFocus(mStartActivity,true, mLaunchBounds,
mLaunchFlags, mOptions);
if (mReuseTask == null) {
/**
*开始创建TaskRecord,并且把新的TaskRecord加入到targetStack的栈顶
*/
final TaskRecord task =mTargetStack.createTaskRecord(
mSupervisor.getNextTaskIdForUserLocked(mStartActivity.userId),
mNewTaskInfo != null ?mNewTaskInfo : mStartActivity.info,
mNewTaskIntent != null ?mNewTaskIntent : mIntent,
mVoiceSession,mVoiceInteractor, !mLaunchTaskBehind /* toTop */);
/*
*设置正在启动的Activity所属的TaskRecord,
*其实到这儿还没有把当前启动的Activity加入到该TaskRecord中,
*/
mStartActivity.setTask(task,taskToAffiliate);
if (mLaunchBounds != null) {
final intstackId = mTargetStack.mStackId;
if(ActivityManager.StackId.resizeStackWithLaunchBounds(stackId)) {
mService.resizeStack(
stackId, mLaunchBounds, true, !ActivityStackSupervisor.PRESERVE_WINDOWS,ActivityManagerService.ANIMATE, -1);
} else {
mStartActivity.task.updateOverrideConfiguration(mLaunchBounds);
}
}
if (DEBUG_TASKS)Slog.v(ActivityStackSupervisor.TAG_TASKS,
"Starting new activity" +
mStartActivity + " in new task" + mStartActivity.task);
} else {
mStartActivity.setTask(mReuseTask,taskToAffiliate);
}
}
经过上一步正在启动的Activity所以对应的TaskRecord以及ActivityStack已经准备好,那么接下去ActivityStarter中未完成分析。
startActivityUnchecked(){
……
setTaskFromReuseOrCreateNewTask(taskToAffiliate);
if(mSupervisor.isLockTaskModeViolation(mStartActivity.task)) {
Slog.e(TAG,"Attempted Lock Task Mode violation mStartActivity=" +mStartActivity);
return ActivityManager.START_RETURN_LOCK_TASK_MODE_VIOLATION;
}
if(!mMovedOtherTask) {
// If stack idis specified in activity options, usually it means that activity is
// launchednot from currently focused stack (e.g. from SysUI or from shell) - in
// that casewe check the target stack.
/*这是设置对应TaskRecord返回前一个ActivityStack的类型*/
updateTaskReturnToType(mStartActivity.task, mLaunchFlags,
preferredLaunchStackId != ActivityManager.StackId.INVALID_STACK_ID ?mTargetStack : topStack);
}
}
/*
*这个if分支是不需要创建Task,并且调用者不为空
*这个流程对应的也是存在复用Task的情况
*对于本文是以启动Launcher中的HOME应用分析,这部分分支代码可以先忽略*/
else if (mSourceRecord != null) {
if(mSupervisor.isLockTaskModeViolation(mSourceRecord.task)) {
Slog.e(TAG, "AttemptedLock Task Mode violation mStartActivity=" + mStartActivity);
return ActivityManager.START_RETURN_LOCK_TASK_MODE_VIOLATION;
}
/*
*1、首先计算当前启动Activity所归属的ActivityStack
*2、把该ActivityStack移动到前台
*3、其中处理相关的Flag
*4、设置当前启动的Activity的Task
**/
final int result =setTaskFromSourceRecord();
if (result !=ActivityManager.START_SUCCESS) {
return result;
}
} else if (mInTask != null) {
/*对于本文是以启动HOME应用分析,这部分代码先忽略*/
// The caller is asking that thenew activity be started in an explicit
// task it has provided to us.
if(mSupervisor.isLockTaskModeViolation(mInTask)) {
Slog.e(TAG, "AttemptedLock Task Mode violation mStartActivity=" + mStartActivity);
return ActivityManager.START_RETURN_LOCK_TASK_MODE_VIOLATION;
}
/*这个从调用中指定的TaskRecord设定当前Activity所属的TaskRecord**/
final int result =setTaskFromInTask();
if (result !=ActivityManager.START_SUCCESS) {
return result;
}
} else {
// This not being started from anexisting activity, and not part of a new task...
// just put it in the top task,though these days this case should never happen.
setTaskToCurrentTopOrCreateNewTask();
}
mService.grantUriPermissionFromIntentLocked(mCallingUid,mStartActivity.packageName,
mIntent,mStartActivity.getUriPermissionsLocked(), mStartActivity.userId);
/*这个表示从任务列表中启动Activity,
*对于本文是以启动HOME Activity分析不是从最近任务列表中启动*/
if (mSourceRecord != null &&mSourceRecord.isRecentsActivity()) {
mStartActivity.task.setTaskToReturnTo(ActivityRecord.RECENTS_ACTIVITY_TYPE);
}
mTargetStack.mLastPausedActivity =null;
sendPowerHintForLaunchStartIfNeeded(false /* forceSend */);
/*把当前启动的Activity加入TaskRecord以及绑定WindowManagerService*/
mTargetStack.startActivityLocked(mStartActivity, newTask,mKeepCurTransition, mOptions);
。。。。。。。。。。
}
我们进入ActivityStack中的startActivityLocked中分析,代码如下:
final void startActivityLocked(ActivityRecord r, boolean newTask, booleankeepCurTransition, ActivityOptions options) {
TaskRecord rTask = r.task;
/**
* rTask即之前创建的TaskRecord,或者为复用的TaskRecord,
*对于本文是以启动Launcher HOMEActivity它为setTaskFromReuseOrCreateNewTask* 这个创建的TaskRecord
*/
final int taskId = rTask.taskId;
// mLaunchTaskBehind tasks get placedat the back of the task stack.
if (!r.mLaunchTaskBehind &&(taskForIdLocked(taskId) == null || newTask)) {
// Last activity in task had beenremoved or ActivityManagerService is reusing task.
// Insert or replace.
// Might not even be in.
insertTaskAtTop(rTask, r);/*插入新创建或复用的TaskRecord到栈顶*/
mWindowManager.moveTaskToTop(taskId);/*同时在Windowmanager中也移动到栈顶*/
}
TaskRecord task = null;
/*
* 对于本文是以启动Launcher HOMEActivity,这时候是有创建
* 一个新的TaskRecord,所以该分支不走
*/
if (!newTask) {//这是表示存在复用的TaskRecord
// If starting in an existing task,find where that is...
boolean startIt = true;
/**遍历TaskRecord
*从这儿也可以得出TaskRecord在ActivityStack是以栈的方式管理的*/
for (int taskNdx =mTaskHistory.size() - 1; taskNdx >= 0; --taskNdx) {
task =mTaskHistory.get(taskNdx);
if (task.getTopActivity() ==null) {
// All activities in taskare finishing.
continue;
}
/*在Task堆栈中找到了复用的Task*/
if (task == r.task) {
// Here it is! Now, if this is not yet visible to the
// user, then just add itwithout starting; it will
// get started when theuser navigates back to it.
if (!startIt) {
if(ActivityManagerDebugConfig.DEBUG_ADD_REMOVE) Slog.i(TAG, "Adding activity" + r + " to task "
+ task, newRuntimeException("here").fillInStackTrace());
//把当前启动的Activity加入到复用的Task栈顶*/
task.addActivityToTop(r);
r.putInHistory();
/*绑定到windowmanager中*/
addConfigOverride(r,task);
if (VALIDATE_TOKENS) {
validateAppTokensLocked();
}
ActivityOptions.abort(options);
return;
}
break;
} else if (task.numFullscreen> 0) {
startIt = false;
}
}
}
task = r.task;
/**当前启动的Activity加到所属Task栈顶中
*对于本文是以启动Launcher HOMEActivity*/
task.addActivityToTop(r);
/*这个是标记Task中Activity堆栈的堆底Activity元素*/
task.setFrontOfTask();
r.putInHistory();
/*如果当前ActivityStack不为 HomeStack,
*或者该ActivityStack中activity个数不为0
*对于本文是以启动Launcher HOMEActivity,所以该流程不走
*/
if (!isHomeStack() || numActivities()> 0) {
// We want to show the startingpreview window if we are
// switching to a new task, or thenext activity's process is
// not currently running.
boolean showStartingIcon = newTask;
ProcessRecord proc = r.app;
if (proc == null) {
proc =mService.mProcessNames.get(r.processName, r.info.applicationInfo.uid);
}
/*对于刚启动HOME应用时,表示进程ProcessReocrd还为空*/
if (proc == null || proc.thread ==null) {
showStartingIcon = true;
}
if (DEBUG_TRANSITION)Slog.v(TAG_TRANSITION,
"Prepare opentransition: starting " + r);
/*动画相关*/
if ((r.intent.getFlags() &Intent.FLAG_ACTIVITY_NO_ANIMATION) != 0) {
mWindowManager.prepareAppTransition(AppTransition.TRANSIT_NONE,keepCurTransition);
mNoAnimActivities.add(r);
} else {
mWindowManager.prepareAppTransition(newTask
? r.mLaunchTaskBehind
?AppTransition.TRANSIT_TASK_OPEN_BEHIND
:AppTransition.TRANSIT_TASK_OPEN
:AppTransition.TRANSIT_ACTIVITY_OPEN, keepCurTransition);
mNoAnimActivities.remove(r);
}
/*当前启动的Activity绑定到WIndowManagerService当中*/
addConfigOverride(r, task);
boolean doShow = true;
if (newTask) {
// Even though this activity isstarting fresh, we still need
// to reset it to make sure weapply affinities to move any
// existing activities from other tasks into it.
// If the caller has requestedthat the target task be
// reset, then do so.
if ((r.intent.getFlags() &Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED) != 0) {
resetTaskIfNeededLocked(r,r);
doShow =topRunningNonDelayedActivityLocked(null) == r;
}
} else if (options != null&& options.getAnimationType()
==ActivityOptions.ANIM_SCENE_TRANSITION) {
doShow = false;
}
if (r.mLaunchTaskBehind) {
// Don't do a starting windowfor mLaunchTaskBehind. More importantly make sure we
// tell WindowManager that r is visibleeven though it is at the back of the stack.
mWindowManager.setAppVisibility(r.appToken, true);
ensureActivitiesVisibleLocked(null, 0,!ActivityStackSupervisor.PRESERVE_WINDOWS);
} else if(SHOW_APP_STARTING_PREVIEW && doShow) {
// Figure out if we aretransitioning from another activity that is
// "has the same startingicon" as the next one. This allowsthe
// window manager to keep theprevious window it had previously
// created, if it still hadone.
ActivityRecord prev =r.task.topRunningActivityWithStartingWindowLocked();
if (prev != null) {
// We don't want to reusethe previous starting preview if:
// (1) The current activityis in a different task.
if (prev.task != r.task) {
prev = null;
}
// (2) The current activityis already displayed.
else if (prev.nowVisible) {
prev = null;
}
}
r.showStartingWindow(prev,showStartingIcon);
}
} else {
// If this is the first activity,don't do any fancy animations,
// because there is nothing for itto animate on top of.
/*当前启动的Activity绑定到WIndowManagerService当中*/
addConfigOverride(r, task);
ActivityOptions.abort(options);
options = null;
}
if (VALIDATE_TOKENS) {
validateAppTokensLocked();
}
}
经过以上步骤,Task也创建了,也把当前启动的Activity加入到Task正确的位置,
ActivityStack也移动到了正确位置。那么剩下的可以分为两种情况
1、对于当前启动的Activity所属的进程已经创建情况,并且当前正在启动的Activity也已经创建过实例了,那么接下来调用resumed、 paused流程。
2、对于当前启动的Activity还没有实例化,他需要走实例化流程。
对于本文启动Launcher 他是需要先创建一个进程,所以接下去我们介绍,应用程序进程创建的过程。
三、Paused之前Activity、resumed当前启动的Activity过程
这一部分其实对应的是Activity的生命周期,这个会在第五章节《Activity的生命周期》中介绍,目前先以系统刚跑起来,第一次启动Launcher 的HomeActivity作简单分析,这时候只是主要看到如何调用到Launcher的进程启动过程。因为经过前两的步骤,到这儿其实相关的Activity所属的Task 、ActivityStack都是移到了正确位置。
我们继续ActivityStarter中的startActivityUnchecked未分析代码。
startActivityUnchecked()
。。。。。。。。
if (mDoResume) {
if (!mLaunchTaskBehind) {
// TODO(b/26381750): Remove this codeafter verification that all the decision
// points above moved targetStack tothe front which will also set the focus
// activity.
/*
* 设置当前focused,因为经过以上几步,启动的activity已经转移到
*栈顶端,这时候设置AMS当前focused的Activity,对于本文分析
*启动Launcher HomeActivity,这时候focusedActivity即
*为Launcher中的Home Activity
*另外调用这个函数也会有ActivityStack、Task栈的移动,即调用各自栈把当
*前正在启动的Activity所属的Task、ActivityStack移动到栈顶
*/
mService.setFocusedActivityLocked(mStartActivity,"startedActivity");
}
/*这时应该为当前启动的Activity,对于本文即为图二表示的HomeActivity*/
final ActivityRecord topTaskActivity =mStartActivity.task.topRunningActivityLocked();
//当前HomeStack为focusable 所以该分支不走
if (!mTargetStack.isFocusable()
|| (topTaskActivity != null&& topTaskActivity.mTaskOverlay
&& mStartActivity != topTaskActivity)) {
。。。。。。
} else {
//最终调用该函数
mSupervisor.resumeFocusedStackTopActivityLocked(mTargetStack,mStartActivity,
mOptions);
}
} else {
mTargetStack.addRecentActivityLocked(mStartActivity);
}
mSupervisor.updateUserStackLocked(mStartActivity.userId, mTargetStack);
mSupervisor.handleNonResizableTaskIfNeeded(
mStartActivity.task,preferredLaunchStackId, mTargetStack.mStackId);
return ActivityManager.START_SUCCESS;
}
接下来分析一下ActivityStackSupervisor中的resumeFocusedStackTopActivityLocked,因为AMS对于Activity比较复杂的部分即为复用栈时候的处理以及最后这部分的resumed相关操作,这两部分读者最好以假定某种启动模式,并对应着代码进行分析,其实resumeFocusedStackTopActivityLocked这个对应的就是Activity生命周期
中的onPaused->onStopped->onDestory,这个我会在第五章节《Activity生命周期》介绍,这边先简单过一下。
boolean resumeFocusedStackTopActivityLocked(
ActivityStack targetStack, ActivityRecord target,ActivityOptions targetOptions) {
/**如果指定的ActivityStack存在,对于本文分析HOMEActivity启动,targetStack即为HomeStack*/
if(targetStack != null && isFocusedStack(targetStack)) {
//进入
resumeTopActivityUncheckedLocked
return targetStack.resumeTopActivityUncheckedLocked(target, targetOptions);
。。。。。。。
}
接着进入当前启动Activity所属ActivityStack中的resumeTopActivityUncheckedLocked,代码如下:
/**
* Ensure that the top activity in thestack is resumed.
*
* @param prev The previously resumedactivity, for when in the process
* of pausing; can be null to call fromelsewhere.
* @param options Activity options.
*
* @return Returns true if something isbeing resumed, or false if
* nothing happened.
*
* NOTE: It is not safe to call this methoddirectly as it can cause an activity in a
* non-focused stack to be resumed.
* Use {@link ActivityStackSupervisor#resumeFocusedStackTopActivityLocked}to resume the
* right activity for the current system state.
*/
boolean resumeTopActivityUncheckedLocked(ActivityRecord prev, ActivityOptions options){
。。。。。。
//进入resumeTopActivityInnerLocked
result =resumeTopActivityInnerLocked(prev, options);
return result;
}
代码比较简单进入resumeTopActivityInnerLocked,这个函数代码比较长,大伙多看几遍。代码如下:
private boolean resumeTopActivityInnerLocked(ActivityRecord prev, ActivityOptionsoptions) {
。。。。。。。
// Find the first activity that is notfinishing.
/*
*首先获取当前ActivityStack中栈顶Activity
*对于本文分析第一次启动Launcher 该next即为Launcher的HomeActivity
*/
final ActivityRecord next =topRunningActivityLocked();
//Remember how we'll process thispause/resume situation, and ensure
// that the state is reset however wewind up proceeding.
/*这个变量是表示是否回调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 Stringreason = "noMoreActivities";
final int returnTaskType = prevTask ==null || !prevTask.isOverHomeStack()
?ActivityRecord.HOME_ACTIVITY_TYPE : prevTask.getTaskToReturnTo();
if (!mFullscreen &&adjustFocusToNextFocusableStackLocked(returnTaskType, reason)) {
// Try to move focus to thenext visible stack with a running activity if this
// stack is not covering theentire screen.
returnmStackSupervisor.resumeFocusedStackTopActivityLocked(
mStackSupervisor.getFocusedStack(), prev, null);
}
// Let's just start up theLauncher...
ActivityOptions.abort(options);
if (DEBUG_STATES)Slog.d(TAG_STATES,
"resumeTopActivityLocked:No more activities go home");
if (DEBUG_STACK)mStackSupervisor.validateTopActivitiesLocked();
// Only resume home if on homedisplay
return isOnHomeDisplay() && mStackSupervisor.resumeHomeStackTask(returnTaskType,prev, reason);
}
next.delayedResume= false;
// If the top activity is the resumedone, nothing to do.
/*这个是如果当前ActivityStack的resumedActivity即为栈顶第一个未finish的Activity,那么表示已经resumed过了就不继续以下的处理*/
if(mResumedActivity == next && next.state == ActivityState.RESUMED&&
mStackSupervisor.allResumedActivitiesComplete()) {
// Make sure we have executed anypending transitions, since there
// should be nothing left to do atthis point.
mWindowManager.executeAppTransition();
mNoAnimActivities.clear();
ActivityOptions.abort(options);
if (DEBUG_STATES)Slog.d(TAG_STATES,
"resumeTopActivityLocked: Top activity resumed " + next);
if (DEBUG_STACK)mStackSupervisor.validateTopActivitiesLocked();
return false;
}
final TaskRecord nextTask = next.task;
/*这个是对上一个resumed的Activity的相关处理
*针对本文第一次启动Launcher,HomeActivity即prev的finishing为false
*/
if (prevTask!= null && prevTask.stack == this &&
prevTask.isOverHomeStack()&& prev.finishing && prev.frontOfTask) {
。。。。。。。。。。
}
}
// If we aresleeping, and there is no resumed activity, and the top
// activity is paused, well that is thestate we want.
if(mService.isSleepingOrShuttingDownLocked()
&& mLastPausedActivity == next
&& mStackSupervisor.allPausedActivitiesComplete()) {
// Make sure we have executed anypending transitions, since there
// should be nothing left to do atthis point.
mWindowManager.executeAppTransition();
mNoAnimActivities.clear();
ActivityOptions.abort(options);
if (DEBUG_STATES) Slog.d(TAG_STATES,
"resumeTopActivityLocked: Going to sleep and all paused");
if (DEBUG_STACK)mStackSupervisor.validateTopActivitiesLocked();
return false;
}
。。。。。。。。
// The activity may be waiting for stop, but thatis no longer
// appropriate for it.
mStackSupervisor.mStoppingActivities.remove(next);
mStackSupervisor.mGoingToSleepActivities.remove(next);
next.sleeping = false;
mStackSupervisor.mWaitingVisibleActivities.remove(next);
if (DEBUG_SWITCH) Slog.v(TAG_SWITCH,"Resuming " + next);
// If we are currently pausing an activity,then don't do anything until that is done.
if(!mStackSupervisor.allPausedActivitiesComplete()) {
if (DEBUG_SWITCH || DEBUG_PAUSE ||DEBUG_STATES) Slog.v(TAG_PAUSE,
"resumeTopActivityLocked: Skip resume: some activitypausing.");
if (DEBUG_STACK)mStackSupervisor.validateTopActivitiesLocked();
return false;
}
mStackSupervisor.setLaunchSource(next.info.applicationInfo.uid);
// We need tostart pausing the current activity so the top one can be resumed...
final boolean dontWaitForPause =(next.info.flags& FLAG_RESUME_WHILE_PAUSING) != 0;
/**这个是pause掉不是FocusedStack的其它ActivityStack的栈顶activity*/
*对于不是当前focusStack的并且存在有mResumedActivity不为null的都要paused
*/
boolean pausing =mStackSupervisor.pauseBackStacks(userLeaving, next, dontWaitForPause);
/*
*这个表示该ActivityStack已经存在resumedActivity
*但是对于本文介绍启动Launcher HOMEActivity时其实到这儿HOME Activity还未实例化,*此时HomeStack中还不存在有 *Activity,这时候该mResumed为null,读者可以先跳过
*/
if (mResumedActivity != null) {
。。。。。。。。。
}
/*对于第一次启动HOME应用pausing为false
*读者可以跳过
*/
if (pausing) {
。。。。。。。
return true;
} else if (
//针对本文分析第一次启动Launcher HomeActivity,此时mResumedAcitivyt还
//为null ,并且next.state状态还为INITIATION,这步可以先跳过
mResumedActivity == next
&&next.state == ActivityState.RESUMED
&&mStackSupervisor.allResumedActivitiesComplete()){
。。。。。。。。。。
return true;
}
// If the most recent activity was noHistory butwas only stopped rather
// than stopped+finished because thedevice went to sleep, we need to make
// sure to finish it as we're making anew activity topmost.
/**
*如果此时处于屏幕灭屏状态,并且当前Resumed的Activity设置了Intent.FLAG_ACTIVITY_NO_HISTORY
*那么需要finish此Activity
*/
if (mService.isSleepingLocked()&& mLastNoHistoryActivity != null &&
!mLastNoHistoryActivity.finishing) {
if (DEBUG_STATES)Slog.d(TAG_STATES,
"no-history finish of" + mLastNoHistoryActivity + " on new resume");
requestFinishActivityLocked(mLastNoHistoryActivity.appToken,Activity.RESULT_CANCELED,
null,"resume-no-history", false);
mLastNoHistoryActivity = null;
}
/*对于第一次启动HOME应用prev和next是相同
*读者可以先跳过
*/
if (prev != null && prev !=next) {
。。。。。。
}
。。。。。。。
// We are starting up the nextactivity, so tell the window manager
// that the previous one will be hiddensoon. This way it can know
// to ignore it when computing thedesired screen orientation.
boolean anim = true;
if (mIsAnimationBoostEnabled == true&& mPerf == null) {
mPerf = new BoostFramework();
}
if (prev != null) {//这边是准备相关的动画
if (prev.finishing) {
if (DEBUG_TRANSITION)Slog.v(TAG_TRANSITION,
"Prepare closetransition: prev=" + prev);
if(mNoAnimActivities.contains(prev)) {
anim = false;
mWindowManager.prepareAppTransition(AppTransition.TRANSIT_NONE, false);
} else {
mWindowManager.prepareAppTransition(prev.task == next.task
?AppTransition.TRANSIT_ACTIVITY_CLOSE
:AppTransition.TRANSIT_TASK_CLOSE, false);
}
mWindowManager.setAppVisibility(prev.appToken, false);
} else {
if (DEBUG_TRANSITION)Slog.v(TAG_TRANSITION,
"Prepare opentransition: prev=" + prev);
if(mNoAnimActivities.contains(next)) {
anim = false;
mWindowManager.prepareAppTransition(AppTransition.TRANSIT_NONE, false);
} else {
mWindowManager.prepareAppTransition(prev.task == next.task
?AppTransition.TRANSIT_ACTIVITY_OPEN
:next.mLaunchTaskBehind
?AppTransition.TRANSIT_TASK_OPEN_BEHIND
:AppTransition.TRANSIT_TASK_OPEN, false);
}
}
} else {
if(DEBUG_TRANSITION) Slog.v(TAG_TRANSITION, "Prepare open transition: noprevious");
if (mNoAnimActivities.contains(next)){
anim = false;
mWindowManager.prepareAppTransition(AppTransition.TRANSIT_NONE, false);
} else {
mWindowManager.prepareAppTransition(AppTransition.TRANSIT_ACTIVITY_OPEN,false);
}
}
Bundler esumeAnimOptions = null;
if (anim) {
ActivityOptions opts =next.getOptionsForTargetActivityLocked();
if (opts != null) {
resumeAnimOptions =opts.toBundle();
}
next.applyOptionsLocked();
} else {
next.clearOptionsLocked();
}
ActivityStack lastStack =mStackSupervisor.getLastStack();
/**
*如果当前ActivityStack中,此时处于Task最顶端的Activity已经创建过了并且已经纳入相
*应的进程中,那么进入该Activity的resumed过程。
*举个例子:比如你已经通过Launcher启动了应用2中的Activity A,这时候按HOME键
*返回到Launcher桌面,这时你又点击Launcher上应用2的图标,这时候就会调用onResumed
*对于本文第一次启动Launcher HOME Activity next.app为null即还没有创建对应的进程
*读者可以先跳过这一步
*/
if (next.app != null &&next.app.thread != null) {
。。。。。。。。。
return true;
}
} else {
// Whoops, need to restart thisactivity!
if (!next.hasBeenLaunched) {
next.hasBeenLaunched = true;
} else {
if (SHOW_APP_STARTING_PREVIEW){
next.showStartingWindow(null, true);
}
}
//对于本文第一次启动Launcher HOMEActivity或者第一次启动其它应用,最终调用这边开//始创建应用对应的进程
mStackSupervisor.startSpecificActivityLocked(next, true, true);
}
if (DEBUG_STACK)mStackSupervisor.validateTopActivitiesLocked();
return true;
}
以上就是对于当前启动的Activity已经纳入到对应的进程时,paused之前的Activity以及resumed当前启动的Activity过程,这种情况下并没有Activity创建过程,因为他之前已经创建过了,这也符合应用开发过程中所说的Actiivity从后台到前台会调用Activity生命周期的onResumed函数。
四、进程的创建
针对本文paused之前Activity、resumed当前启动的Activity过程这一章节,主要是针对当前启动Activity已经创建的过程的分析,那么对于第一次启动过程,比如从Launcer桌面点击图标启动一个应用时,它是需要为它创建一个对应的进程的,本章节就介绍下一个应用对应的进程创建过程。
我们接着第三章节写的跟踪进入ActivityStackSupervisor中的startSpecificActivityLocked,代码如下:
void startSpecificActivityLocked(ActivityRecord r, boolean andResume, booleancheckConfig) {
// Is this activity's applicationalready running?
/*
*根据Activity的processName(该值在应用AndroidManifest.xml中
*android:process定义,如果未定义则默认为当前应用包名)在AMS查询当前启动*的Activity对应的进程是否存
* 存在,对于本文第一次启动Launcher或者其它第一次启动应用时,app为null
*/
ProcessRecord app =mService.getProcessRecordLocked(r.processName,
r.info.applicationInfo.uid,true);
r.task.stack.setLaunchTime(r);
/*对于第一次启动HOME应用或第一次启动其它应用,因为还没有创建对应的进程
*所以app此时为null
*读者可以无跳过这一步
*/
if (app != null && app.thread!= null) {
try {
if ((r.info.flags&ActivityInfo.FLAG_MULTIPROCESS)== 0
||!"android".equals(r.info.packageName)) {
// Don't add this if it isa platform component that is marked
// to run in multipleprocesses, because this is actually
// part of the framework sodoesn't make sense to track as a
// separate apk in theprocess.
app.addPackage(r.info.packageName, r.info.applicationInfo.versionCode,
mService.mProcessStats);
}
/*如果当前启动的Activity所属的进程已经存在,那么调用
* 该函数只开始Activity初始化生命周期,而不需要再重新创建进程。
*/
realStartActivityLocked(r, app,andResume, checkConfig);
return;
} catch (RemoteException e) {
Slog.w(TAG, "Exceptionwhen starting activity "
+r.intent.getComponent().flattenToShortString(), e);
}
}
//如果当前启动的Activity所属的进程还未创建,这边调用AMS为启动的Activity创建进程
mService.startProcessLocked(r.processName,r.info.applicationInfo, true, 0,
"activity",r.intent.getComponent(), false, false, true);
}
关于AMS中进程创建的我会忽略相关代码,抓住创建进程的主线,进入AMS中的startProcessLocked,最终调用到以下函数
final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
boolean knownToBeDead, intintentFlags, String hostingType, ComponentName hostingName,
boolean allowWhileBooting, booleanisolated, int isolatedUid, boolean keepIfLarge,
String abiOverride, StringentryPoint, String[] entryPointArgs, Runnable crashHandler) {
//相关代码各位读者可以自行分析
long startTime =SystemClock.elapsedRealtime();
ProcessRecord app;
。。。。。。
//对于第一次启动应用此时app为null
if (app != null && app.pid >0) {
。。。。。。
}
。。。。。。
if (app == null) {
//这时候创建用来描述应用进程ProcessRecord
app = newProcessRecordLocked(info,processName, isolated, isolatedUid);
。。。。。。
}
。。。。。。
startProcessLocked(
app, hostingType,hostingNameStr, abiOverride, entryPoint, entryPointArgs);
checkTime(startTime,"startProcess: done starting proc!");
return (app.pid != 0) ? app : null;
}
进入newProcessRecordLocked分析一下
final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,boolean isolated, int isolatedUid) {
String proc =customProcess != null ? customProcess : info.processName;
BatteryStatsImpl stats =mBatteryStatsService.getActiveStatistics();
final int userId =UserHandle.getUserId(info.uid);
int uid = info.uid;
。。。。。。。。
}
/**这时候开始创建ProcessRecord对象
*创建的ProcessRecord会保存AMS中的mProcessNames和mPidsSelfLocked这两个
*变量中,记住这两个变量,此时用来描述进程ProcessRecord所表示已经创建
*OK,因为下面在创建Android主线程ActivityThread时
*会用到此时创建的ProcessRecord
*/
final ProcessRecordr = new ProcessRecord(stats, info, proc, uid);
if (!mBooted && !mBooting
&& userId == UserHandle.USER_SYSTEM
&& (info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
r.persistent = true;
}
//保存创建的ProcessRecord到变量mProcessNames
addProcessNameLocked(r);
}
分析完newProcessRecordLocked接着进入
startProcessLocked(
app, hostingType,hostingNameStr, abiOverride, entryPoint, entryPointArgs);
。。。。。。
boolean isActivityProcess =(entryPoint == null);
//这个很重要,我们知道Android应用都存在一个应用主线ActivityThread即表示主线程
if (entryPoint == null) entryPoint= "android.app.ActivityThread";
//这边开始正式创建进程
Process.ProcessStartResultstartResult = Process.start(entryPoint,
app.processName,uid, uid, gids, debugFlags, mountExternal,
app.info.targetSdkVersion,app.info.seinfo, requiredAbi, instructionSet,
app.info.dataDir,entryPointArgs);
。。。。。。
if (oldApp !=null && !app.isolated) {
// Clean up anything relatingto this pid first
Slog.w(TAG, "Reusing pid" + startResult.pid
+ " while app isstill mapped to it");
cleanUpApplicationRecordLocked(oldApp, false, false, -1,
true /*replacingPid*/);
}
synchronized (mPidsSelfLocked) {
//把创建的ProcessRecord保存到mPidsSelfLocked变量中,
this.mPidsSelfLocked.put(startResult.pid,app);
if (isActivityProcess) {
Message msg =mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
msg.obj = app;
mHandler.sendMessageDelayed(msg, startResult.usingWrapper
?PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
}
}
。。。。。。。。
}
经过以上步骤,AMS中表示应用进程的ProcessRecord已经创建完毕,并且保存在了AMS中的mProcessNames、mPidsSelfLocked这两个变量当中。关于Process.start这块的大家可以上网看下关于Android中zygote如何创建进程的步骤,这边就不列了,本文的目的是梳理Activity的创建,最终进程创建OK之后他会调用ActivityThread中的main函数,这边说下ActivityThread中比较重要的变量。
/**这个mAppThread变量是和ProcessRecord以及AMS进行通信的*/
finalApplicationThread mAppThread = new ApplicationThread();
我们看下ActivityThread中的main函数代码如下:
public static void main(String[] args) {
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER,"ActivityThreadMain");
SamplingProfilerIntegration.start();
// CloseGuard defaults to true and canbe quite spammy. We
// disable it here, but selectivelyenable it later (via
// StrictMode) on debug builds, butusing DropBox, not logs.
CloseGuard.setEnabled(false);
Environment.initForCurrentUser();
// Set the reporter for event loggingin libcore
EventLogger.setReporter(new EventLoggingReporter());
// Make sure TrustedCertificateStorelooks in the right place for CA certificates
final File configDir =Environment.getUserConfigDirectory(UserHandle.myUserId());
TrustedCertificateStore.setDefaultUserDirectory(configDir);
Process.setArgV0("<pre-initialized>");
Looper.prepareMainLooper();
ActivityThread thread = newActivityThread();
//调用attach,记住传入的是参数为false
thread.attach(false);
if (sMainThreadHandler == null) {
sMainThreadHandler =thread.getHandler();
}
。。。。。。
}
进入ActivityThread的attach函数
private void attach(boolean system) {
ViewRootImpl.addFirstDrawHandler(newRunnable() {
@Override
public void run() {
ensureJitEnabled();
}
});
android.ddm.DdmHandleAppName.setAppName("<pre-initialized>",
UserHandle.myUserId());
RuntimeInit.setApplicationObject(mAppThread.asBinder());
final IActivityManager mgr =ActivityManagerNative.getDefault(); try{
=//注意传入的变量为IBinder类型的mAppThread
mgr.attachApplication(mAppThread);
} catch(RemoteException ex) {
throwex.rethrowFromSystemServer();
}
BinderInternal.addGcWatcher(newRunnable() {
@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 {
mgr.releaseSomeActivities(mAppThread);
} catch(RemoteException e) {
throwe.rethrowFromSystemServer();
}
}
}
});
} else {//此时传入的参数为false以下分支先忽略,该分支是在AMS初始化
//的时候进入该分支
。。。。。。
}
}
这部分代码逻辑还是比较简单,读者自行看下,接着进入AMS中的attachApplication函数
@Override
public final voidattachApplication(IApplicationThread thread) {
synchronized (this) {
int callingPid =Binder.getCallingPid();
final long origId =Binder.clearCallingIdentity();
attachApplicationLocked(thread, callingPid);
Binder.restoreCallingIdentity(origId);
}
}
接着进入AMS的attachApplicationLocked,代码如下:
private finalboolean attachApplicationLocked(
IApplicationThread thread,//该参数为ActivityThread中的mAppThread
int pid) {
// Find theapplication record that is being attached... either via
// the pid if we are running inmultiple processes, or just pull the
// next app record if we are emulatingprocess with anonymous threads.
ProcessRecord app;
if (pid != MY_PID && pid >=0) {
synchronized (mPidsSelfLocked) {
/**因为之前AMS中的startProcessLocked中已经创建应用对应的ProcessRecord,并且保存**在mPidsSelfLocked
*忘记的可以看AMS中的startProcessLocked
*/
app = mPidsSelfLocked.get(pid);
}
} else {
app = null;
}
//这时候已经创建了,此时app不为null
if (app == null) {
Slog.w(TAG,"No pending application record for pid " + pid
+ "(IApplicationThread " + thread + "); dropping process");
EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS,pid);
if (pid > 0 && pid !=MY_PID) {
Process.killProcessQuiet(pid);
//TODO:killProcessGroup(app.info.uid, pid);
} else {
try {
thread.scheduleExit();
} catch (Exception e) {
// Ignore exceptions.
}
}
return false;
}
。。。。。。
/*
*这边是设置ProcessRecord与ActivityThread进行通信的Ibinder对象,而ProcessRecord
*在AMS中所以通过thread就建立了AMS和应用主线程ActivityThread的通信
* thread即为ActivityThread中的mAppThread
*/
app.makeActive(thread,mProcessStats);
。。。。。。
/*
*我们知道thread即为ActivityThread中的mAppThread所以这时候回调
* ActivityThread中的bindApplication
*/
thread.bindApplication(processName,appInfo, providers, app.instrumentationClass,
profilerInfo,
app.instrumentationArguments,app.instrumentationWatcher,
app.instrumentationUiAutomationConnection, testMode,
mBinderTransactionTrackingEnabled, enableTrackAllocation,
isRestrictedBackupMode ||!normalMode, app.persistent,
newConfiguration(mConfiguration), app.compat,
getCommonServicesLocked(app.isolated),
mCoreSettingsObserver.getCoreSettingsLocked());
updateLruProcessLocked(app, false,null);
。。。。。。。
}
这时候进入ActivityThread中的bindApplication代码如下:
public final void bindApplication(String processName, ApplicationInfo appInfo,
List<ProviderInfo>providers, ComponentName instrumentationName,
ProfilerInfo profilerInfo,Bundle instrumentationArgs,
IInstrumentationWatcherinstrumentationWatcher,
IUiAutomationConnectioninstrumentationUiConnection, int debugMode,
boolean enableBinderTracking,boolean trackAllocation,
boolean isRestrictedBackupMode,boolean persistent, Configuration config,
CompatibilityInfo compatInfo,Map<String, IBinder> services, Bundle coreSettings) {
if (services != null) {
// Setup the service cache inthe ServiceManager
ServiceManager.initServiceCache(services);
}
setCoreSettings(coreSettings);
AppBindData data = newAppBindData();
data.processName = processName;
data.appInfo = appInfo;
data.providers = providers;
data.instrumentationName =instrumentationName;
data.instrumentationArgs = instrumentationArgs;
data.instrumentationWatcher =instrumentationWatcher;
data.instrumentationUiAutomationConnection =instrumentationUiConnection;
data.debugMode = debugMode;
data.enableBinderTracking = enableBinderTracking;
data.trackAllocation =trackAllocation;
data.restrictedBackupMode =isRestrictedBackupMode;
data.persistent = persistent;
data.config = config;
data.compatInfo = compatInfo;
data.initProfilerInfo = profilerInfo;
sendMessage(H.BIND_APPLICATION,data);
}
在这个函数中设置完相应的参数,通过Handler最终调用的函数是handleBindApplication
private voidhandleBindApplication(AppBindData data) {
// Register the UI Thread as asensitive thread to the runtime.
//这也是一堆代码,读者对着代码自行分析,这边先删除太占篇幅
。。。。。。
/*
* Before spawning a new process, resetthe time zone to be the system time zone.
* This needs to be done because thesystem 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 changeonce we create the App Context.
*/
LocaleList.setDefault(data.config.getLocales());
synchronized (mResourcesManager) {
/*
* Update the system configurationsince its preloaded and might not
* reflect configuration changes.The configuration object passed
* in AppBindData can be safelyassumed to be up to date
*/
mResourcesManager.applyConfigurationToResourcesLocked(data.config,data.compatInfo);
mCurDefaultDisplayDpi =data.config.densityDpi;
// This calls mResourcesManager sokeep it within the synchronized block.
applyCompatConfiguration(mCurDefaultDisplayDpi);
}
/* 这边为进程创建了一个LoadApk对象并且保存在mPackages变量当中,
* LoadApk主要用于应用的相关的resDir、libDir相关资源的东西,
* 但是此时LoadApk的ClassLoader为null
*/
data.info = getPackageInfoNoCheck(data.appInfo,data.compatInfo);
。。。。。。。
final boolean is24Hr ="24".equals(mCoreSettings.getString(Settings.System.TIME_12_24));
DateFormat.set24HourTimePref(is24Hr);
。。。。。。
// Allow application-generated systracemessages if we're debuggable.
// Instrumentation info affects theclass loader, so load it before
// setting up the app context.
final InstrumentationInfo ii;
if (data.instrumentationName != null) {
try {
ii = newApplicationPackageManager(null, getPackageManager())
.getInstrumentationInfo(data.instrumentationName,0);
} catch(PackageManager.NameNotFoundException e) {
throw new RuntimeException(
"Unable to findinstrumentation info for: " + data.instrumentationName);
}
mInstrumentationPackageName =ii.packageName;
mInstrumentationAppDir =ii.sourceDir;
mInstrumentationSplitAppDirs =ii.splitSourceDirs;
mInstrumentationLibDir =getInstrumentationLibrary(data.appInfo, ii);
mInstrumentedAppDir =data.info.getAppDir();
mInstrumentedSplitAppDirs =data.info.getSplitAppDirs();
mInstrumentedLibDir =data.info.getLibDir();
} else {
ii = null;
}
//这边开始创建Context大家在开发过程经常使用到的Context上下文了
final ContextImpl appContext =ContextImpl.createAppContext(this, data.info);
updateLocaleListFromAppContext(appContext,
mResourcesManager.getConfiguration().getLocales());
。。。。。。。
// Continue loading instrumentation.
/*
* 1、创建Instrument
* Instrument这个大家在开发过程使用的比较少,这个有点儿类似Android应
*的工具类,对于Activity所有的生命周期比如onCreate、onResume都是通过该
*instrumetn进行分发调用
* 这边说明下如果不是自定义的Instrument此时ii为null,对于自定义的Instrument
* 是通过Context的startInstrumentation来启动一个进程,这时候ii就不会为null了
*/
if (ii != null) {
final ApplicationInfo instrApp = new ApplicationInfo();
ii.copyTo(instrApp);
instrApp.initForUser(UserHandle.myUserId());
final LoadedApk pi =getPackageInfo(instrApp, data.compatInfo,
appContext.getClassLoader(), false, true, false);
final ContextImpl instrContext =ContextImpl.createAppContext(this, pi)
try {
final ClassLoader cl =instrContext.getClassLoader()
mInstrumentation =(Instrumentation)
cl.loadClass(data.instrumentationName.getClassName()).newInstance();
} catch (Exception e) {
throw new RuntimeException(
"Unable to instantiateinstrumentation "
+ data.instrumentationName+ ": " + e.toString(), e);
}
final ComponentName component = new ComponentName(ii.packageName, ii.name);
mInstrumentation.init(this,instrContext, appContext, component,
data.instrumentationWatcher,data.instrumentationUiAutomationConnection);
if (mProfiler.profileFile != null&& !ii.handleProfiling
&&mProfiler.profileFd == null) {
mProfiler.handlingProfiling =true;
final File file = newFile(mProfiler.profileFile);
file.getParentFile().mkdirs();
Debug.startMethodTracing(file.toString(), 8 * 1024 * 1024);
}
} else {
mInstrumentation = newInstrumentation();
}
。。。。。。。ActivityClientRecord
// Allow disk access during applicationand provider setup. This could
// block processing ordered broadcasts,but later processing would
// probably end up doing the same diskaccess.
final StrictMode.ThreadPolicysavedPolicy = StrictMode.allowThreadDiskWrites();
try {
// If the app is being launched forfull backup or restore, bring it up in
// a restricted environment withthe base application class.
/**
* 2、创建Application
* 对于应用开发者可能会在应用中重载类Application,
* 而这个Application一个应用只存在一个,这儿即创建Application
*/
Application app =data.info.makeApplication(data.restrictedBackupMode, null);
mInitialApplication = app;
// don't bring up providers inrestricted mode; they may depend on the
// app's custom Application class
if (!data.restrictedBackupMode) {
if(!ArrayUtils.isEmpty(data.providers)) {
installContentProviders(app,data.providers);
// For process thatcontains content providers, we want to
// ensure that the JIT isenabled "at some point".
mH.sendEmptyMessageDelayed(H.ENABLE_JIT,10*1000);
}
}
// Do this after providers, sinceinstrumentation tests generally start their
// test thread at this point, andwe don't want that racing.
try {
mInstrumentation.onCreate(data.instrumentationArgs);
}
catch (Exception e) {
throw new RuntimeException(
"Exception thrown inonCreate() 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 createapplication " + app.getClass().getName()
+ ": " +e.toString(), e);
}
}
} finally {
StrictMode.setThreadPolicy(savedPolicy);
}
}
这边我们得分析一下,
Application app =data.info.makeApplication(data.restrictedBackupMode, null);因为这里边涉及很多重要的东西,主要为应用程序中的Application创建Context、LoadApk。我们进入LoadApk中的makeApplication代码如下:
public Application makeApplication(boolean forceDefaultAppClass,
Instrumentation instrumentation) {
if (mApplication != null) {
return mApplication;
}
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER,"makeApplication");
Application app = null;
String appClass =mApplicationInfo.className;
//对于应用未重载Application时,默认为android.app.Application
if (forceDefaultAppClass || (appClass== null)) {
appClass ="android.app.Application";
}
try {
java.lang.ClassLoader cl =getClassLoader();
if(!mPackageName.equals("android")) {
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER,
"initializeJavaContextClassLoader");
initializeJavaContextClassLoader();
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
}
/*
* 创建ContextImple对象
*/
ContextImpl appContext =ContextImpl.createAppContext(mActivityThread, this);
/*
*为当前启动的应用创建Application这部分作用
*1、把上一步创建的appContext绑定到了ContextWrapper中mBase中
*2、把当前LoadedApk绑定到应用ApplicationmLoadedApk
*3、必须把创建的Application保存到LoadedApk当中
*/
app =mActivityThread.mInstrumentation.newApplication(
cl, appClass, appContext);
appContext.setOuterContext(app);
} catch (Exception e) {
if(!mActivityThread.mInstrumentation.onException(app, e)) {
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
throw new RuntimeException(
"Unable to instantiateapplication " + appClass
+ ": " + e.toString(),e);
}
}
mActivityThread.mAllApplications.add(app);
mApplication = app;
if (instrumentation != null) {
try {
instrumentation.callApplicationOnCreate(app);
} catch (Exception e) {
if(!instrumentation.onException(app, e)) {
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
throw new RuntimeException(
"Unable to createapplication " + app.getClass().getName()
+ ": " +e.toString(), e);
}
}
}
// Rewrite the R 'constants' for alllibrary apks.
SparseArray<String>packageIdentifiers = getAssets(mActivityThread)
.getAssignedPackageIdentifiers();
final int N =packageIdentifiers.size();
for (int i = 0; i < N; i++) {
final int id =packageIdentifiers.keyAt(i);
if (id == 0x01 || id == 0x7f) {
continue;
}
rewriteRValues(getClassLoader(),packageIdentifiers.valueAt(i), id);
}
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
return app;
}
经过以上几步,应用中所涉及到的Instrument、Application以有Application中的Context、LoadedApk相关的就已经都准备好了,此时还没有到Activity的生命周期当中,我们继续往下。。。。接下来返回继续AMS的attachApplicationLocked之后的流程。
private final boolean attachApplicationLocked(IApplicationThread thread,
int pid) {
。。。。。。
// See if the top visible activity iswaiting to run in this process...
if (normalMode) {
try {
if(mStackSupervisor.attachApplicationLocked(app)) {
didSomething = true;
}
} catch (Exception e) {
Slog.wtf(TAG,"Exception thrown launching activities in " + app, e);
badApp = true;
}
}
。。。。。。
}
进入ActivityStackSupervisor中的attachApplicationLocked代码如下
boolean attachApplicationLocked(ProcessRecord app) throws RemoteException {
final StringprocessName = app.processName;
boolean didSomething = 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)) {
continue;
}
ActivityRecord hr =stack.topRunningActivityLocked();
/*因为在ActivityStarter中的startActivityUnchecked,即在本文第二章节<计算Activity所属的*Task、 *ActivityStack,及操作>中已经把要启动Activity所属的
*ActivityStack以及TaskRecord移动到栈顶了,那么时候hr即为当前要启动的
*Activity,本文是分析HOME应用,所以hr即为homeActivity
*/
if (hr !=null) {
if (hr.app == null&& app.uid == hr.info.applicationInfo.uid
&&processName.equals(hr.processName)) {
try {
//这时候真正开始Activity的初始化生命周期
if(realStartActivityLocked(hr, app, true, true)) {
didSomething =true;
}
} catch(RemoteException e) {
Slog.w(TAG,"Exception in new application when starting activity "
+hr.intent.getComponent().flattenToShortString(), e);
throw e;
}
}
}
if (!didSomething) {
ensureActivitiesVisibleLocked(null,0, !PRESERVE_WINDOWS);
}
return didSomething;
}
这一章节主要流程是在AMS创建描述进程信息的ProcessRecord,并且保存到AMS中,
并且通过zygote进程来真正创建进程,此过程完成了应用主线程ActivityThread创建、应用Application的创建、Context的创建、LoadApk这些重要类的创建。但到这步Activity初始化流程其实还没有开始,这一部顶多完成了Acitivty初始化的准备工作。Activity生命周期介绍
这一章节是所以Activity都会经历的生命周期。
我们知道activity的生命周期为onCreate->onStart->onResumed->running->onPaused->onStopped->onDestroy。这章节我们分析Activity生命周期分成两部分来介绍。
1、Activity创建过程的生命周期onCreate->onStart->onResumed
这个过程在Activity初始化完成。 我们在第四章节介绍进程创建开头有提到ActivityStackSupervisor中的startSpecificActivityLocked这个函数中,如果当前启动的Activity所属的进程信息已经创建过了,那么直接调用realStartActivityLocked进入Activity初始化生命周期,对于第四章节介绍进程创建的最后对于新建的进程最终也会调用realStartActivityLocked进入Activity初始化生命周期。忘记的读者可以返回第四章节最后一部分回顾一下。
进入ActivityStackSupervisor中的realStartActivityLocked,代码如下:
final boolean realStartActivityLocked(ActivityRecord r, ProcessRecord app,
boolean andResume, booleancheckConfig) throws RemoteException {
。。。。。。
//当前启动的Activity保存AMS中对Activity进程描述的ProcessRecord信息
r.app = app;
app.waitingToKill= null;
r.launchCount++;
r.lastLaunchTime= SystemClock.uptimeMillis();
if (DEBUG_ALL) Slog.v(TAG,"Launching: " + r);
int idx = app.activities.indexOf(r);
//如果当前启动的Activty还不存在ProcessRecord中,则把它加到ProcessRecord中
if (idx < 0) {
app.activities.add(r);
}
。。。。。。
final ActivityStack stack = task.stack;
。。。。。。
if (r.isHomeActivity()) {
// Home process is the rootprocess of the task.
mService.mHomeProcess =task.mActivities.get(0).app;
}
/**
*我们之前在创建ProcessRecord时候,知道thread即为ActivityThread中的mAppThread,
*这时我们进入ActivityThread中
* 这步开始Activity初始化流程。。。
*/
app.thread.scheduleLaunchActivity(
new Intent(r.intent), r.appToken,
System.identityHashCode(r),
r.info, new Configuration(mService.mConfiguration),
newConfiguration(task.mOverrideConfig),
r.compat, r.launchedFromPackage,
task.voiceInteractor, app.repProcState, r.icicle,r.persistentState, results,
newIntents, !andResume,mService.isNextTransitionForward(), profilerInfo);
。。。。。。
}
各位读者,这时候流程跑到这儿,马上就能够看到Activity的生命周期了,大家喝口水继续
进入ActivityThread中scheduleLaunchActivity,代码如下:
//we usetoken to identify this activity without having to send the
// activity itself back to the activitymanager. (matters more with ipc)
@Override
public final voidscheduleLaunchActivity(Intent intent, IBinder token, int ident,
ActivityInfo info,Configuration curConfig, Configuration overrideConfig,
CompatibilityInfo compatInfo,String referrer, IVoiceInteractor voiceInteractor,
int procState, Bundle state,PersistableBundle persistentState,
List<ResultInfo>pendingResults, List<ReferrerIntent> pendingNewIntents,
boolean notResumed, booleanisForward, ProfilerInfo profilerInfo) {
updateProcessState(procState,false);
ActivityClientRecord r = newActivityClientRecord();
r.token =token;
r.ident =ident;
r.intent =intent;
r.referrer =referrer;
r.voiceInteractor= voiceInteractor;
r.activityInfo= info;
r.compatInfo =compatInfo;
r.state =state;
r.persistentState= persistentState;
r.pendingResults= pendingResults;
r.pendingIntents= pendingNewIntents;
r.startsNotResumed= notResumed;
r.isForward =isForward;
r.profilerInfo= profilerInfo;
r.overrideConfig= overrideConfig;
updatePendingConfiguration(curConfig);
sendMessage(H.LAUNCH_ACTIVITY,r);
}
通过Handler调用
r.packageInfo =getPackageInfoNoCheck(r.activityInfo.applicationInfo,r.compatInfo);
获取LoadApk,Application在创建进程时候调用makeApplication已经创建,这时候不会再重新创建一个,而是直接采用之前创建的,然后调用handleLaunchActivity,代码如下:
private void handleLaunchActivity(ActivityClientRecord r, Intent customIntent, Stringreason) {
// If we aregetting 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();
}
// Make sure we are running with themost recent config.
handleConfigurationChanged(null, null);
// Initialize before creating theactivity
WindowManagerGlobal.initialize();
//这儿就正式调用Activity的onCreate函数我们继续进入分析
Activity a = performLaunchActivity(r,customIntent);
。。。。。
}
进入performLaunchActivity:代码如下
private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
ActivityInfoaInfo = 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 = newComponentName(r.activityInfo.packageName,
r.activityInfo.targetActivity);
}
Activity activity = null;
try {
java.lang.ClassLoader cl =r.packageInfo.getClassLoader();
//这儿先创建要启动的Activity的实例,本文分析为Home,所以此时创建的实例
//为HomeActivity,读者可以返回文章之前的图二
activity =mInstrumentation.newActivity(
cl,component.getClassName(), r.intent);
StrictMode.incrementExpectedActivityCount(activity.getClass());
r.intent.setExtrasClassLoader(cl);
r.intent.prepareToEnterProcess();
if (r.state != null) {
r.state.setClassLoader(cl);
}
} catch (Exception e) {
if (!mInstrumentation.onException(activity,e)) {
throw new RuntimeException(
"Unable to instantiateactivity " + component
+ ": " +e.toString(), e);
}
}
try {
/*
*这个在创建进程时候在调用ActivityThread调用makeApplication已经创
*建过Application,所以此时只是返回之前创建的Application
*/
Application app =r.packageInfo.makeApplication(false, mInstrumentation);
if (activity != null) {
//为当前Activity 创建Context,实际上指向的是ContextImpl
Context appContext = createBaseContextForActivity(r,activity);
CharSequencetitle = r.activityInfo.loadLabel(appContext.getPackageManager());
Configuration config = newConfiguration(mCompatConfiguration);
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;
}
//这时候调用attach,这个函数很重要,列下几个重要的变量
/**1、它把创建的Context回到了Activity中的context当中,这样Activity就获取到了*context
*2、创建了PhoneWindow
*3、创建了UI线程
*4、得到了应用的主线程
*5、mToken绑定到PhoneWindow。mToken即为ActivityRecord创建时的mAppToken
*6、把创建进程时候创建的Application绑定到Activity
*7、把ActivityRecord的Intent绑定Activity中的mIntent
*8、把创建的Instrument绑定到Activity
*/
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);
if(customIntent != null) {
activity.mIntent =customIntent;
}
r.lastNonConfigurationInstances= null;
activity.mStartedActivity = false;
int theme =r.activityInfo.getThemeResource();
if (theme != 0) {
activity.setTheme(theme);
}
activity.mCalled = false;
//Activity实例创建完毕,也attach完之后,就开始调用onCreate
//他是通过Instrument进行调用的,这在ActivityThread中handleBindApplication创建
if(r.isPersistable()) {
mInstrumentation.callActivityOnCreate(activity, r.state,r.persistentState);
} else {
mInstrumentation.callActivityOnCreate(activity,r.state);
}
if (!activity.mCalled) {
throw newSuperNotCalledException(
"Activity " +r.intent.getComponent().toShortString() +
" did not callthrough to super.onCreate()");
}
r.activity =activity;
r.stopped = true;
if (!r.activity.mFinished) {
///开始调用onStart函数
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);
}
}
if (!r.activity.mFinished) {
activity.mCalled= false;
///调用函数onPasCreate
if (r.isPersistable()) {
mInstrumentation.callActivityOnPostCreate(activity,r.state,
r.persistentState);
} else {
mInstrumentation.callActivityOnPostCreate(activity, r.state);
}
if (!activity.mCalled) {
throw newSuperNotCalledException(
"Activity" + r.intent.getComponent().toShortString() +
" did not callthrough to super.onPostCreate()");
}
}
}
r.paused =true;
mActivities.put(r.token,r);
} catch (SuperNotCalledException e) {
throw e;
} catch (Exception e) {
if(!mInstrumentation.onException(activity, e)) {
throw new RuntimeException(
"Unable to startactivity " + component
+ ": " +e.toString(), e);
}
}
return activity;
}
经过以上步骤,当前启动的Activity实例初始化已经完成,每个Activity都要重新创建Context,通过attach初始化相关变量, context、PhoneWindow、UI线程、主线程、mToken绑定到PhoneWindow、Application绑定到Activity、Instrument绑定到Activity。我们应用开发经常碰到的Activity生命周期onCreate、onStart、onPostCreate已经调用,但是onResume还没有调用,我们继续handleLaunchActivity调用完performLaunchActivity之后的代码:
handleLaunchActivity{
。。。。。。。。。
if (a != null) {
r.createdConfig= new Configuration(mConfiguration);
reportSizeConfigurations(r);
Bundle oldState = r.state;
//在这儿开始调用onResumed函数
handleResumeActivity(r.token,false, r.isForward,
!r.activity.mFinished&& !r.startsNotResumed, r.lastProcessedSeq, reason);
。。。。。。。。
}
通过以上分析我们知道启动Activity生命周期onCreate->onStart->onResumed正式调用完毕。
继续之前ActivityStackSupervisor中的realStartActivityLocked调用完scheduleLaunchActivity之后的步骤。扫尾。。.
final boolean realStartActivityLocked(ActivityRecord r, ProcessRecord app,
boolean andResume, booleancheckConfig) throws RemoteException {
if (andResume) {
// As part of the process oflaunching, ActivityThread also performs
// a resume.
//因为Activity已经调用完onResumed,所以这时候当前启动的Activity所属的ActivityStack中的mResumedActivity设置为当前启动的Activity,状态为RESUMED。
stack.minimalResumeActivityLocked(r);
} else {
.。。。。。。。。。
}
。。。。。。。
}
2、Activity结束过程的生命周期onPasued->onStop->onDestory
这个过程在Activity结束时候完成。到本小章节读者应该以假定此时已经启动了相关应用,并且假在在某种场景下,进
行Activity的切换,读者要记者一个Activity移动前台必然存在上一个Activity的paused过程,有些场景我还没有弄明白,如果有读者明白请指出来。
我们对于第三章节简单分析resumeFocusedStackTopActivityLocked这边再继续深分析,弄明白Activity生命周期结束的部分。
我们进入ActivityStackSupervisor中的resumeFocusedStackTopActivityLocked,看函数名字应该是resumed系统中focusedStack的处于栈顶的Activity。代码如下:
boolean resumeFocusedStackTopActivityLocked(
ActivityStack targetStack,//目标ActivityStack,可为null
ActivityRecord target, //上一个resumed的activity,可为null
ActivityOptions targetOptions) {
/*
*对于指定的tagetStack存在,并且为Focused的stack,那么进入
*指定的targetStack进行resume操作。
*/
if (targetStack != null &&isFocusedStack(targetStack)) {
returntargetStack.resumeTopActivityUncheckedLocked(target, targetOptions);
}
/*
*指定的ActivityStack不存在则获取当前Focused的ActivityStack
*获取focusedStack的处于顶端的Activity,并且此时activity的状态
*不为RESUMED
*/
final ActivityRecord r =mFocusedStack.topRunningActivityLocked();
if (r == null || r.state !=ActivityStack.ActivityState.RESUMED) {
mFocusedStack.resumeTopActivityUncheckedLocked(null, null);
}
return false;
}
接着进入对应的ActivityStack中的resumeTopActivityUncheckedLocked,代码如下:
/**
* Ensure that the top activity in thestack is resumed.
*
* @param prev The previously resumedactivity, for when in the process
* of pausing; can be null to call fromelsewhere.
* @param options Activity options.
*
* @return Returns true if something isbeing resumed, or false if
* nothing happened.
*
* NOTE: It is not safe to call this methoddirectly as it can cause an activity in a
* non-focused stack to be resumed.
* Use {@link ActivityStackSupervisor#resumeFocusedStackTopActivityLocked}to resume the
* right activity for the current system state.
*/
boolean resumeTopActivityUncheckedLocked(ActivityRecord prev,ActivityOptions options) {
//当前系统正在处于resumeTopActivity过程则返回
if(mStackSupervisor.inResumeTopActivity) {
// Don't even start recursing.
return false;
}
boolean result = false;
try {
// Protect against recursion.
mStackSupervisor.inResumeTopActivity = true;
if (mService.mLockScreenShown ==ActivityManagerService.LOCK_SCREEN_LEAVING) {
mService.mLockScreenShown =ActivityManagerService.LOCK_SCREEN_HIDDEN;
mService.updateSleepIfNeededLocked();
}
result =resumeTopActivityInnerLocked(prev, options);
} finally {
mStackSupervisor.inResumeTopActivity = false;
}
return result;
}
代码比较简单进入resumeTopActivityInnerLocked,这个函数代码比较长,大伙多看几遍。代码如下:
private boolean resumeTopActivityInnerLocked(ActivityRecord prev, ActivityOptionsoptions) {
。。。。。。。
ActivityRecord parent =mActivityContainer.mParentActivity;
if ((parent != null &&parent.state != ActivityState.RESUMED) ||
!mActivityContainer.isAttachedLocked()) {
// Do not resume this stack if itsparent is not resumed.
// TODO: If in a loo, make surethat parent stack resumeTopActivity is called 1st.
return false;
}
mStackSupervisor.cancelInitializingActivities();
// Find the first activity that is notfinishing.
/*
*首先获取当前ActivityStack中栈顶Activity,这个即为我们
*要resumed的Activity
*/
final ActivityRecord next =topRunningActivityLocked();
//Remember how we'll process thispause/resume situation, and ensure
// that the state is reset however we wind upproceeding.
/*这个变量是表示是否回调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 Stringreason = "noMoreActivities";
final int returnTaskType = prevTask== null || !prevTask.isOverHomeStack()
?ActivityRecord.HOME_ACTIVITY_TYPE : prevTask.getTaskToReturnTo();
if (!mFullscreen &&adjustFocusToNextFocusableStackLocked(returnTaskType, reason)) {
// Try to move focus to thenext visible stack with a running activity if this
// stack is not covering theentire screen.
returnmStackSupervisor.resumeFocusedStackTopActivityLocked(
mStackSupervisor.getFocusedStack(), prev, null);
}
// Let's just start up theLauncher...
ActivityOptions.abort(options);
if (DEBUG_STATES)Slog.d(TAG_STATES,
"resumeTopActivityLocked: No more activities go home");
if (DEBUG_STACK)mStackSupervisor.validateTopActivitiesLocked();
// Only resume home if on homedisplay
return isOnHomeDisplay() &&
mStackSupervisor.resumeHomeStackTask(returnTaskType, prev, reason);
}
next.delayedResume= false;
// If the topactivity is the resumed one, nothing to do.
/*这个是如果当前ActivityStack的resumedActivity即为栈顶Activity,那么表示已经resumed过了就不继续以下的处理*/
if(mResumedActivity == next && next.state == ActivityState.RESUMED&&
mStackSupervisor.allResumedActivitiesComplete()) {
// Make sure we have executed anypending transitions, since there
// should be nothing left to do atthis point.
mWindowManager.executeAppTransition();
mNoAnimActivities.clear();
ActivityOptions.abort(options);
if (DEBUG_STATES)Slog.d(TAG_STATES,
"resumeTopActivityLocked: Top activity resumed " + next);
if (DEBUG_STACK) mStackSupervisor.validateTopActivitiesLocked();
return false;
}
final TaskRecord nextTask = next.task;
/*
*这个是对上一个resumed的Activity的相关处理
*针对这个,本人不是很不清楚表示的场景
*/
if (prevTask!= null && prevTask.stack == this &&
prevTask.isOverHomeStack()&& prev.finishing && prev.frontOfTask) {
if (DEBUG_STACK) mStackSupervisor.validateTopActivitiesLocked();
if (prevTask == nextTask) {
prevTask.setFrontOfTask();
} else if (prevTask != topTask()) {
// This task is going away butit was supposed to return to the home stack.
// Now the task above it has toreturn to the home task instead.
final int taskNdx = mTaskHistory.indexOf(prevTask)+ 1;
mTaskHistory.get(taskNdx).setTaskToReturnTo(ActivityRecord.HOME_ACTIVITY_TYPE);
} else if (!isOnHomeDisplay()) {
return false;
} else if (!isHomeStack()){
if (DEBUG_STATES)Slog.d(TAG_STATES,
"resumeTopActivityLocked: Launching home next");
final int returnTaskType = prevTask ==null || !prevTask.isOverHomeStack() ?
ActivityRecord.HOME_ACTIVITY_TYPE:prevTask.getTaskToReturnTo();
return isOnHomeDisplay()&&
mStackSupervisor.resumeHomeStackTask(returnTaskType, prev,"prevFinished");
}
}
// If we are sleeping, and there is no resumedactivity, and the top
// activity is paused, well that is thestate we want.
if(mService.isSleepingOrShuttingDownLocked()
&& mLastPausedActivity == next
&& mStackSupervisor.allPausedActivitiesComplete()) {
// Make sure we have executed anypending transitions, since there
// should be nothing left to do atthis point.
mWindowManager.executeAppTransition();
mNoAnimActivities.clear();
ActivityOptions.abort(options);
if (DEBUG_STATES) Slog.d(TAG_STATES,
"resumeTopActivityLocked: Going to sleep and all paused");
if (DEBUG_STACK)mStackSupervisor.validateTopActivitiesLocked();
return false;
}
// Make sure that the user who ownsthis activity is started. If not,
// we will just leave it as is becausesomeone should be bringing
// another user's activities to the topof the stack.
//这个是多用户相关
if (!mService.mUserController.hasStartedUserState(next.userId)){
Slog.w(TAG, "Skipping resumeof top activity " + next
+ ": user " +next.userId + " is stopped");
if (DEBUG_STACK)mStackSupervisor.validateTopActivitiesLocked();
return false;
}
// Theactivity may be waiting for stop, but that is no longer
// apprpriate for it.
mStackSupervisor.mStoppingActivities.remove(next);
mStackSupervisor.mGoingToSleepActivities.remove(next);
next.sleeping = false;
mStackSupervisor.mWaitingVisibleActivities.remove(next);
if (DEBUG_SWITCH) Slog.v(TAG_SWITCH,"Resuming " + next);
// If we are currently pausing anactivity, then don't do anything until that is done.
if(!mStackSupervisor.allPausedActivitiesComplete()) {
if (DEBUG_SWITCH || DEBUG_PAUSE ||DEBUG_STATES) Slog.v(TAG_PAUSE,
"resumeTopActivityLocked: Skip resume: some activitypausing.");
if (DEBUG_STACK) mStackSupervisor.validateTopActivitiesLocked();
return false;
}
mStackSupervisor.setLaunchSource(next.info.applicationInfo.uid);
// We need tostart pausing the current activity so the top one can be resumed...
final boolean dontWaitForPause =(next.info.flags& FLAG_RESUME_WHILE_PAUSING) != 0;
/*
*这个是pause掉不是FocusedStack的其它ActivityStack的栈顶activity*/
*对于不是当前focusStack的并且存在有mResumedActivity不为null的都要paused
*举个例子:如果当前处于FULLSCREEN_WORKSPACE_STACK(应用处于的Stack)
*这时候按HOME键切换到Launcher桌面,因为Launcher是处于HOME_STACK,
*那么时候需要把FULLSCREEN_STACK中的resumed 状态的Activity进行pausing过程
*/
boolean pausing =mStackSupervisor.pauseBackStacks(userLeaving, next, dontWaitForPause);
/*
*这个表示当前ActivityStack已经存在resumedActivity,也进行pausing过程。
*/
if (mResumedActivity != null) {
pausing |=startPausingLocked(userLeaving, false, next, dontWaitForPause);
}
我们分析关于Activity如何进行Pausing操作。进入startPausingLocked函数,
/**
* Start pausing the currently resumedactivity. It is an error to call this ifthere
* is already an activity being paused orthere is no resumed activity.
*
*@param userLeaving True if this should result in an onUserLeavingto the current activity.
* @param uiSleeping True if this ishappening with the user interface going to sleep (the screen turning off).
* @param resuming The activity we arecurrently trying to resume or null
* if this is not being called as part of resuming the top activity,so we
* shouldn't try to instigate a resume here if not null.
* @param dontWait True if the caller doesnot want to wait for the pause to
* complete. If set to true,we will immediately complete the pause
* here before returning.
* @return Returns true if an activity now is in thePAUSING state, and we are
* waiting for it to tell us when it is done.
*/
//函数的注释大伙可以看下,其中参数dontWait表示如何Activity如果有设置
//android:resumeWhilePausing="true"那么会马上进行PAUSED
final boolean startPausingLocked(booleanuserLeaving, boolean uiSleeping,
ActivityRecord resuming,
boolean dontWait
) {
//这个表示ActivityStack中的已经进行过了pausing操作,那么接下去直接finish操作
if (mPausingActivity != null) {
Slog.wtf(TAG, "Going to pausewhen pause is already pending for " + mPausingActivity
+ " state=" +mPausingActivity.state);
if (!mService.isSleepingLocked()) {
// Avoid recursion among checkfor sleep and complete pause during sleeping.
// Because activity will bepaused immediately after resume, just let pause
// be completed by the order ofactivity paused from clients.
completePauseLocked(false,resuming);
}
}
ActivityRecord prev = mResumedActivity;
//表示当前ActivityStack还没有resumed 过Activity,直接返回
if (prev == null) {
if (resuming == null) {
Slog.wtf(TAG, "Trying topause when nothing is resumed");
mStackSupervisor.resumeFocusedStackTopActivityLocked();
}
return false;
}
/*
*这边就是转换过程中一些Activity状态的记录过程,大致这样
*mResumedActivity->mPausingActivity
*mResumedActivity->mLastPausedActivity
*/
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;
//这边该ActivityStack中的resumedActivity状态变成了PAUSING状态
prev.state = ActivityState.PAUSING;
。。。。。。
final ActivityRecord next =mStackSupervisor.topRunningActivityLocked();
if (mService.mHasRecents
&&(next == null || next.noDisplay || next.task != prev.task || uiSleeping)) {
//这是标记该ResumedActivity是否需要截屏
prev.mUpdateTaskThumbnailWhenHidden= true;
}
。。。。。。。
//这儿就是该ActivityStack的resumedActivity的调用onPause函数
*注意此时prev.state值为 ActivityState.PAUSING
if (prev.app != null &&prev.app.thread != null) {
try {
EventLog.writeEvent(EventLogTags.AM_PAUSE_ACTIVITY,
prev.userId,System.identityHashCode(prev),
prev.shortComponentName);
mService.updateUsageStats(prev,false);
/*调用Activity的onPaused,这个流程不分析了,读者可以自行分析
*如果dontWait为false(即android:resumeWhilePausing为false时候)
*它调用ActivityThread的schedulePauseActivity之后,
*ActivityThread会通过AMS会回调该ActivityStack的activityPausedLocked*函数并且会调用completePauseLocked这 *个函数下面还会涉及,下面再分*析,在这个函数里面会把该activity的状态prev.state修改成PAUSED,
*/
prev.app.thread.schedulePauseActivity(prev.appToken, prev.finishing,
userLeaving,prev.configChangeFlags, dontWait);
} catch (Exception e) {
// Ignore exception, if processdied other code will cleanup.
Slog.w(TAG, "Exceptionthrown during pause", e);
mPausingActivity = null;
mLastPausedActivity = null;
mLastNoHistoryActivity = null;
}
} else {
mPausingActivity = null;
mLastPausedActivity = null;
mLastNoHistoryActivity = null;
}
// If we are not going to sleep, we wantto ensure the device is
// awake until the next activity isstarted.
if (!uiSleeping &&!mService.isSleepingOrShuttingDownLocked()) {
mStackSupervisor.acquireLaunchWakelock();
}
/如果上步在调用onPaush没有出错,或者resumed对应的进程不为空
//那么继续paused过程
if (mPausingActivity != null) {
// Have the window manager pause its keydispatching until the new
// activity has started. If we're pausing the activity just because
// the screen is being turned offand the UI is sleeping, don't interrupt
// key dispatch; the same activitywill pick it up again on wakeup.
if (!uiSleeping) {
prev.pauseKeyDispatchingLocked();
} else if (DEBUG_PAUSE) {
Slog.v(TAG_PAUSE, "Keydispatch not paused for screen off");
}
//如果AndroidManifest.xml有设置android:resumeWhilePausing="true"该值为true
if (dontWait) {
// If the caller said they don'twant to wait for the pause, then complete
//the pause now.
completePauseLocked(false,resuming);
return false;
} else {
// Schedule a pause timeout incase the app doesn't respond.
// We don't give it much timebecause this directly impacts the
// responsiveness seen by theuser.
//这个其实最终也会调用到completePauseLocked这里面,所以
//我们接下来看看这里面操作
Message msg = mHandler.obtainMessage(PAUSE_TIMEOUT_MSG);
msg.obj = prev;
prev.pauseTime =SystemClock.uptimeMillis();
mHandler.sendMessageDelayed(msg, PAUSE_TIMEOUT);
if (DEBUG_PAUSE)Slog.v(TAG_PAUSE, "Waiting for pause to complete...");
return true;
}
} else {
// This activity failed to schedulethe
// pause, so just treat it as beingpaused now.
if (DEBUG_PAUSE) Slog.v(TAG_PAUSE,"Activity not running, resuming next.");
if (resuming == null) {
mStackSupervisor.resumeFocusedStackTopActivityLocked();
}
return false;
}
}
我们接着上一步startPausingLocked中调用completePauseLocked过程分析,其实这个是AcrivityRecord中的PAUSING过程到PAUSED的过程。代码如下:
private void completePauseLocked(boolean resumeNext, ActivityRecordresuming) {
//这个mPausingActivity在startPausingLocked赋值
ActivityRecord prev =mPausingActivity;
//表示当前正在pausing的activity不为null
//这个流程表示处理Activity的pausing过程
if (prev != null) {
final booleanwasStopping = prev.state == ActivityState.STOPPING;
//这时候Activity由PAUSIING到PAUSED
prev.state =ActivityState.PAUSED;
//如果这个activity状态为finish的时候直接finish该activity
if(prev.finishing) {
//如果pausingActivty已经finish了直接调用这个这个就不展开分析了,大致说下,如果prev处于前台,那么 //它会把该Activiyt状态切成ActivityState.STOPPGING。如果prev不处于前台,那么Activity状态
//切成ActivityState.FINISHI,且该ActivityRecord中的finish的值改成
//true并且通过r.app.thread.scheduleDestroyActivity调
//用Activity的onStop、onDestory函数,这个流程完了之后通
//过AMS的activityDestroyed函数回调ActivityStack中的
//removeActivityFromHistoryLocked把该Activity中TaskRecord中删除,//且把状态切成 //ActivityState.Destory。
prev =finishCurrentActivityLocked(prev, FINISH_AFTER_VISIBLE, false);
} else if(prev.app != null) {
if(mStackSupervisor.mWaitingVisibleActivities.remove(prev)) {
if(DEBUG_SWITCH || DEBUG_PAUSE) Slog.v(TAG_PAUSE,
"Complete pause, no longer waiting: " + prev);
}
//这个是好像Activty configuration变化时候,并且当前activity还处//于pausing时候会置成true,这时候会重新launchActivty过程
// 具体的还没有弄明白
if (prev.deferRelaunchUntilPaused){
//Complete the deferred relaunch that was waiting for pause to complete.
if(DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Re-launching after pause: " + prev);
relaunchActivityLocked(prev, prev.configChangeFlags, false,
prev.preserveWindowOnDeferredRelaunch);
} else if(wasStopping) {
// We arealso stopping, the stop request must have gone soon after the pause.
// We can't clobber it, because the stopconfirmation will not be handled.
// We don't need toschedule another stop, we only need to let it happen.
prev.state= ActivityState.STOPPING;
} else if((!prev.visible && !hasVisibleBehindActivity())
||mService.isSleepingOrShuttingDownLocked()) {
// If we were visiblethen resumeTopActivities will release resources before
// stopping.
addToStopping(prev, true /*immediate */);
}
} else {
prev = null;
}
// It is possible theactivity was freezing the screen before it was paused.
// In that case goahead and remove the freeze this activity has on the screen
// since it is nolonger visible.
if (prev != null){
prev.stopFreezingScreenLocked(true /*force*/);
}
//到这儿pausing过程就已经完成了,重置变量
mPausingActivity =null;
}
//pausing处理完了,resumed下个Activity
if (resumeNext) {
finalActivityStack topStack = mStackSupervisor.getFocusedStack();
if(!mService.isSleepingOrShuttingDownLocked()) {
//继续调用本小章节的函数
mStackSupervisor.resumeFocusedStackTopActivityLocked(topStack, prev,null);
} else {
mStackSupervisor.checkReadyForSleepLocked();
ActivityRecordtop = topStack.topRunningActivityLocked();
if (top ==null || (prev != null && top != prev)) {
// Ifthere are no more activities available to run, do resume anyway to start
//something. Also if the top activity on the stack is not the just paused
//activity, we need to go ahead and resume it to ensure we complete an
//in-flight app switch.
mStackSupervisor.resumeFocusedStackTopActivityLocked();
}
}
}
if (prev != null) {
prev.resumeKeyDispatchingLocked();
if (prev.app !=null && prev.cpuTimeAtResume > 0
&& mService.mBatteryStatsService.isOnBattery()) {
long diff =mService.mProcessCpuTracker.getCpuTimeForPid(prev.app.pid)
-prev.cpuTimeAtResume;
if (diff >0) {
BatteryStatsImpl bsi =mService.mBatteryStatsService.getActiveStatistics();
synchronized (bsi) {
BatteryStatsImpl.Uid.Proc ps =
bsi.getProcessStatsLocked(prev.info.applicationInfo.uid,
prev.info.packageName);
if (ps!= null) {
ps.addForegroundTimeLocked(diff);
}
}
}
}
prev.cpuTimeAtResume = 0; // reset it
}
// Notify when thetask stack has changed, but only if visibilities changed (not just
// focus). Also ifthere is an active pinned stack - we always want to notify it about
// task stack changes,because its positioning may depend on it.
if(mStackSupervisor.mAppVisibilitiesChangedSinceLastPause
||mService.mStackSupervisor.getStack(PINNED_STACK_ID) != null) {
mService.notifyTaskStackChangedLocked();
mStackSupervisor.mAppVisibilitiesChangedSinceLastPause = false;
}
mStackSupervisor.ensureActivitiesVisibleLocked(resuming, 0,!PRESERVE_WINDOWS);
}
我们总结下这个过程,调用startPausingLocked,Activity生命周期的onPaused被调用,并且此时ActivityRecord状态经历了RESUMED->PAUSING->PAUSED的变化,经过这一步ActivityStack处于running状态的Activity已经变成PAUSED状态。
我们继续分析startPausingLocked的之后的代码,接上
private boolean resumeTopActivityInnerLocked(ActivityRecord prev, ActivityOptionsoptions) {
。。。。。。。。
pausing |=startPausingLocked(userLeaving, false, next, dontWaitForPause);
。。。。。。。。
//如果当前Activity状态还示切到PAUSED,还处于PAUSING时候
//就不再继续下面的resumed处于栈顶的activity,因为这时候resumed的
//Activtity还未走完paused流程
if (pausing) {
if (DEBUG_SWITCH || DEBUG_STATES)Slog.v(TAG_STATES,
"resumeTopActivityLocked: Skip resume: need to startpausing");
// At this point we want to put theupcoming activity's process
// at the top of the LRU list,since we know we will be needing it
// very soon and it would be awaste to let it get killed if it
// happens to be sitting towardsthe end.
if (next.app != null &&next.app.thread != null) {
mService.updateLruProcessLocked(next.app, true, null);
}
if (DEBUG_STACK)mStackSupervisor.validateTopActivitiesLocked();
return true;
} else if (mResumedActivity == next&&next.state == ActivityState.RESUMED &&
mStackSupervisor.allResumedActivitiesComplete()) {
// It ispossible for the activity to be resumed when we paused back stacks above if the
// next activity doesn't have towait for pause to complete.
// So, nothing else to-do except:
// Make sure we have executed anypending transitions, since there
// should be nothing left to do atthis point.
mWindowManager.executeAppTransition();
mNoAnimActivities.clear();
ActivityOptions.abort(options);
if (DEBUG_STATES)Slog.d(TAG_STATES,
"resumeTopActivityLocked: Top activity resumed (dontWaitForPause)" + next);
if (DEBUG_STACK)mStackSupervisor.validateTopActivitiesLocked();
return true;
}
// If the mostrecent activity was noHistory but was only stopped rather
// than stopped+finished because thedevice went to sleep, we need to make
// sure to finish it as we're making anew activity topmost.
/**
*如果此时处于屏幕灭屏状态,并且当前Resumed的Activity设置了Intent.FLAG_ACTIVITY_NO_HISTORY
*那么需要finish此Activity
*/
if (mService.isSleepingLocked()&& mLastNoHistoryActivity != null &&
!mLastNoHistoryActivity.finishing) {
if (DEBUG_STATES)Slog.d(TAG_STATES,
"no-history finish of" + mLastNoHistoryActivity + " on new resume");
requestFinishActivityLocked(mLastNoHistoryActivity.appToken,Activity.RESULT_CANCELED,
null,"resume-no-history", false);
mLastNoHistoryActivity = null;
}
if (prev != null && prev !=next) {
if(!mStackSupervisor.mWaitingVisibleActivities.contains(prev)
&& next != null &&!next.nowVisible) {
mStackSupervisor.mWaitingVisibleActivities.add(prev);
if (DEBUG_SWITCH)Slog.v(TAG_SWITCH,
"Resuming top,waiting visible to hide: " + prev);
} else {
// The next activity is alreadyvisible, so hide the previous
// activity's windows right nowso we can show the new one ASAP.
// We only do this if theprevious is finishing, which should mean
// it is on top of the onebeing resumed so hiding it quickly
// is good. Otherwise, we want to do the normal route ofallowing
// the resumed activity to beshown so we can decide if the
// previous should actually behidden depending on whether the
// new one is found to befull-screen or not.
if (prev.finishing) {
mWindowManager.setAppVisibility(prev.appToken, false);
if (DEBUG_SWITCH)Slog.v(TAG_SWITCH,
"Not waitingfor visible to hide: " + prev + ", waitingVisible="
+mStackSupervisor.mWaitingVisibleActivities.contains(prev)
+ ",nowVisible=" + next.nowVisible);
} else {
if (DEBUG_SWITCH)Slog.v(TAG_SWITCH,
"Previous already visiblebut still waiting to hide: " + prev
+ ",waitingVisible="
+mStackSupervisor.mWaitingVisibleActivities.contains(prev)
+ ", nowVisible="+ next.nowVisible);
}
}
}
// Launching this app's activity, makesure the app is no longer
// considered stopped.
try {
AppGlobals.getPackageManager().setPackageStoppedState(
next.packageName,false, next.userId); /* TODO: Verify if correct userid */
} catch (RemoteException e1) {
} catch (IllegalArgumentException e) {
Slog.w(TAG, "Failed trying tounstop package "
+ next.packageName +": " + e);
}
// We are starting up the nextactivity, so tell the window manager
// that the previous one will be hiddensoon. This way it can know
// to ignore it when computing thedesired screen orientation.
boolean anim = true;
if (mIsAnimationBoostEnabled == true&& mPerf == null) {
mPerf = new BoostFramwork();
}
//这边是准备相关的动画,这样用户可以视觉感觉切换过程
/读者看下就好
if (prev != null) {
。。。。
}
Bundle resumeAnimOptions = null;
if (anim) {
ActivityOptions opts =next.getOptionsForTargetActivityLocked();
if (opts != null) {
resumeAnimOptions =opts.toBundle();
}
next.applyOptionsLocked();
} else {
next.clearOptionsLocked();
}
ActivityStack lastStack =mStackSupervisor.getLastStack();
/*
*这之前是pausing上一个resumed的Activity,这时候就要进入栈顶的resumed过程了,
*不然栈顶的Activity永远不显示了。
*如果当前ActivityStack中,此时处于Task栈顶的Activity已经创建过了并且已经纳入相
*应的进程中,那么进入该Activity的resumed过程。
*举个例子:比如你已经通过Launcher启动了应用2中的Activity A,这时候按HOME键
*返回到Launcher桌面,这时你又点击Launcher上应用2的图标,这时候就会调用onResumed
*/
if (next.app != null &&next.app.thread != null) {
// If the previous activity istranslucent, force a visibility update of
// the next activity, so that it'sadded to WM's opening app list, and
// transition animation can be setup properly.
// For example, pressing Homebutton with a translucent activity in focus.
// Launcher is already visible inthis case. If we don't add it to opening
// apps,maybeUpdateTransitToWallpaper() will fail to identify this as a
// TRANSIT_WALLPAPER_OPENnimation, and run some funny animation.
final booleanlastActivityTranslucent = lastStack != null
&& (!lastStack.mFullscreen
||(lastStack.mLastPausedActivity != null
&& !lastStack.mLastPausedActivity.fullscreen));
// This activity is now becomingvisible.
if (!next.visible || next.stopped|| lastActivityTranslucent) {
mWindowManager.setAppVisibility(next.appToken, true);
}
// schedule launch ticks to collectinformation about slow apps.
next.startLaunchTickingLocked();
ActivityRecord lastResumedActivity=
lastStack == null ? null:lastStack.mResumedActivity;
ActivityState lastState =next.state;
mService.updateCpuStats();
if (DEBUG_STATES)Slog.v(TAG_STATES, "Moving to RESUMED: " + next + " (inexisting)");
/**
*这时候栈顶的Activity的activty处于RESUMED状态
*/
next.state = ActivityState.RESUMED;
//重新设置当前ActivityStack的resumed的activity
mResumedActivity = next;
next.task.touchActiveTime();
mRecentTasks.addLocked(next.task);
mService.updateLruProcessLocked(next.app, true, null);
updateLRUListLocked(next);
mService.updateOomAdjLocked();
// Have the window managerre-evaluate the orientation of
// the screen based on the newactivity order.
boolean notUpdated = true;
if(mStackSupervisor.isFocusedStack(this)) {
Configuration config =mWindowManager.updateOrientationFromAppTokens(
mService.mConfiguration,
next.mayFreezeScreenLocked(next.app) ? next.appToken : null);
if (config != null) {
next.frozenBeforeDestroy =true;
}
notUpdated =!mService.updateConfigurationLocked(config, next, false);
}
if (notUpdated) {
// The configuration updatewasn't able to keep the existing
// instance of the activity,and instead started a new one.
// We should be all done, butlet's just make sure our activity
// is still at the top andschedule another run if something
// weird happened.
ActivityRecord nextNext =topRunningActivityLocked();
if (DEBUG_SWITCH ||DEBUG_STATES) Slog.i(TAG_STATES,
"Activity configchanged during resume: " + next
+ ", new next:" + nextNext);
if (nextNext != next) {
// Do over!
mStackSupervisor.scheduleResumeTopActivities();
}
if(mStackSupervisor.reportResumedActivityLocked(next)) {
mNoAnimActivities.clear()
if (DEBUG_STACK)mStackSupervisor.validateTopActivitiesLocked();
return true;
}
if (DEBUG_STACK)mStackSupervisor.validateTopActivitiesLocked();
return false;
}
try {
// Deliver all pending results.
ArrayList<ResultInfo> a =next.results;
if (a != null) {
final int N = a.size();
if (!next.finishing&& N > 0) {
if (DEBUG_RESULTS) Slog.v(TAG_RESULTS,
"Delivering results to " + next + ": " + a);
next.app.thread.scheduleSendResult(next.appToken, a);
}
}
boolean allowSavedSurface =true;
if (next.newIntents != null) {
// Restrict saved surfaceto launcher start, or there is no intent at all
// (eg. task being broughtto front). If the intent is something else,
// likely the app is goingto show some specific page or view, instead of
// what's left last time.
for (int i =next.newIntents.size() - 1; i >= 0; i--) {
final Intent intent =next.newIntents.get(i);
if (intent != null&& !ActivityRecord.isMainIntent(intent)) {
allowSavedSurface =false;
break;
}
}
next.app.thread.scheduleNewIntent(
next.newIntents,next.appToken, false /* andPause */);
}
// Well the app will no longerbe stopped.
// Clear app token stoppedstate in window manager if needed.
mWindowManager.notifyAppResumed(next.appToken, next.stopped,allowSavedSurface);
EventLog.writeEvent(EventLogTags.AM_RESUME_ACTIVITY, next.userId,
System.identityHashCode(next), next.task.taskId,next.shortComponentName);
next.sleeping = false;
mService.showUnsupportedZoomDialogIfNeededLocked(next);
mService.showAskCompatModeDialogLocked(next);
next.app.pendingUiClean = true;
next.app.forceProcessStateUpTo(mService.mTopProcessState);
next.clearOptionsLocked();
//这边即为调用当前处于栈顶的Activity的生命
//周期的onRestart->onResumed
next.app.thread.scheduleResumeActivity(next.appToken,
next.app.repProcState,
mService.isNextTransitionForward(),
resumeAnimOptions);
mStackSupervisor.checkReadyForSleepLocked();
} catch (Exception e) {
// Whoops, need to restart thisactivity!
if (DEBUG_STATES)Slog.v(TAG_STATES, "Resume failed; resetting state to "
+ lastState + ":" + next);
next.state = lastState;
if (lastStack != null) {
lastStack.mResumedActivity= lastResumedActivity;
}
Slog.i(TAG, "Restarting becauseprocess died: " + next);
if (!next.hasBeenLaunched) {
next.hasBeenLaunched =true;
} else if (SHOW_APP_STARTING_PREVIEW &&lastStack != null &&
mStackSupervisor.isFrontStack(lastStack)) {
next.showStartingWindow(null, true);
}
mStackSupervisor.startSpecificActivityLocked(next, true, false);
if (DEBUG_STACK)mStackSupervisor.validateTopActivitiesLocked();
return true;
}
// From this point on, if somethinggoes wrong there is no way
// to recover the activity.
try {
//这时候activity的状态为visible
completeResumeLocked(next);
} catch (Exception e) {
// If any exception getsthrown, toss away this
// activity and try the nextone.
Slog.w(TAG, "Exceptionthrown during resume of " + next, e);
requestFinishActivityLocked(next.appToken, Activity.RESULT_CANCELED,null,
"resume-exception", true);
if (DEBUG_STACK)mStackSupervisor.validateTopActivitiesLocked();
return true;
}
} else {//这个流程创建进程时候已经分析过了
// Whoops, need to restart thisactivity!
if (!next.hasBeenLaunched) {
next.hasBeenLaunched = true;
} else {
if (SHOW_APP_STARTING_PREVIEW){
next.showStartingWindow(null, true);
}
}
mStackSupervisor.startSpecificActivityLocked(next, true, true);
}
if (DEBUG_STACK)mStackSupervisor.validateTopActivitiesLocked();
return true;
}
经过这一小章节的解析,AMS会先startPausingLocked函数中paused之前的resumed的Activity,这时候Activity生命周期的onPaused被调用,并且此时ActivityRecord状态经历了RESUMED->PAUSING->PAUSED的变化,接下来是resumed当前activityStack处于栈顶的Activity,它把当前ActivityStack的resumed的activity修改成当前栈顶的activity,栈顶Activity的状态对应修改成RESUMED,并且调用Activity的生命周期onStart->onResume,最后设置其visible为true。
到这儿其实关于Activity生命中的onStop和onDestory还没有介绍,因为之前只是在Activity切换,并没有涉及到Activity结束的情况。那么onStop和onDestory何时会调用呢?
举一个情况来分析,我们知道应用中Activity调用finish 函数是会结束当前Activity的,我们以这个作为切入来点分析。调用finish最终会调用到AMS中的finishActivity当中,我们简化当前finsi的activity不是root Activity(即不是AndroidManifest有定义Main的activity)。
finishActivity会它所属的activityStack中的requestFinishActivityLocked函数,代码如下:
final boolean requestFinishActivityLocked(IBinder token, int resultCode,
Intent resultData, String reason, boolean oomAdj) {
ActivityRecord r = isInStackLocked(token);
if (r == null) {
return false;
}
finishActivityLocked(r, resultCode, resultData, reason, oomAdj);
return true;
}
进入finishActivityLocked代码如下:
/**
* @return Returns true if this activityhas been removed from the history
* list, or false if it is still in thelist and will be removed later.
*/
final booleanfinishActivityLocked(ActivityRecord r, int resultCode, Intent resultData,
String reason, boolean oomAdj) {
if (r.finishing) {
Slog.w(TAG, "Duplicate finishrequest for " + r);
return false;
}
//在这儿会把activityRecord中的finishing设置为true
//表示该activity正在处于finishing过程
r.makeFinishingLocked();
final TaskRecord task = r.task;
final ArrayList<ActivityRecord>activities = task.mActivities;
final int index =activities.indexOf(r);
if (index < (activities.size() - 1)){
task.setFrontOfTask();
if ((r.intent.getFlags() &Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET) != 0) {
// If the caller asked thatthis activity (and all above it)
// be cleared when the task isreset, don't lose that information,
// but propagate it up to thenext activity.
ActivityRecord next =activities.get(index+1);
next.intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET);
}
}
r.pauseKeyDispatchingLocked();
//需要重新设置下当前focused的activity
adjustFocusedActivityLocked(r,"finishActivity");
finishActivityResultsLocked(r,resultCode, resultData);
final boolean endTask = index <= 0;
final int transit = endTask ?AppTransition.TRANSIT_TASK_CLOSE : AppTransition.TRANSIT_ACTIVITY_CLOSE;
/**
当前Resumed的activity(即当前running状态)自身调用finish
*/
if (mResumedActivity == r) {
if (DEBUG_VISIBILITY ||DEBUG_TRANSITION) Slog.v(TAG_TRANSITION,
"Prepare closetransition: finishing " + r);
mWindowManager.prepareAppTransition(transit, false)
// Tell window manage to preparefor this one to be removed.
mWindowManager.setAppVisibility(r.appToken, false);
if (mPausingActivity == null) {
if (DEBUG_PAUSE)Slog.v(TAG_PAUSE, "Finish needs to pause: " + r);
if (DEBUG_USER_LEAVING)Slog.v(TAG_USER_LEAVING,
"finish() =>pause with userLeaving=false");
//这个之前分析过了,大家注意下参数不同走的流程不同就好
//最终这个也会进入finishCurrentActivityLocked
startPausingLocked(false,false, null, false);
}
if (endTask) {
mStackSupervisor.removeLockedTaskLocked(task);
}
} else if (r.state !=ActivityState.PAUSING) {
//看注释
// If the activity is PAUSING, wewill complete the finish once
// it is done pausing; else we canjust directly finish it here.
if (DEBUG_PAUSE) Slog.v(TAG_PAUSE,"Finish not pausing: " + r);
if (r.visible) {
mWindowManager.prepareAppTransition(transit, false);
mWindowManager.setAppVisibility(r.appToken, false);
mWindowManager.executeAppTransition();
if(!mStackSupervisor.mWaitingVisibleActivities.contains(r)) {
mStackSupervisor.mWaitingVisibleActivities.add(r);
}
}
//这儿正式结束activity
returnfinishCurrentActivityLocked(r, (r.visible || r.nowVisible) ?
FINISH_AFTER_VISIBLE :FINISH_AFTER_PAUSE, oomAdj) == null;
} else {
if (DEBUG_PAUSE) Slog.v(TAG_PAUSE,"Finish waiting for pause of: " + r);
}
return false;
}
我们分析下这个finishCurrentActivityLocked函数,代码如下:
final ActivityRecord finishCurrentActivityLocked(ActivityRecord r, int mode, boolean oomAdj) {
// First things first: if this activityis currently visible,
// and the resumed activity is not yetvisible, then hold off on
// finishing until the resumed onebecomes visible.
//经过上一步调用makeFinishingLocked之后,当前处于栈顶的running已经变化了
//比如此时栈有A,B,C这三个,原来如果为topRunning为C,
//这时经过makeFinishingLocked之后,topRunning变成了B
final ActivityRecord next =mStackSupervisor.topRunningActivityLocked();
//这个是比如当前finish的Acity还处于可视状态,那么他的状态先切成了STOPPING
if (mode == FINISH_AFTER_VISIBLE&& (r.visible || r.nowVisible)
&& next != null&& !next.nowVisible) {
if(!mStackSupervisor.mStoppingActivities.contains(r)) {
addToStopping(r, false /*immediate */);
}
if (DEBUG_STATES) Slog.v(TAG_STATES,
"Moving to STOPPING:"+ r + " (finish requested)");
r.state = ActivityState.STOPPING;
if (oomAdj) {
mService.updateOomAdjLocked();
}
return r;
}
// make sure the record is cleaned out of other places.
mStackSupervisor.mStoppingActivities.remove(r);
mStackSupervisor.mGoingToSleepActivities.remove(r);
mStackSupervisor.mWaitingVisibleActivities.remove(r);
if (mResumedActivity == r) {
mResumedActivity = null;
}
final ActivityState prevState =r.state;
if (DEBUG_STATES) Slog.v(TAG_STATES,"Moving to FINISHING: " + r);
//这时候Activity状态转换成FINISHING
r.state = ActivityState.FINISHING;
final booleanfinishingActivityInNonFocusedStack
= r.task.stack !=mStackSupervisor.getFocusedStack()
&& prevState ==ActivityState.PAUSED && mode == FINISH_AFTER_VISIBLE;
if (mode == FINISH_IMMEDIATELY
|| (prevState ==ActivityState.PAUSED
&& (mode ==FINISH_AFTER_PAUSE || mStackId == ActivityManager.StackId.PINNED_STACK_ID))
||finishingActivityInNonFocusedStack
|| prevState == ActivityState.STOPPED
|| prevState ==ActivityState.INITIALIZING) {
r.makeFinishingLocked()
/*这边开始调用Activity生命周期的onStop->onDestory,如果当前还未paused*的还会onPaused这个生命周期,这函数 *里面会把Activity从
*对应的进程中删除,nowVisible变成false,,
*把Activity从对应的Task中移除并且状态修改成DESTROYED
*从WindowMangerService删除对应的Activity
*/
boolean activityRemoved =destroyActivityLocked(r, true, "finish-imm");
if(finishingActivityInNonFocusedStack) {
// Finishing activity that was in pausedstate and it was in not currently focused
// stack, need to makesomething visible in its place.
mStackSupervisor.ensureActivitiesVisibleLocked(null, 0,!ActivityStackSupervisor.PRESERVE_WINDOWS);
}
if (activityRemoved){ mStackSupervisor.resumeFocusedStackTopActivityLocked();
}
if (DEBUG_CONTAINERS)Slog.d(TAG_CONTAINERS,
"destroyActivityLocked: finishCurrentActivityLocked r=" + r +
" destroy returnedremoved=" + activityRemoved);
return activityRemoved ? null : r;
}
// Need to go through the full pause cycleto get this
// activity into the stopped state andthen finish it.
if (DEBUG_ALL) Slog.v(TAG,"Enqueueing pending finish: " + r);
mStackSupervisor.mFinishingActivities.add(r);
r.resumeKeyDispatchingLocked();
mStackSupervisor.resumeFocusedStackTopActivityLocked();
return r;
}
到这儿我们就能知道Activity生命周期中的onStop->onDestory了,Activity状态转换
FINISHING->DESTORYING->DESTORYED,已经从相关的进程和Task移除Activity。
好了,到了这步一个启动的Activity整个生命流程算是介绍完了,涉及东西异常多、和繁锁,读者需要自己拿着代码,可以对着流程自己梳理,其中还有很多在这篇文章里没有涉及,忽略很多,毕竟AMS涉及东西太多。晕!!!!
开机广播BOOT_COMPLETED发送流程
何时发送BOOT_COMPLETED广播,这章节我简单说下,看下流程怎么走。
我们接上一章节Activity初始化中的minimalResumeActivityLocked进行分析:
void inimalResumeActivityLocked(ActivityRecord r) {
r.state = ActivityState.RESUMED;
mResumedActivity = r;
r.task.touchActiveTime();
mRecentTasks.addLocked(r.task);
///
completeResumeLocked(r);
mStackSupervisor.checkReadyForSleepLocked();
setLaunchTime(r);
if (DEBUG_SAVED_STATE)Slog.i(TAG_SAVED_STATE,
"Launch completed;removing icicle of " + r.icicle);
分析completeResumeLocked:
private voidcompleteResumeLocked(ActivityRecord next) {
next.visible = true;
next.idle = false;
next.results = null;
next.newIntents = null;
next.stopped = false;
if (next.isHomeActivity()) {
ProcessRecord app =next.task.mActivities.get(0).app;
if (app != null && app !=mService.mHomeProcess) {
mService.mHomeProcess = app;
}
}
if (next.nowVisible) {
// We won't get a call toreportActivityVisibleLocked() so dismiss lockscreen now.
mStackSupervisor.reportActivityVisibleLocked(next);
mStackSupervisor.notifyActivityDrawnForKeyguard();
}
// schedule an idle timeout in case theapp doesn't do it for us.
mStackSupervisor.scheduleIdleTimeoutLocked(next);
。。。。。。。。
}
进入scheduleIdleTimeoutLocked,这个函数实际上是通过Handler最终调用activityIdleInternalLocked
final ActivityRecord activityIdleInternalLocked(final IBinder token, booleanfromTimeout,
Configuration config) {
。。。。。。
ActivityRecord r = ActivityRecord.forTokenLocked(token);
if (r != null) {
if (isFocusedStack(r.task.stack) ||fromTimeout) {
booting =checkFinishBootingLocked();
}
}
。。。。。。。
}
进入checkFinishBootingLocked:代码如下
private boolean checkFinishBootingLocked() {
final boolean booting =mService.mBooting;
boolean enableScreen = false;
mService.mBooting = false;
if (!mService.mBooted) {
mService.mBooted = true;
enableScreen = true;
}
if (booting || enableScreen) {
mService.postFinishBooting(booting,enableScreen);
}
return booting;
}
继续进入AMS中的postFinishBooting,在该函数通过Handler,最终进入finishBooting
final void finishBooting() {
synchronized (this) {
。。。。。
/**开始发送广播*/
mUserController.sendBootCompletedLocked(
newIIntentReceiver.Stub() {
@Override
public voidperformReceive(Intent intent, int resultCode,
Stringdata, Bundle extras, boolean ordered,
booleansticky, int sendingUser) {
synchronized(ActivityManagerService.this) {
requestPssAllProcsLocked(SystemClock.uptimeMillis(),
true, false);
}
}
});
scheduleStartProfilesLocked();
}
}
}
进入sendBootCompletedLocked进行分析
void sendBootCompletedLocked(IIntentReceiver resultTo) {
for (int i = 0; i <mStartedUsers.size(); i++) {
UserState uss =mStartedUsers.valueAt(i);
finishUserBoot(uss, resultTo);
}
}
接着进入finishUserBoot
private void finishUserBoot(UserState uss, IIntentReceiver resultTo) {
。。。。。。。。
// We need to delay unlockingmanaged profiles until the parent user
// is also unlocked.
if(getUserManager().isManagedProfile(userId)) {
final UserInfo parent =getUserManager().getProfileParent(userId);
if (parent != null
&&isUserRunningLocked(parent.id, ActivityManager.FLAG_AND_UNLOCKED)) {
Slog.d(TAG, "User" + userId + " (parent " + parent.id
+ "):attempting unlock because parent is unlocked");
maybeUnlockUser(userId);
} else {
String parentId = (parent == null) ?"<null>" : String.valueOf(parent.id);
Slog.d(TAG, "User" + userId + " (parent " + parentId
+ "): delayingunlock because parent is locked");
}
} else {
maybeUnlockUser(userId);
}
}
}
接着进入maybeUnlockUser看看
boolean unlockUserCleared(final int userId, byte[] token, byte[] secret,
IProgressListener listener) {
UserState uss;
。。。。。。
finishUserUnlocking(uss);
。。。。。。。
return true;
}
继续进入finishUserUnlocking
private void finishUserUnlocking(finalUserState uss) {
final int userId =uss.mHandle.getIdentifier();
。。。。。。
if (proceedWithUnlock) {
uss.mUnlockProgress.start();
// Prepare app storage before we goany further
uss.mUnlockProgress.setProgress(5,
mService.mContext.getString(R.string.android_start_title));
mUserManager.onBeforeUnlockUser(userId);
uss.mUnlockProgress.setProgress(20);
// Dispatch unlocked to systemservices; when fully dispatched
// that calls through to the next"unlocked" phase
mHandler.obtainMessage(SYSTEM_USER_UNLOCK_MSG, userId, 0, uss)
.sendToTarget();
}
}
通过发送一个消息SYSTEM_USER_UNLOCK_MSG到AMS中,AMS中再回调
mUserController.finishUserUnlocked((UserState)msg.obj);
void finishUserUnlocked(final UserState uss) {
final int userId =uss.mHandle.getIdentifier();
。。。。。。。
} else {
finishUserUnlockedCompleted(uss);
}
}
}
}
继续分析finishUserUnlockedCompleted
private void finishUserUnlockedCompleted(UserStateuss) {
final int userId =uss.mHandle.getIdentifier();
synchronized (mService) {
// Bail if we ended up with a staleuser
if(mStartedUsers.get(uss.mHandle.getIdentifier()) != uss) return;
final UserInfo userInfo =getUserInfo(userId);
if (userInfo == null) {
return;
}
// Only keep marching forward ifuser is actually unlocked
if (!StorageManager.isUserKeyUnlocked(userId))return;
// Remember that we logged in
mUserManager.onUserLoggedIn(userId);
if (!userInfo.isInitialized()) {
if (userId !=UserHandle.USER_SYSTEM) {
Slog.d(TAG,"Initializing user #" + userId);
Intent intent = newIntent(Intent.ACTION_USER_INITIALIZE);
intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
mService.broadcastIntentLocked(null,null, intent, null,
newIIntentReceiver.Stub() {
@Override
public voidperformReceive(Intent intent, int resultCode,
String data, Bundle extras, booleanordered,
booleansticky, int sendingUser) {
// Note:performReceive is called with mService lock held
getUserManager().makeInitialized(userInfo.id);
}
}, 0, null, null,null, AppOpsManager.OP_NONE,
null, true, false,MY_PID, SYSTEM_UID, userId);
}
}
Slog.d(TAG, "SendingBOOT_COMPLETE user #" + userId);
int uptimeSeconds =(int)(SystemClock.elapsedRealtime() / 1000);
MetricsLogger.histogram(mService.mContext,"framework_boot_completed", uptimeSeconds);
//这时候就开始发送BOOT_COMPLETED消息了
final Intent bootIntent = newIntent(Intent.ACTION_BOOT_COMPLETED, null);
bootIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
bootIntent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT
|Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND);
mService.broadcastIntentLocked(null, null, bootIntent, null, null, 0,null, null,
new String[] {android.Manifest.permission.RECEIVE_BOOT_COMPLETED },
AppOpsManager.OP_NONE, null, true,false, MY_PID, SYSTEM_UID, userId);
}
}
发送BOOT_COMPLETED消息流程简单的描述了下,即在Launcher启动完毕之后,AMS开始发送该广播。
本文介绍了下AMS中关于如何管理Activity,但是没有涉及到WindowManagerService相关界面的显示,这个只是梳理下Activity在AMS中如何表现。文章有错误的地方还请读者指出来,有疑问也可以提出来。