Android -- Activity启动流程分析
Activity是Apk向用户提供交互界面的接口,它应该是我们平时最常见、最常用的组件了。在Android系统中,Activity以任务栈的形式管理,这部分内容可以参考之前的Activity任务栈部分。本文我们侧重分析Activity启动的流程,来了解Activity启动过程中,系统到底做了哪些处理。
Activity的启动过程是比较复杂的,涉及到的代码量之大,调用关系之复杂,都是令人绝望的。不过,我们并不需要读懂这个过程中的所有代码,这是没必要、也不现实的。我们的目的是掌握Activity启动过程中一些重要函数调用的含义,掌握Activity启动实现的机制,并理解Activity生命周期函数的调用时机;有了这些基础,如果我们再有兴趣继续深入分析,就不会那么绝望了。
我们有两种方式启动一个Activity,一是在Launcher中点击应用的图标;二是在应用内部,通过函数调用启动Activity;这里我们先介绍第一种情况,后续再介绍第二种情况。系统启动的第一个Apk是Launcher,我们正是从Launcher中点击某个Apk的icon,并进入该应用的。假设我们有一个名叫Test的Apk,它具有如下的配置清单文件:
<?xml version="1.0" encoding="utf-8"?>我们以此Apk为例,简要分析从Launcher启动该Apk、并最终将HomeActivity显示给用户的流程。
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.coder.lovebugs">
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity android:name=".HomeActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name=".SecondActivity" />
</application>
</manifest>
当我们点击Launcher上应用的图标时,会调用Launcher::startActivitySafely(View v, Intent intent, Object tag) 函数来开始启动应用:
boolean startActivitySafely(View v, Intent intent, Object tag) {根据函数调用,下一步层次调用:
boolean success = false;
try {
success = startActivity(v, intent, tag);//层次调用startActivity(View v, Intent intent, Object tag)
} catch (ActivityNotFoundException e) {
Toast.makeText(this, R.string.activity_not_found, Toast.LENGTH_SHORT).show();
Log.e(TAG, "Unable to launch. tag=" + tag + " intent=" + intent, e);
}
return success;
}
boolean startActivity(View v, Intent intent, Object tag) { intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);//默认添加了FLAG_ACTIVITY_NEW_TASK启动标志位 try { ... if (useLaunchAnimation) { ... } else { if (user == null || user.equals(android.os.Process.myUserHandle())) { startActivity(intent);//层次调用,Activity::startActivity(Intent)方法 } else { ... } } return true; } catch (SecurityException e) { Toast.makeText(this, R.string.activity_not_found, Toast.LENGTH_SHORT).show(); Log.e(TAG, "Launcher does not have the permission to launch " + intent + ". Make sure to create a MAIN intent-filter for the corresponding activity " + "or use the exported attribute for this activity. " + "tag="+ tag + " intent=" + intent, e); } return false; }因为,一个应用启动时,系统都会为它创建一个单独的任务栈,所以这里添加了Intent.FLAG_ACTIVITY_NEW_TASK标志,用来告知系统需要为这个应用创建一个单独的任务栈。随后继续层次调用,调用父类Activity::startActivity(Intent)函数去启动应用:
public void startActivity(Intent intent, @Nullable Bundle options) { if (options != null) { startActivityForResult(intent, -1, options); } else {//Bundle为空 // Note we want to go through this call for compatibility with // applications that may have overridden the method. startActivityForResult(intent, -1); } }参数intent包含了我们需要启动的Activity的一些信息,如下:
action: android.intent.action.MAIN //表明是主Activity由于options参数为null,则继续分析:
category: android.intent.category.LAUNCHER //表明需要在Launcher上显示图标
component:com.coder.lovebugs.HomeActivity //需要启动的Activity组件名称
public void startActivityForResult(@RequiresPermission Intent intent, int requestCode, @Nullable Bundle options) { if (mParent == null) { options = transferSpringboardActivityOptions(options); Instrumentation.ActivityResult ar = mInstrumentation.execStartActivity( this, mMainThread.getApplicationThread(), mToken, this, intent, requestCode, options);//调用Instrumentation的方法;注意参数信息;mToken等参数都标识了Launcher组建的信息 ... } else { ... } }
参数requestCode为-1,表明该Activity退出时不需要返回结果给Launcher。对象mInstrumentation是Instrumentation类型;Instrumentation负责监控组件与系统之间的交互过程,Activity、Service等都通过它来与系统交互;进入Instrumentation处理之后,Activity组件的启动过程就会交给ActivityManagerService(AMS)了,为了后续流程的分析,我们先明确下此处各个传参的基本含义:
- this:Activity实际是Context的子类,它代表了当前启动该Activity的组件,即Launcher
- mMainThread.getApplicationThread():mMainThread是ActivityThread类型,它代表了Launcher应用的主线程;getApplicationThread()函数返回的其实是ApplicationThread类型(实现了IApplicationThread接口),它是一个Binder子类;AMS通过该对象,就可以在Activity组件启动过程与Launcher的主线程进行交互了
- mToken:在AMS中,每个Activity组件都对应一个ActivityRecord对象,AMS以ActivityRecord类型来管理Activity组件。AMS为了将自己内部管理的ActivityRecord实例与某个Activity组件对应起来,就使用了一个IBinder实例来作为桥梁,对Activity和ActivityRecord进行关联。所以,AMS通过传入的Activity::mToken对象就可以在它内部找到这个Activity对应的ActivityRecord实例了
- this:也是代表当前启动该Activity的组件,即Launcher
- intent:它描述了我们需要启动的Activity组件的参数
接着进入Instrumentation.execStartActivity( Context who, IBinder contextThread, IBinder token, Activity target,Intent intent, int requestCode, Bundle options):
public ActivityResult execStartActivity(
Context who, IBinder contextThread, IBinder token, Activity target,
Intent intent, int requestCode, Bundle options) {
IApplicationThread whoThread = (IApplicationThread) contextThread;//Launcher组件的主线程
...
try {
intent.migrateExtraStreamToClipData();
intent.prepareToLeaveProcess(who);//即将离开的进程是Launcher进程
int result = ActivityManagerNative.getDefault()
.startActivity(whoThread, who.getBasePackageName(), intent,
intent.resolveTypeIfNeeded(who.getContentResolver()),
token, target != null ? target.mEmbeddedID : null,
requestCode, 0, null, options);//进入ActivityManagerService::startActivity()方法
checkStartActivityResult(result, intent);
} catch (RemoteException e) {
throw new RuntimeException("Failure from system", e);
}
return null;
}
该函数中,我们的Activity启动流程就即将进入AMS了;AMS是系统核心服务,四大组件的生命周期过程都与AMS息息相关。首先将传入的表示Launcher进程主线程的contextThread转换成IApplicationThread类型,然后按参数调用AMS::startActivity()函数。
AMS是Binder体系的一个实现类,它的继承结构图如下所示:
依据Binder IPC机制,我们首先进入ActivityManagerProxy中查看:
public int ActivityManagerProxy::startActivity(IApplicationThread caller, String callingPackage, Intent intent,
String resolvedType, IBinder resultTo, String resultWho, int requestCode,
int startFlags, ProfilerInfo profilerInfo, Bundle options) throws RemoteException {
Parcel data = Parcel.obtain();
Parcel reply = Parcel.obtain();
data.writeInterfaceToken(IActivityManager.descriptor);
data.writeStrongBinder(caller != null ? caller.asBinder() : null);
data.writeString(callingPackage);
intent.writeToParcel(data, 0);
data.writeString(resolvedType);
data.writeStrongBinder(resultTo);
data.writeString(resultWho);
data.writeInt(requestCode);
data.writeInt(startFlags);
if (profilerInfo != null) {
data.writeInt(1);
profilerInfo.writeToParcel(data, Parcelable.PARCELABLE_WRITE_RETURN_VALUE);
} else {
data.writeInt(0);
}
if (options != null) {
data.writeInt(1);
options.writeToParcel(data, 0);
} else {
data.writeInt(0);
}
mRemote.transact(START_ACTIVITY_TRANSACTION, data, reply, 0);
reply.readException();
int result = reply.readInt();
reply.recycle();
data.recycle();
return result;
}
发送了START_ACTIVITY_TRANSACTION类型的请求,再直接进入AMS的Server端看该类型请求的处理:
public boolean ActivityManagerNative::onTransact(int code, Parcel data, Parcel reply, int flags)这里直接调用Server端实现AMS中的同签名的startActivity()函数,处理这次请求调用;这样我们的Activity启动工作就正式进入了AMS。
throws RemoteException {
switch (code) {
case START_ACTIVITY_TRANSACTION:
{
data.enforceInterface(IActivityManager.descriptor);
IBinder b = data.readStrongBinder();
IApplicationThread app = ApplicationThreadNative.asInterface(b);
String callingPackage = data.readString();
Intent intent = Intent.CREATOR.createFromParcel(data);
String resolvedType = data.readString();
IBinder resultTo = data.readStrongBinder();
String resultWho = data.readString();
int requestCode = data.readInt();
int startFlags = data.readInt();
ProfilerInfo profilerInfo = data.readInt() != 0
? ProfilerInfo.CREATOR.createFromParcel(data) : null;
Bundle options = data.readInt() != 0
? Bundle.CREATOR.createFromParcel(data) : null;
int result = startActivity(app, callingPackage, intent, resolvedType,
resultTo, resultWho, requestCode, startFlags, profilerInfo, options);
reply.writeNoException();
reply.writeInt(result);
return true;
}
...
}
AMS::startActivity()函数实现如下:
@Override层次调用AMS::startActivityAsUser():
public final int startActivity(IApplicationThread caller, String callingPackage,
Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
int startFlags, ProfilerInfo profilerInfo, Bundle bOptions) {
//caller是指向Launcher的ApplicationThread对象,AMS可以通过该对象与Launcher的主线程进行交互
//intent包含了所要启动的Activity的信息
//resultTo是一个ActivityRecord的IBidner对象,它在AMS中会对应Launcher中的一个Activity组件
return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
resultWho, requestCode, startFlags, profilerInfo, bOptions,
UserHandle.getCallingUserId());//层次调用
}
@Override public final int startActivityAsUser(IApplicationThread caller, String callingPackage, Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) { enforceNotIsolatedCaller("startActivity"); userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, false, ALLOW_FULL_ONLY, "startActivity", null); // TODO: Switch to user app stacks here. return mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, profilerInfo, null, null, bOptions, false, userId, null, null/*inTask参数为null*/);//ActivityStarter实例用于管理如何启动Activity }继而调用ActivityStarter::startActivity()。AMS在处理Activity启动过程中,引入了很多的辅助类型;其中,需要注意的几个类型关系如下图所示
ActivityStarter是AMS管理Activity启动过程的一个管理类,直接看它的函数调用:
final int ActivityStarter::startActivityMayWait(IApplicationThread caller, int callingUid,首先通过resolveIntent()/resolveActivity()调用,从PackageManagerService中获取到当前需要启动的Activity的一些信息,保存到aInfo/rInfo中,然后继续调用startActivityLocked()函数处理后续流程:
String callingPackage, Intent intent, String resolvedType,
IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
IBinder resultTo, String resultWho, int requestCode, int startFlags,
ProfilerInfo profilerInfo, IActivityManager.WaitResult outResult, Configuration config,
Bundle bOptions, boolean ignoreTargetSecurity, int userId,
IActivityContainer iContainer, TaskRecord inTask) {
// Refuse possible leaked file descriptors
if (intent != null && intent.hasFileDescriptors()) {
throw new IllegalArgumentException("File descriptors passed in Intent");
}
...
// Save a copy in case ephemeral needs it
final Intent ephemeralIntent = new Intent(intent);
// Don't modify the client's object!
intent = new Intent(intent);
ResolveInfo rInfo = mSupervisor.resolveIntent(intent, resolvedType, userId);//通过PMS根据该intent获取到需要启动的组件的更多信息
if (rInfo == null) {//这种场景下,系统得到的rInfo不会为null
...
}
// Collect information about the target of the Intent.
ActivityInfo aInfo = mSupervisor.resolveActivity(intent, rInfo, startFlags, profilerInfo);//将获取到的Activity组件信息保存到ActivityInfo对象中
ActivityOptions options = ActivityOptions.fromBundle(bOptions);
ActivityStackSupervisor.ActivityContainer container =
(ActivityStackSupervisor.ActivityContainer)iContainer;
synchronized (mService) {
if (container != null && container.mParentActivity != null &&
container.mParentActivity.state != RESUMED) {
// Cannot start a child activity if the parent is not resumed.
return ActivityManager.START_CANCELED;
}
final int realCallingPid = Binder.getCallingPid();
final int realCallingUid = Binder.getCallingUid();
int callingPid;
if (callingUid >= 0) {
callingPid = -1;
} else if (caller == null) {
callingPid = realCallingPid;
callingUid = realCallingUid;
} else {
callingPid = callingUid = -1;
}
...
int res = startActivityLocked(caller, intent, ephemeralIntent, resolvedType,
aInfo, rInfo, voiceSession, voiceInteractor,
resultTo, resultWho, requestCode, callingPid,
callingUid, callingPackage, realCallingPid, realCallingUid, startFlags,
options, ignoreTargetSecurity, componentSpecified, outRecord, container,
inTask);//继续处理Activity组件启动流程
...
}
}
final int ActivityStarter::startActivityLocked(IApplicationThread caller, Intent intent, Intent ephemeralIntent, String resolvedType, ActivityInfo aInfo, ResolveInfo rInfo, IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor, IBinder resultTo, String resultWho, int requestCode, int callingPid, int callingUid, String callingPackage, int realCallingPid, int realCallingUid, int startFlags, ActivityOptions options, boolean ignoreTargetSecurity, boolean componentSpecified, ActivityRecord[] outActivity, ActivityStackSupervisor.ActivityContainer container, TaskRecord inTask) { int err = ActivityManager.START_SUCCESS; ProcessRecord callerApp = null;//调用进程对应的ProcessRecord实例,这里是Launcher进程 if (caller != null) { callerApp = mService.getRecordForAppLocked(caller);//Launcher进程所对应的ProcessRecord对象 if (callerApp != null) { callingPid = callerApp.pid;//保存Launcher进程的pid和uid信息 callingUid = callerApp.info.uid; } else { Slog.w(TAG, "Unable to find 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;//指向Launcher组件的一个ActivityRecord实例,它作为source端 ActivityRecord resultRecord = null; if (resultTo != null) {//resultTo对象指向了Launcher中一个Activity组件,这样它AMS就可以知道需要把结果返回给哪个组件 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) {//如果需要返回结果,且启动当前组件的那个Activity组件还未finish() resultRecord = sourceRecord;//则sourceRecord则就是resultRecord } } } final int launchFlags = intent.getFlags();//得到新Activity组件的启动标志 ... mInterceptor.setStates(userId, realCallingPid, realCallingUid, startFlags, callingPackage); mInterceptor.intercept(intent, rInfo, aInfo, resolvedType, inTask, callingPid, callingUid, options); intent = mInterceptor.mIntent; rInfo = mInterceptor.mRInfo; aInfo = mInterceptor.mAInfo; resolvedType = mInterceptor.mResolvedType; inTask = mInterceptor.mInTask; callingPid = mInterceptor.mCallingPid; callingUid = mInterceptor.mCallingUid; options = mInterceptor.mActivityOptions; ... ActivityRecord r = new ActivityRecord(mService, callerApp, callingUid, callingPackage, intent, resolvedType, aInfo, mService.mConfiguration, resultRecord, resultWho, requestCode, componentSpecified, voiceSession != null, mSupervisor, container, options, sourceRecord);//根据之前得到的一些信息,创建一个代表将要启动的Activity的ActivityRecord对象 ... try { mService.mWindowManager.deferSurfaceLayout(); err = startActivityUnchecked(r, sourceRecord, voiceSession, voiceInteractor, startFlags, true, options, inTask);//继续调用startActivityUnchecked();doResume为true } finally { mService.mWindowManager.continueSurfaceLayout(); } ... }首先获取到启动当前Activity的进程信息,处理Launcher组件接收启动结果的内容;最后根据一些参数初始化ActivityRecord对象,它代表了当前需要启动的Activity在AMS中的存在形式;接着继续调用startActivityUnchecked()函数进行处理:
private int ActivityStarter::startActivityUnchecked(final ActivityRecord r, ActivityRecord sourceRecord, IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor, int startFlags, boolean doResume, ActivityOptions options, TaskRecord inTask) { setInitialState(r, options, inTask, doResume, startFlags, sourceRecord, voiceSession, voiceInteractor);//设置一些变量,保存到成员变量中;mDoResume根据参数被设置为了true;mSourceRecord被设置成了sourceRecord,即将每次启动当前Activity的组件保存起来;可以用在进程内启动子Activity无需创建新栈的情况 computeLaunchingTaskFlags();//mAddingToTask被置为false computeSourceStack(); mIntent.setFlags(mLaunchFlags); mReusedActivity = getReusableIntentActivity();... boolean newTask = false; final TaskRecord taskToAffiliate = (mLaunchTaskBehind && mSourceRecord != null) ? mSourceRecord.task : null; // Should this be considered a new task? if (mStartActivity.resultTo == null/*源Activity并不需要知道启动结果*/ && mInTask == null && !mAddingToTask/*默认false*/ && (mLaunchFlags & FLAG_ACTIVITY_NEW_TASK) != 0) {//从MAS::startActivityAsUser()调用传入的inTask参数就是null;符合此项条件;mStartActivity指向当前正在启动的Activity newTask = true;//需要创建新栈 //由于该Activity的启动参数设置为FLAG_ACTIVITY_NEW_TASK,表明它运行在Launcher之外的任务中;该任务可以是新任务,也可以是某个存在的任务 setTaskFromReuseOrCreateNewTask(taskToAffiliate);//如果Activity通过android:taskAffinity属性设置了专属任务,则会去查询该任务是否存在,不存在则会创建它,并将该Activity运行在该任务中 //创建了新的TaskRecord后,它会被保存到ActivityStack::mTaskHistory中,接下来就会进入ActivityStatck去启动Activity if (mSupervisor.isLockTaskModeViolation(mStartActivity.task)) { Slog.e(TAG, "Attempted Lock Task Mode violation mStartActivity=" + mStartActivity); return START_RETURN_LOCK_TASK_MODE_VIOLATION; } if (!mMovedOtherTask) { // If stack id is specified in activity options, usually it means that activity is // launched not from currently focused stack (e.g. from SysUI or from shell) - in // that case we check the target stack. updateTaskReturnToType(mStartActivity.task, mLaunchFlags, preferredLaunchStackId != INVALID_STACK_ID ? mTargetStack : topStack); } } else if (mSourceRecord != null) {//如果走此分支,则表明当前的子Activity不需要创建新的任务栈去运行;所以它会运行在先前的任务栈中 if (mSupervisor.isLockTaskModeViolation(mSourceRecord.task)) { Slog.e(TAG, "Attempted Lock Task Mode violation mStartActivity=" + mStartActivity); return START_RETURN_LOCK_TASK_MODE_VIOLATION; } final int result = setTaskFromSourceRecord();//将先前的任务栈设置给该Activity if (result != START_SUCCESS) { return result; } } ... mTargetStack.mLastPausedActivity = null; sendPowerHintForLaunchStartIfNeeded(false /* forceSend */); mTargetStack.startActivityLocked(mStartActivity, newTask, mKeepCurTransition, mOptions);//调用ActivityStack::startActivityLocked()设置一些参数,例如将ActivityRecord放到它堆栈的顶端 if (mDoResume) { final ActivityRecord topTaskActivity = mStartActivity.task.topRunningActivityLocked(); if (!mTargetStack.isFocusable() || (topTaskActivity != null && topTaskActivity.mTaskOverlay && mStartActivity != topTaskActivity)) { // If the activity is not focusable, we can't resume it, but still would like to // make sure it becomes visible as it starts (this will also trigger entry // animation). An example of this are PIP activities. // Also, we don't want to resume activities in a task that currently has an overlay // as the starting activity just needs to be in the visible paused state until the // over is removed. mTargetStack.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS); // Go ahead and tell window manager to execute app transition for this activity // since the app transition will not be triggered through the resume channel. mWindowManager.executeAppTransition(); } else { mSupervisor.resumeFocusedStackTopActivityLocked(mTargetStack, mStartActivity, mOptions);//ActivityStackSupervisor::resumeFocusedStackTopActivityLocked()启动Activity } } else { mTargetStack.addRecentActivityLocked(mStartActivity); } ... return START_SUCCESS; }首先,先需要初始化一些变量。接着判断当前启动的Activity是否需要运行在一个单独的任务栈中;由于我们设置了FLAG_ACTIVITY_NEW_TASK标志,并且传参的结果符合需要创建新任务栈的情况,所以会调用setTaskFromReuseOrCreateNewTask()为当前Activity创建的新的任务栈(TaskRecord)。ActivityStack::startActivityLocked()函数中有一些需要注意的处理:
final void ActivityRecord::startActivityLocked(ActivityRecord r, boolean newTask, boolean keepCurTransition, ActivityOptions options) { TaskRecord rTask = r.task;//该Activity所运行的任务 final int taskId = rTask.taskId; // mLaunchTaskBehind tasks get placed at the back of the task stack. if (!r.mLaunchTaskBehind && (taskForIdLocked(taskId) == null || newTask)) { // Last activity in task had been removed or ActivityManagerService is reusing task. // Insert or replace. // Might not even be in. insertTaskAtTop(rTask, r); mWindowManager.moveTaskToTop(taskId); } TaskRecord task = null; if (!newTask) {//因为创建了新的任务栈,所以newTas为TRUE... } // Place a new activity at top of stack, so it is next to interact // with the user. task = r.task; // Slot the activity into the history stack and proceed if (DEBUG_ADD_REMOVE) Slog.i(TAG, "Adding activity " + r + " to stack to task " + task, new RuntimeException("here").fillInStackTrace()); task.addActivityToTop(r);//将本次启动的Activity加入到该任务栈的mActivities列表的最顶端 task.setFrontOfTask();//在此次的TaskRecord中,找到一个处于栈最顶端的ActivityRecord,并将它的frontOfTask设置为true r.putInHistory();//设置inHistory标志位 ... }该函数中会把当前需要启动的Activity插入到它所属的任务栈的顶端,这样后面系统在处理启动流程时,就可以检查任务栈的顶端Activity,来获取到当前需要启动的Activity了。
接着调用ActivityStackSupervisor::resumeFocusedStackTopActivityLocked()函数继续处理流程:
boolean ActivityStackSupervisor::resumeFocusedStackTopActivityLocked(最终的处理会在ActivityStack::resumeTopActivityInnerLocked()之中:
ActivityStack targetStack, ActivityRecord target, ActivityOptions targetOptions) {//调用resumeTopActivityUncheckedLocked()
if (targetStack != null && isFocusedStack(targetStack)) {
return targetStack.resumeTopActivityUncheckedLocked(target, targetOptions);
}
final ActivityRecord r = mFocusedStack.topRunningActivityLocked();
if (r == null || r.state != RESUMED) {
mFocusedStack.resumeTopActivityUncheckedLocked(null, null);//调用ActivityStack::resumeTopActivityUncheckedLocked()
}
return false;
}
boolean ActivityStack::resumeTopActivityUncheckedLocked(ActivityRecord prev, ActivityOptions options) {
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);//resumeTopActivityInnerLocked()
} finally {
mStackSupervisor.inResumeTopActivity = false;
}
return result;
}
private boolean ActivityStack::resumeTopActivityInnerLocked(ActivityRecord prev, ActivityOptions options) { if (DEBUG_LOCKSCREEN) mService.logLockScreen(""); if (!mService.mBooting && !mService.mBooted) { // Not ready yet! return false; }... // Find the first activity that is not finishing. final ActivityRecord next = topRunningActivityLocked();//找到当前Activity堆栈中第一个不是处于结束状态的Activity,即为即将要启动的Activity final TaskRecord prevTask = prev != null ? prev.task : null; if (next == null) {//如果当前Task没有Activity,显示 Home Activity // There are no more activities! ... } next.delayedResume = false; // If the top activity is the resumed one, nothing to do. if (mResumedActivity == next && next.state == ActivityState.RESUMED && mStackSupervisor.allResumedActivitiesComplete()) {//如果要启动的Activity就是当前已经resumed的Activity,则什么都不做 ... return false; } ... // If we are sleeping, and there is no resumed activity, and the top // activity is paused, well that is the state we want. if (mService.isSleepingOrShuttingDownLocked() && mLastPausedActivity == next && mStackSupervisor.allPausedActivitiesComplete()) {//如果系统正准备睡眠或关闭,直接退出 // Make sure we have executed any pending transitions, since there // should be nothing left to do at this 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 that is no longer // appropriate for it. //将启动的Activity从Stopping/GoingtoSleep/WaitingVisible等队列移除 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()) {//如果系统当前还有暂停的Activity,先退出 ... return false; } // We need to start pausing the current activity so the top one can be resumed... final boolean dontWaitForPause = (next.info.flags & FLAG_RESUME_WHILE_PAUSING) != 0; boolean pausing = mStackSupervisor.pauseBackStacks(userLeaving, next, dontWaitForPause); if (mResumedActivity != null) {//需要先暂停当前显示的Activity,此时它指向Launcher,再显示新的Activity;如果Activity已经处理了paused状态,mResumedActivity会被重置为null if (DEBUG_STATES) Slog.d(TAG_STATES, "resumeTopActivityLocked: Pausing " + mResumedActivity); pausing |= startPausingLocked(userLeaving, false, next, dontWaitForPause);//将Launcher切换至Paused状态,再返回来显示新的Activity } if (pausing) {//如果系统还有正在暂停的Activity,先退出 ... return true; } else if (mResumedActivity == next && next.state == ActivityState.RESUMED && mStackSupervisor.allResumedActivitiesComplete()) { ... } // Launching this app's activity, make sure 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 to unstop package " + next.packageName + ": " + e); }... ActivityStack lastStack = mStackSupervisor.getLastStack(); if (next.app != null && next.app.thread != null) {//如果这个Activity所在的应用进程已经存在,只需要把Activity显示出来 if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, "Resume running: " + next + " stopped=" + next.stopped + " visible=" + next.visible);... 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) {//如果是特殊的几种重启Activity的情况,先调用应用的onNewIntent() // Restrict saved surface to launcher start, or there is no intent at all // (eg. task being brought to front). If the intent is something else, // likely the app is going to 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 */);//调用应用的onNewIntent() }... next.app.thread.scheduleResumeActivity(next.appToken, next.app.repProcState, mService.isNextTransitionForward(), resumeAnimOptions);//调用应用进程该Activity的onResume()直接把它显示出来 } catch (Exception e) { // Whoops, need to restart this activity! ... } ... } else {//如果Activiy所在的应用还未启动,则先启动应用,为它创建应用进程... if (DEBUG_STATES) Slog.d(TAG_STATES, "resumeTopActivityLocked: Restarting " + next); mStackSupervisor.startSpecificActivityLocked(next, true, true);//startSpecificActivityLocked(),此时,如果应用进程已经启动,则会去直接启动Activity;否则,先为它启动一个进程 } if (DEBUG_STACK) mStackSupervisor.validateTopActivitiesLocked(); return true; }我们知道,系统在启动一个 新的Activity时,会将之前显示的Activitypause掉,再将当前的Activity resume并显示给用户;这其中就涉及到Activity生命周期变化的过程。
ActivityStack有几个成员变量控制了这个过程,它们的含义大致如下:
- ActivityRecord mPausingActivity:在启动下一个Activity之前,系统正在pause的Activity
- ActivityRecord mLastPausedActivity:系统最近处理地已经进入paused状态的Activity
- ActivityRecord mResumedActivity:系统当前正在显示、与用户直接交互的Activity
- ActivityRecord mLastStartedActivity:系统最近启动完成的Activity
首先调用topRunningActivityLocked()函数找到当前Activity堆栈中第一个不是处于结束状态的Activity,即为即将要启动的Activity,保存到next变量中。我们是在Launcher中启动一个新应用Activity的,此时系统处于resumed状态的Activity就是Launcher,即mResumedActivity不为null,并指向Launcher组件;所以,此时我们需要先暂停Launcher组件的Activity;再去启动当前新的Activity,这部分处理是调用startPausingLocked()函数实现的。
如果当前系统正在处理Activity的pause过程,则此时会先退出当前处理。之后,会先判断当前启动需要启动的Activity,它的应用进程是否已经被创建了,如果是,则会直接去resume该Activity;否则,需要先为当前的Activity创建一个新的应用进程,再去处理它的启动工作。
我们来看Launcher组件被pause的过程,直接看startPausingLocked()函数的处理:
/**首先会重置ActivityStack中一些变量的状态,mResumedActivity置为null,mPausingActivity/mLastPausedActivity则指向当前正在进入pause状态的组件,即Launcher。紧接着进入Launcher组件的主线程中处理Activity的pause过程。
* Start pausing the currently resumed activity. It is an error to call this if there
* is already an activity being paused or there is no resumed activity.
*
* @param userLeaving True if this should result in an onUserLeaving to the current activity.
* @param uiSleeping True if this is happening with the user interface going to sleep (the
* screen turning off).
* @param resuming The activity we are currently 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 does not 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 the PAUSING state, and we are waiting for
* it to tell us when it is done.
*/
final boolean ActivityStack::startPausingLocked(boolean userLeaving, boolean uiSleeping,
ActivityRecord resuming, boolean dontWait) {
if (mPausingActivity != null) {
Slog.wtf(TAG, "Going to pause when pause is already pending for " + mPausingActivity
+ " state=" + mPausingActivity.state);
if (!mService.isSleepingLocked()) {
// Avoid recursion among check for sleep and complete pause during sleeping.
// Because activity will be paused immediately after resume, just let pause
// be completed by the order of activity paused from clients.
completePauseLocked(false, resuming);
}
}
ActivityRecord prev = mResumedActivity;//当前已经Resume的Activity是Launcher中的组件,先保存一份
...
//mResumedActivity设置为null,并将mPausingActivity/mLastPausedActivity设置为即将要进入pause状态的Launcher组件
mResumedActivity = null;
mPausingActivity = prev;//当前正在进入Pause状态的组件是Launcher组件
mLastPausedActivity = prev;//当前正在进入Pause状态的组件是Launcher组件
mLastNoHistoryActivity = (prev.intent.getFlags() & Intent.FLAG_ACTIVITY_NO_HISTORY) != 0
|| (prev.info.flags & ActivityInfo.FLAG_NO_HISTORY) != 0 ? prev : null;
prev.state = ActivityState.PAUSING;
prev.task.touchActiveTime();//将prev的状态设置为PAUSING
...
if (prev.app != null && prev.app.thread != null) {//因为Launcher已经运行了,所以它的进程一定存在
if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Enqueueing pending pause: " + prev);
try {
EventLog.writeEvent(EventLogTags.AM_PAUSE_ACTIVITY,
prev.userId, System.identityHashCode(prev),
prev.shortComponentName);
mService.updateUsageStats(prev, false);
prev.app.thread.schedulePauseActivity(prev.appToken, prev.finishing,
userLeaving, prev.configChangeFlags, dontWait);//调用Launcher组件的onPause()方法,进入paused状态
} catch (Exception e) {
// Ignore exception, if process died other code will cleanup.
Slog.w(TAG, "Exception thrown during pause", e);
mPausingActivity = null;
mLastPausedActivity = null;
mLastNoHistoryActivity = null;
}
} else {
mPausingActivity = null;
mLastPausedActivity = null;
mLastNoHistoryActivity = null;
}
...
if (mPausingActivity != null) {
...
if (dontWait) {
// If the caller said they don't want to wait for the pause, then complete
// the pause now.
completePauseLocked(false, resuming);
return false;
} else {//向AMS发送一个Pause超时的延时消息,以便AMS处理Launcher组件长时间未响应的情况
// Schedule a pause timeout in case the app doesn't respond.
// We don't give it much time because this directly impacts the
// responsiveness seen by the user.
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 {
...
return false;
}
}
prev是ActivityRecord类型,它的成员app是ProcessRecord对象,描述了当前Activity所运行在的进程的信息;ProcessRecord的成员thread是IApplicationThread类型,它用于AMS和应用进程之间进行通信,实际指向ApplicationThread服务的Client端实例:ApplicationThreadProxy;这样AMS只要通过一个Activity所代表的ActivityRecord对象就可以和Activity所属的进程和主线程进行交互了;AMS所有跟生命周期相关的处理都是以此种方式跟应用进程交互的。
IApplicationThread家族的继承关系类图大致如下所示:
图中的ActivityThread类型就是代表应用进程的主线程;AMS为应用创建进程时,会指定ActivityThread的入口函数为整个进程的入口函数,并在其中做一些全局初始化工作。
这样我们就基本了解AMS是如何与应用进程交互的了。那么,我们直接看这部分的代码处理过程:
public final void ApplicationThreadProxy::schedulePauseActivity(IBinder token, boolean finished,最终处理pause的过程是向ActivityThread::H发送了一个PAUSE消息,直接看这部分的处理:
boolean userLeaving, int configChanges, boolean dontReport) throws RemoteException {
Parcel data = Parcel.obtain();
data.writeInterfaceToken(IApplicationThread.descriptor);
data.writeStrongBinder(token);
data.writeInt(finished ? 1 : 0);
data.writeInt(userLeaving ? 1 :0);
data.writeInt(configChanges);
data.writeInt(dontReport ? 1 : 0);
mRemote.transact(SCHEDULE_PAUSE_ACTIVITY_TRANSACTION, data, null,
IBinder.FLAG_ONEWAY);
data.recycle();
}
@Override
public boolean ApplicationThreadNative::onTransact(int code, Parcel data, Parcel reply, int flags)
throws RemoteException {
switch (code) {
case SCHEDULE_PAUSE_ACTIVITY_TRANSACTION:
{
data.enforceInterface(IApplicationThread.descriptor);
IBinder b = data.readStrongBinder();
boolean finished = data.readInt() != 0;
boolean userLeaving = data.readInt() != 0;
int configChanges = data.readInt();
boolean dontReport = data.readInt() != 0;
schedulePauseActivity(b, finished, userLeaving, configChanges, dontReport);
return true;
}
...
}
/**
* This manages the execution of the main thread in an
* application process, scheduling and executing activities,
* broadcasts, and other operations on it as the activity
* manager requests.
*
* {@hide}
*/
public final class ActivityThread {
final H mH = new H();
private void sendMessage(int what, Object obj, int arg1, int arg2, int seq) {
if (DEBUG_MESSAGES) Slog.v(
TAG, "SCHEDULE " + mH.codeToString(what) + " arg1=" + arg1 + " arg2=" + arg2 +
"seq= " + seq);
Message msg = Message.obtain();
msg.what = what;
SomeArgs args = SomeArgs.obtain();
args.arg1 = obj;
args.argi1 = arg1;
args.argi2 = arg2;
args.argi3 = seq;
msg.obj = args;
mH.sendMessage(msg);
}
private class ApplicationThread extends ApplicationThreadNative {
public final void schedulePauseActivity(IBinder token, boolean finished,
boolean userLeaving, int configChanges, boolean dontReport) {
int seq = getLifecycleSeq();
if (DEBUG_ORDER) Slog.d(TAG, "pauseActivity " + ActivityThread.this
+ " operation received seq: " + seq);
sendMessage(
finished ? H.PAUSE_ACTIVITY_FINISHING : H.PAUSE_ACTIVITY,
token,
(userLeaving ? USER_LEAVING : 0) | (dontReport ? DONT_REPORT : 0),
configChanges,
seq);
}
}
private class H extends Handler {
public void handleMessage(Message msg) {
...
}
}
}
public void handleMessage(Message msg) { if (DEBUG_MESSAGES) Slog.v(TAG, ">>> handling: " + codeToString(msg.what)); switch (msg.what) {... case PAUSE_ACTIVITY: { Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityPause"); SomeArgs args = (SomeArgs) msg.obj; handlePauseActivity((IBinder) args.arg1, false, (args.argi1 & USER_LEAVING) != 0, args.argi2, (args.argi1 & DONT_REPORT) != 0, args.argi3); maybeSnapshot(); Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); } break;}}原来是直接调用handlePauseActivity()函数进行处理:
private void ActivityThread::handlePauseActivity(IBinder token, boolean finished, boolean userLeaving, int configChanges, boolean dontReport, int seq) { ActivityClientRecord r = mActivities.get(token); if (DEBUG_ORDER) Slog.d(TAG, "handlePauseActivity " + r + ", seq: " + seq); if (!checkAndUpdateLifecycleSeq(seq, r, "pauseActivity")) { return; } if (r != null) { //Slog.v(TAG, "userLeaving=" + userLeaving + " handling pause of " + r); if (userLeaving) { performUserLeavingActivity(r); } r.activity.mConfigChangeFlags |= configChanges; performPauseActivity(token, finished, r.isPreHoneycomb(), "handlePauseActivity");//调用performPauseActivity() // Make sure any pending writes are now committed. if (r.isPreHoneycomb()) { QueuedWork.waitToFinish(); } // Tell the activity manager we have paused. if (!dontReport) { try { ActivityManagerNative.getDefault().activityPaused(token);//将已经进入Paused状态的Activity的结果告知AMS } catch (RemoteException ex) { throw ex.rethrowFromSystemServer(); } } mSomeActivitiesChanged = true; } }直接看performPauseActivity()函数:
final Bundle performPauseActivity(IBinder token, boolean finished, boolean saveState, String reason) { ActivityClientRecord r = mActivities.get(token); return r != null ? performPauseActivity(r, finished, saveState, reason) : null; } final Bundle performPauseActivity(ActivityClientRecord r, boolean finished, boolean saveState, String reason) { if (r.paused) { if (r.activity.mFinished) { // If we are finishing, we won't call onResume() in certain cases. // So here we likewise don't want to call onPause() if the activity // isn't resumed. return null; } RuntimeException e = new RuntimeException( "Performing pause of activity that is not resumed: " + r.intent.getComponent().toShortString()); Slog.e(TAG, e.getMessage(), e); } if (finished) { r.activity.mFinished = true; } // Next have the activity save its current state and managed dialogs... if (!r.activity.mFinished && saveState) { callCallActivityOnSaveInstanceState(r); } performPauseActivityIfNeeded(r, reason);//调用performPauseActivityIfNeeded() // Notify any outstanding on paused listeners ArrayList<OnActivityPausedListener> listeners; synchronized (mOnPauseListeners) { listeners = mOnPauseListeners.remove(r.activity); } int size = (listeners != null ? listeners.size() : 0); for (int i = 0; i < size; i++) { listeners.get(i).onPaused(r.activity); } return !r.activity.mFinished && saveState ? r.state : null; }
ActivityThread::mActivities成员以IBinder为键值,保存了所有运行在该应用进程之中的Activity;每个Activity以ActivityClientRecord类型表示。
在主线程中根据mToken实例找到了代表当前需要进入pause状态的Activity对应的ActivityClientRecord实例后,调用performPauseActivityIfNeeded()函数处理该Activity的onPause(),随后并将当前Activity的处理结果反馈给AMS;直接看:
private void ActivityThread::performPauseActivityIfNeeded(ActivityClientRecord r, String reason) {通过Instrumentation调用该Activity的onPause()函数:
if (r.paused) {
// You are already paused silly...
return;
}
try {
r.activity.mCalled = false;
mInstrumentation.callActivityOnPause(r.activity);//调用当前即将进入pause状态的Activity::onPause()
EventLog.writeEvent(LOG_AM_ON_PAUSE_CALLED, UserHandle.myUserId(),
r.activity.getComponentName().getClassName(), reason);
if (!r.activity.mCalled) {
throw new SuperNotCalledException("Activity " + safeToComponentShortString(r.intent)
+ " did not call through to super.onPause()");
}
} catch (SuperNotCalledException e) {
throw e;
} catch (Exception e) {
if (!mInstrumentation.onException(r.activity, e)) {
throw new RuntimeException("Unable to pause activity "
+ safeToComponentShortString(r.intent) + ": " + e.toString(), e);
}
}
r.paused = true;//再将该Activity的paused置为true,表明它已经进入了paused状态
}
private void ActivityThread::performPauseActivityIfNeeded(ActivityClientRecord r, String reason) { if (r.paused) { // You are already paused silly... return; } try { r.activity.mCalled = false; mInstrumentation.callActivityOnPause(r.activity);//调用当前即将进入pause状态的Activity::onPause() EventLog.writeEvent(LOG_AM_ON_PAUSE_CALLED, UserHandle.myUserId(), r.activity.getComponentName().getClassName(), reason); if (!r.activity.mCalled) { throw new SuperNotCalledException("Activity " + safeToComponentShortString(r.intent) + " did not call through to super.onPause()"); } } catch (SuperNotCalledException e) { throw e; } catch (Exception e) { if (!mInstrumentation.onException(r.activity, e)) { throw new RuntimeException("Unable to pause activity " + safeToComponentShortString(r.intent) + ": " + e.toString(), e); } } r.paused = true;//再将该Activity的paused置为true,表明它已经进入了paused状态 }/** * Perform calling of an activity's {@link Activity#onPause} method. The * default implementation simply calls through to that method. * * @param activity The activity being paused. */ public void Instrumentation::callActivityOnPause(Activity activity) { activity.performPause(); }final void Activity::performPause() { mDoReportFullyDrawn = false; mFragments.dispatchPause(); mCalled = false; onPause(); //调用了当前Activity所属的onPause()函数 mResumed = false; if (!mCalled && getApplicationInfo().targetSdkVersion >= android.os.Build.VERSION_CODES.GINGERBREAD) { throw new SuperNotCalledException( "Activity " + mComponent.toShortString() + " did not call through to super.onPause()"); } mResumed = false; }随后在将当前已经进入pause状态的Activity的状态也设置为paused;至此,Launcher Activity组件进入pause状态的处理就结束了。这一部分的处理流程有一定的共同性,后续再分析这部分内容时,就会跳过一些Binder调用的过程,以简化分析过程。
Launcher组件的Activity进入pause状态后,还需要将结果反馈给AMS:
private void ActivityThread::handlePauseActivity(IBinder token, boolean finished,传入的参数是代表Launcher组件的一个IBinder对象,AMS可以根据该实例找到对应的ActivityRecord实例;直接分析AMS::activityPaused()函数:
boolean userLeaving, int configChanges, boolean dontReport, int seq) {
...
// Tell the activity manager we have paused.
if (!dontReport) {
try {
ActivityManagerNative.getDefault().activityPaused(token);//将已经进入Paused状态的Activity的结果告知AMS
} catch (RemoteException ex) {
throw ex.rethrowFromSystemServer();
}
}
mSomeActivitiesChanged = true;
}
}
@Override public final void ActivityManagerService::activityPaused(IBinder token) { final long origId = Binder.clearCallingIdentity(); synchronized(this) { ActivityStack stack = ActivityRecord.getStackLocked(token); if (stack != null) { stack.activityPausedLocked(token, false);//调用activityPausedLocked() } } Binder.restoreCallingIdentity(origId); }其中涉及到的Binder通信的部分,可以参考之前的分析过程。直接调用ActivityStack::activityPausedLocked()函数:
final void ActivityStack::activityPausedLocked(IBinder token, boolean timeout) { if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Activity paused: token=" + token + ", timeout=" + timeout); final ActivityRecord r = isInStackLocked(token);//根据token找到任务栈中Launcher对应的组件 if (r != null) { mHandler.removeMessages(PAUSE_TIMEOUT_MSG, r);//移除之前发送的PAUSE_TIMEOUT_MSG消息;因为该组件已经在规定的时间内进入pause成功了 if (mPausingActivity == r) {//mPausingActivity之前设置过,它此时也指向Launcher组件 if (DEBUG_STATES) Slog.v(TAG_STATES, "Moving to PAUSED: " + r + (timeout ? " (due to timeout)" : " (pause complete)")); completePauseLocked(true, null);//参数resumeNext值为true return; } else { ... } } ... }首先根据token参数找到对应的Launcher组件的ActivityRecord对象,因为之前的处理过程mPausingActivity已经执行了Launcher组件,所以此时会移除之前发送的处理pause超时的消息,并调用completePauseLocked()函数处理后续新Activity的启动过程:
private void ActivityStack::completePauseLocked(boolean resumeNext, ActivityRecord resuming) { ActivityRecord prev = mPausingActivity;//在处理pause状态是,该成员已经被设置过,不会为null if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Complete pause: " + prev); if (prev != null) { final boolean wasStopping = prev.state == ActivityState.STOPPING; prev.state = ActivityState.PAUSED; if (prev.finishing) { if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Executing finish of activity: " + prev); prev = finishCurrentActivityLocked(prev, FINISH_AFTER_VISIBLE, false); } else if (prev.app != null) { ... } else { if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "App died during pause, not stopping: " + prev); prev = null; } ... mPausingActivity = null;//最后重置mPausingActivity状态,因为此时Launcher已经是paused了 } if (resumeNext) {//为true final ActivityStack topStack = mStackSupervisor.getFocusedStack(); if (!mService.isSleepingOrShuttingDownLocked()) {//如果此时设备未处于休眠或关闭状态,则去启动位于Activity组件堆栈顶端的Activity mStackSupervisor.resumeFocusedStackTopActivityLocked(topStack, prev, null);//调用resumeFocusedStackTopActivityLocked()去启动任务栈顶端的Activity } else { mStackSupervisor.checkReadyForSleepLocked(); ActivityRecord top = topStack.topRunningActivityLocked(); if (top == null || (prev != null && top != prev)) { // If there 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(); } } }... }resumeNext参数传入的值为true;首先会清空一些状态,将mPausingActivity指向的Activity状态设置为PAUSED,随后并置为null。接着调用ActivityStackSupervisor.resumeFocusedStackTopActivityLocked()函数去启动当前任务栈顶端的Activity,即目标Activity:
boolean ActivityStackSupervisor::resumeFocusedStackTopActivityLocked( ActivityStack targetStack, ActivityRecord target, ActivityOptions targetOptions) {//调用resumeTopActivityUncheckedLocked() if (targetStack != null && isFocusedStack(targetStack)) { return targetStack.resumeTopActivityUncheckedLocked(target, targetOptions); } final ActivityRecord r = mFocusedStack.topRunningActivityLocked(); if (r == null || r.state != RESUMED) { mFocusedStack.resumeTopActivityUncheckedLocked(null, null);//调用resumeTopActivityUncheckedLocked() } return false; }boolean ActivityStack::resumeTopActivityUncheckedLocked(ActivityRecord prev, ActivityOptions options) { 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);//resumeTopActivityInnerLocked() } finally { mStackSupervisor.inResumeTopActivity = false; } return result; }与先前一样,还是进入ActivityStack::resumeTopActivityInnerLocked()函数:
private boolean ActivityStack::resumeTopActivityInnerLocked(ActivityRecord prev, ActivityOptions options) { if (DEBUG_LOCKSCREEN) mService.logLockScreen("");... // Find the first activity that is not finishing. final ActivityRecord next = topRunningActivityLocked();//找到当前Activity堆栈中第一个不是处于结束状态的Activity,即为即将要启动的Activity ... // We need to start pausing the current activity so the top one can be resumed... final boolean dontWaitForPause = (next.info.flags & FLAG_RESUME_WHILE_PAUSING) != 0; boolean pausing = mStackSupervisor.pauseBackStacks(userLeaving, next, dontWaitForPause); if (mResumedActivity != null) {//需要先暂停当前显示的Activity,此时它指向Launcher,再显示新的Activity;如果Activity已经处理了paused状态,mResumedActivity会被重置为null if (DEBUG_STATES) Slog.d(TAG_STATES, "resumeTopActivityLocked: Pausing " + mResumedActivity); pausing |= startPausingLocked(userLeaving, false, next, dontWaitForPause);//将Launcher切换至Paused状态,再返回来显示新的Activity } if (pausing) {//如果系统还有正在暂停的Activity,先退出 ... } else if (mResumedActivity == next && next.state == ActivityState.RESUMED && ... }... ActivityStack lastStack = mStackSupervisor.getLastStack(); if (next.app != null && next.app.thread != null) {//如果这个Activity所在的应用进程已经存在,只需要把Activity显示出来 ... } else {//如果Activiy所在的应用还未启动,则先启动应用 ... mStackSupervisor.startSpecificActivityLocked(next, true, true);//startSpecificActivityLocked(),此时,如果应用进程已经启动,则会去直接启动Activity;否则,先为它启动一个进程 } if (DEBUG_STACK) mStackSupervisor.validateTopActivitiesLocked(); return true; }根据之前的处理,mResumedActivity/mPausingActivity都以置为null;因为,我们需要启动的Activity它的应用进程并未创建过,所以这里需要为它创建一个应用进程:
void ActivityStackSupervisor::startSpecificActivityLocked(ActivityRecord r, boolean andResume, boolean checkConfig) { // Is this activity's application already running? ProcessRecord app = mService.getProcessRecordLocked(r.processName, r.info.applicationInfo.uid, true); r.task.stack.setLaunchTime(r); 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 is a platform component that is marked // to run in multiple processes, because this is actually // part of the framework so doesn't make sense to track as a // separate apk in the process. app.addPackage(r.info.packageName, r.info.applicationInfo.versionCode, mService.mProcessStats); } realStartActivityLocked(r, app, andResume, checkConfig);//如果应用进程已经启动了,则调用该函数继续处理;其会触发类的onCreate()方法 return; } catch (RemoteException e) { Slog.w(TAG, "Exception when starting activity " + r.intent.getComponent().flattenToShortString(), e); } // If a dead object exception was thrown -- fall through to // restart the application. } mService.startProcessLocked(r.processName, r.info.applicationInfo, true, 0, "activity", r.intent.getComponent(), false, false, true);//应用进程没有启动,则去启动应用进程 }
因为我们的应用并未启动过,所以需要为它创建应用,这是通过ASM::startProcessLocked()处理的;否则,当前应用进程已经启动过,此时只需要直接启动当前Activity即可,这部分由realStartActivityLocked()处理。
AMS为应用创建进程是借助fork机制实现的,并指定了应用进程的入口函数是ActivityThread::main(),这部分内容会在后续的文章中分析;当系统进程创建工作完成后,就会进入ActivityThread::main()函数:
//应用进程的入口函数这里主要创建了ActivityThread实例并调用了attach()函数,紧接着并启动了消息循环。ActivityThread的构造函数并没有什么重要的工作,我们主要看attach()函数的实现:
public static void ActivityThread::main(String[] args) {
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "ActivityThreadMain");
SamplingProfilerIntegration.start();
// CloseGuard defaults to true and can be quite spammy. We
// disable it here, but selectively enable it later (via
// StrictMode) on debug builds, but using DropBox, not logs.
CloseGuard.setEnabled(false);
Environment.initForCurrentUser();
// Set the reporter for event logging in libcore
EventLogger.setReporter(new EventLoggingReporter());
// Make sure TrustedCertificateStore looks 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 = new ActivityThread();//创建ActivityThread对象
thread.attach(false);//调用attach()向AMS发送一个进程启动完成通知
if (sMainThreadHandler == null) {
sMainThreadHandler = thread.getHandler();
}
if (false) {
Looper.myLooper().setMessageLogging(new
LogPrinter(Log.DEBUG, "ActivityThread"));
}
// End of event ActivityThreadMain.
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
Looper.loop();//开启消息循环
throw new RuntimeException("Main thread loop unexpectedly exited");
}
private void ActivityThrad::attach(boolean system) {调用了AMS::attachApplication()函数,告知AMS当前为应用新创建的进程已经准备好了,可以开始启动Activity了;mAppThread的定义是:
sCurrentActivityThread = this;
mSystemThread = system;
if (!system) {//传参为false
...
RuntimeInit.setApplicationObject(mAppThread.asBinder());//将ApplicationThread对象添加到RuntimeInit中
final IActivityManager mgr = ActivityManagerNative.getDefault();
try {
mgr.attachApplication(mAppThread);//调用AMS::attachApplication(),表明当次想要启动的应用进程已经启动完毕;参数是ApplicationThread对象,它用于AMS和ActivityThread所在的进程之间的通信
} catch (RemoteException ex) {
throw ex.rethrowFromSystemServer();
}
...
} else {
...
}
...
}
final ApplicationThread mAppThread = new ApplicationThread();将它传递给AMS,AMS就可以通过它与该新创建的应用进程和主线程交互了。我们看AMS::attachApplication()函数的实现:
@Override public final void AMS::attachApplication(IApplicationThread thread) { synchronized (this) { int callingPid = Binder.getCallingPid(); final long origId = Binder.clearCallingIdentity(); attachApplicationLocked(thread, callingPid);//调用attachApplicationLocked() Binder.restoreCallingIdentity(origId); } } private final boolean AMS::attachApplicationLocked(IApplicationThread thread, int pid) { // Find the application record that is being attached... either via // the pid if we are running in multiple processes, or just pull the // next app record if we are emulating process with anonymous threads. ProcessRecord app; if (pid != MY_PID && pid >= 0) { synchronized (mPidsSelfLocked) { app = mPidsSelfLocked.get(pid);//创建应用进程时,会将进程对象和pid保存到mPidsSelfLocked集合中,所以此时可以取出对应的进程对象 } } else { app = null; } if (app == null) { ... } // If this application record is still attached to a previous // process, clean it up now. if (app.thread != null) {//如果app中已经有线程,说明app以前存在,现在是重启;先清理掉这些信息 handleAppDiedLocked(app, true, true); } final String processName = app.processName; try { AppDeathRecipient adr = new AppDeathRecipient( app, pid, thread);//创建app死亡监听对象 thread.asBinder().linkToDeath(adr, 0); app.deathRecipient = adr; } catch (RemoteException e) { app.resetPackageList(mProcessStats); startProcessLocked(app, "link fail", processName); return false; } app.makeActive(thread, mProcessStats);//会将创建的ActivityThread对应的ApplicationThread对象的Binder实例保存到该ProcessRecord对象的thread成员中,用以和该进程的主线程交互 ... mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);... try {... thread.bindApplication(processName, appInfo, providers, app.instrumentationClass, profilerInfo, app.instrumentationArguments, app.instrumentationWatcher, app.instrumentationUiAutomationConnection, testMode, mBinderTransactionTrackingEnabled, enableTrackAllocation, isRestrictedBackupMode || !normalMode, app.persistent, new Configuration(mConfiguration), app.compat, getCommonServicesLocked(app.isolated), mCoreSettingsObserver.getCoreSettingsLocked());//调用bindApplication()方法 updateLruProcessLocked(app, false, null); app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis(); } catch (Exception e) { ... } // Remove this record from the list of starting applications. mPersistentStartingProcesses.remove(app); if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES, "Attach application locked removing on hold: " + app); mProcessesOnHold.remove(app); boolean badApp = false; boolean didSomething = false; // See if the top visible activity is waiting to run in this process... if (normalMode) { try { if (mStackSupervisor.attachApplicationLocked(app)) {//调用attachApplicationLocked(),去启动当前Activity组件堆栈最顶端的Activity didSomething = true; } } catch (Exception e) { Slog.wtf(TAG, "Exception thrown launching activities in " + app, e); badApp = true; } }... return true;}
首先会调用thread的bindApplication()函数,它会做一些应用共用的初始化动作,直接看它在ActivityThread中的处理:
public final void ApplicationThread::bindApplication(String processName, ApplicationInfo appInfo,从代码可以得知,一个ActivityThread对象,即一个应用的主线程中只会存在一个LoadedApk、Instrumentation、Application等实例,它们在一个应用进程中被所有Activity共用。
List<ProviderInfo> providers, ComponentName instrumentationName,
ProfilerInfo profilerInfo, Bundle instrumentationArgs,
IInstrumentationWatcher instrumentationWatcher,
IUiAutomationConnection instrumentationUiConnection, 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 in the ServiceManager
ServiceManager.initServiceCache(services);
}
setCoreSettings(coreSettings);
AppBindData data = new AppBindData();
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);
}
private void ActivityThread::handleBindApplication(AppBindData data) {
// Register the UI Thread as a sensitive thread to the runtime.
VMRuntime.registerSensitiveThread();
...
data.info = getPackageInfoNoCheck(data.appInfo, data.compatInfo);//初始化LoadedApk对象
...
// Instrumentation info affects the class loader, so load it before
// setting up the app context.
final InstrumentationInfo ii;
if (data.instrumentationName != null) {//如果应用指定了自己的Instrumentation,则去初始化它;否则,直接创建Instrumentation实例
try {
ii = new ApplicationPackageManager(null, getPackageManager())
.getInstrumentationInfo(data.instrumentationName, 0);
} catch (PackageManager.NameNotFoundException e) {
throw new RuntimeException(
"Unable to find instrumentation 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;
}
final ContextImpl appContext = ContextImpl.createAppContext(this, data.info);//生成ContextImpl对象
updateLocaleListFromAppContext(appContext,
mResourcesManager.getConfiguration().getLocales());
...
// Continue loading instrumentation.
if (ii != null) {如果应用指定了自己的Instrumentation类型,则去初始化它;否则,直接创建Instrumentation实例
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 instantiate instrumentation "
+ 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 = new File(mProfiler.profileFile);
file.getParentFile().mkdirs();
Debug.startMethodTracing(file.toString(), 8 * 1024 * 1024);
}
} else {
mInstrumentation = new Instrumentation();
}
...
try {
// If the app is being launched for full backup or restore, bring it up in
// a restricted environment with the base application class.
Application app = data.info.makeApplication(data.restrictedBackupMode, null);
mInitialApplication = app;
...
// Do this after providers, since instrumentation tests generally start their
// test thread at this point, and we don't want that racing.
try {
mInstrumentation.onCreate(data.instrumentationArgs);
}
catch (Exception e) {
...
}
try {
mInstrumentation.callApplicationOnCreate(app);
} catch (Exception e) {
...
}
} finally {
StrictMode.setThreadPolicy(savedPolicy);
}
}
public final LoadedApk ActivityThread::getPackageInfoNoCheck(ApplicationInfo ai,
CompatibilityInfo compatInfo) {
return getPackageInfo(ai, compatInfo, null, false, true, false);
}
private LoadedApk ActivityThread::getPackageInfo(ApplicationInfo aInfo, CompatibilityInfo compatInfo,
ClassLoader baseLoader, boolean securityViolation, boolean includeCode,
boolean registerPackage) {
final boolean differentUser = (UserHandle.myUserId() != UserHandle.getUserId(aInfo.uid));
synchronized (mResourcesManager) {
WeakReference<LoadedApk> ref;
if (differentUser) {
// Caching not supported across users
ref = null;
} else if (includeCode) {
ref = mPackages.get(aInfo.packageName);
} else {
ref = mResourcePackages.get(aInfo.packageName);
}
LoadedApk packageInfo = ref != null ? ref.get() : null;
if (packageInfo == null || (packageInfo.mResources != null
&& !packageInfo.mResources.getAssets().isUpToDate())) {
if (localLOGV) Slog.v(TAG, (includeCode ? "Loading code package "
: "Loading resource-only package ") + aInfo.packageName
+ " (in " + (mBoundApplication != null
? mBoundApplication.processName : null)
+ ")");
packageInfo =
new LoadedApk(this, aInfo, compatInfo, baseLoader,
securityViolation, includeCode &&
(aInfo.flags&ApplicationInfo.FLAG_HAS_CODE) != 0, registerPackage);
if (mSystemThread && "android".equals(aInfo.packageName)) {
packageInfo.installSystemApplicationInfo(aInfo,
getSystemContext().mPackageInfo.getClassLoader());
}
if (differentUser) {
// Caching not supported across users
} else if (includeCode) {
mPackages.put(aInfo.packageName,
new WeakReference<LoadedApk>(packageInfo));
} else {
mResourcePackages.put(aInfo.packageName,
new WeakReference<LoadedApk>(packageInfo));
}
}
return packageInfo;
}
}
public Application LoadedApk::makeApplication(boolean forceDefaultAppClass,
Instrumentation instrumentation) {
if (mApplication != null) {
return mApplication;
}
...
Application app = null;
...
try {
...
ContextImpl appContext = ContextImpl.createAppContext(mActivityThread, this);
app = mActivityThread.mInstrumentation.newApplication(
cl, appClass, appContext);
appContext.setOuterContext(app);
} catch (Exception e) {
...
}
mActivityThread.mAllApplications.add(app);
mApplication = app;
if (instrumentation != null) {
try {
instrumentation.callApplicationOnCreate(app);
} catch (Exception e) {
...
}
}
...
return app;
}
接着调用ActivityStackSupervisor.attachApplicationLocked()在该进程启动当前的目标Activity:
boolean ActivityStackSupervisor::attachApplicationLocked(ProcessRecord app) throws RemoteException {首先得到当前任务栈顶端的Activity,它既是我们当前需要启动的目标。因为该Activity尚未启动,所以会去调用realStartActivityLocked()去启动:
final String processName = 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();//得到Activity堆栈最顶端的Activity,去启动它
if (hr != null) {
if (hr.app == null && app.uid == hr.info.applicationInfo.uid
&& processName.equals(hr.processName)) {//该Activity的app为null,且它的uid和进程名都与此次的进程相同,表明这个进程就是为该Activity创建的;则去启动该Activity
try {
if (realStartActivityLocked(hr, app, true, true)) {//启动这个Activity
didSomething = true;
}
} catch (RemoteException e) {
Slog.w(TAG, "Exception in new application when starting activity "
+ hr.intent.getComponent().flattenToShortString(), e);
throw e;
}
}
}
}
}
if (!didSomething) {//如果Activity堆栈对顶端的组件已经启动,但是窗口没有显示出来,则去显示它
ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
}
return didSomething;
}
final boolean ActivityStackSupervisor::realStartActivityLocked(ActivityRecord r, ProcessRecord app, boolean andResume, boolean checkConfig) throws RemoteException {... 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); if (idx < 0) { app.activities.add(r);//将此次启动的Activity添加到该进程的activities列表中,它保存了所有运行在该进程中的Activity信息 } ... final ActivityStack stack = task.stack; try { ... if (andResume) { app.hasShownUi = true; app.pendingUiClean = true; } ... app.thread.scheduleLaunchActivity(new Intent(r.intent), r.appToken, System.identityHashCode(r), r.info, new Configuration(mService.mConfiguration), new Configuration(task.mOverrideConfig), r.compat, r.launchedFromPackage, task.voiceInteractor, app.repProcState, r.icicle, r.persistentState, results, newIntents, !andResume, mService.isNextTransitionForward(), profilerInfo);//调用ActivityThread中的handleLaunchActivity()函数去launch一个Activity,AMS与ActivityThread通信要借助ApplicationThread对象 ... } catch (RemoteException e) { ... } r.launchFailed = false; ... return true; }将会调用前面提到的IApplicationThread对象的scheduleLaunchActivity()函数去launch当前的Activity:
public final void ApplicationThreadProxy::scheduleLaunchActivity(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, boolean isForward, ProfilerInfo profilerInfo) throws RemoteException { Parcel data = Parcel.obtain(); data.writeInterfaceToken(IApplicationThread.descriptor); intent.writeToParcel(data, 0); data.writeStrongBinder(token); data.writeInt(ident); info.writeToParcel(data, 0); curConfig.writeToParcel(data, 0); if (overrideConfig != null) { data.writeInt(1); overrideConfig.writeToParcel(data, 0); } else { data.writeInt(0); } compatInfo.writeToParcel(data, 0); data.writeString(referrer); data.writeStrongBinder(voiceInteractor != null ? voiceInteractor.asBinder() : null); data.writeInt(procState); data.writeBundle(state); data.writePersistableBundle(persistentState); data.writeTypedList(pendingResults); data.writeTypedList(pendingNewIntents); data.writeInt(notResumed ? 1 : 0); data.writeInt(isForward ? 1 : 0); if (profilerInfo != null) { data.writeInt(1); profilerInfo.writeToParcel(data, Parcelable.PARCELABLE_WRITE_RETURN_VALUE); } else { data.writeInt(0); } mRemote.transact(SCHEDULE_LAUNCH_ACTIVITY_TRANSACTION, data, null, IBinder.FLAG_ONEWAY); data.recycle(); } @Override public boolean ApplicationThreadNative::onTransact(int code, Parcel data, Parcel reply, int flags) throws RemoteException {case SCHEDULE_LAUNCH_ACTIVITY_TRANSACTION: { data.enforceInterface(IApplicationThread.descriptor); Intent intent = Intent.CREATOR.createFromParcel(data); IBinder b = data.readStrongBinder(); int ident = data.readInt(); ActivityInfo info = ActivityInfo.CREATOR.createFromParcel(data); Configuration curConfig = Configuration.CREATOR.createFromParcel(data); Configuration overrideConfig = null; if (data.readInt() != 0) { overrideConfig = Configuration.CREATOR.createFromParcel(data); } CompatibilityInfo compatInfo = CompatibilityInfo.CREATOR.createFromParcel(data); String referrer = data.readString(); IVoiceInteractor voiceInteractor = IVoiceInteractor.Stub.asInterface( data.readStrongBinder()); int procState = data.readInt(); Bundle state = data.readBundle(); PersistableBundle persistentState = data.readPersistableBundle(); List<ResultInfo> ri = data.createTypedArrayList(ResultInfo.CREATOR); List<ReferrerIntent> pi = data.createTypedArrayList(ReferrerIntent.CREATOR); boolean notResumed = data.readInt() != 0; boolean isForward = data.readInt() != 0; ProfilerInfo profilerInfo = data.readInt() != 0 ? ProfilerInfo.CREATOR.createFromParcel(data) : null; scheduleLaunchActivity(intent, b, ident, info, curConfig, overrideConfig, compatInfo, referrer, voiceInteractor, procState, state, persistentState, ri, pi, notResumed, isForward, profilerInfo); return true; }}直接调用ApplicationThread::scheduleLauncherActivity:
// we use token to identify this activity without having to send the // activity itself back to the activity manager. (matters more with ipc) @Override public final void ApplicationThread::scheduleLaunchActivity(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, boolean isForward, ProfilerInfo profilerInfo) { updateProcessState(procState, false); ActivityClientRecord r = new ActivityClientRecord();//创建ActivityClientRecord对象,并进行初始化 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); } public void ActivityThrad::H::handleMessage(Message msg) { if (DEBUG_MESSAGES) Slog.v(TAG, ">>> handling: " + codeToString(msg.what)); switch (msg.what) { case LAUNCH_ACTIVITY: { Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityStart"); final ActivityClientRecord r = (ActivityClientRecord) msg.obj; r.packageInfo = getPackageInfoNoCheck( r.activityInfo.applicationInfo, r.compatInfo); handleLaunchActivity(r, null, "LAUNCH_ACTIVITY"); Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); } break;}}首先会将AMS传入的参数封装成ActivityClientRecord对象,然后调用ActivityThread::handleLaunchActivity():
private void ActivityThread::handleLaunchActivity(ActivityClientRecord r, Intent customIntent, String reason) {分别会调用performLaunchActivity()和handleResumeActivity()来完成当前启动Activity的初始化及生命周期调用工作;首先看performLaunchActivity():
...
Activity a = performLaunchActivity(r, customIntent);//调用performLaunchActivity(),过程中会执行Activity::onCreate()和onStart()方法
if (a != null) {
...
handleResumeActivity(r.token, false, r.isForward,
!r.activity.mFinished && !r.startsNotResumed, r.lastProcessedSeq, reason);//调用handleResumeActivity(),过程中会执行Activity::onResume()方法
if (!r.activity.mFinished && r.startsNotResumed) {
// The activity manager actually wants this one to start out paused, because it
// needs to be visible but isn't in the foreground. We accomplish this by going
// through the normal startup (because activities expect to go through onResume()
// the first time they run, before their window is displayed), and then pausing it.
// However, in this case we do -not- need to do the full pause cycle (of freezing
// and such) because the activity manager assumes it can just retain the current
// state it has.
performPauseActivityIfNeeded(r, reason);
// We need to keep around the original state, in case we need to be created again.
// But we only do this for pre-Honeycomb apps, which always save their state when
// pausing, so we can not have them save their state when restarting from a paused
// state. For HC and later, we want to (and can) let the state be saved as the
// normal part of stopping the activity.
if (r.isPreHoneycomb()) {
r.state = oldState;
}
}
} else {
...
}
}
private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) { // System.out.println("##### [" + System.currentTimeMillis() + "] ActivityThread.performLaunchActivity(" + r + ")"); ActivityInfo aInfo = r.activityInfo; if (r.packageInfo == null) { r.packageInfo = getPackageInfo(aInfo.applicationInfo, r.compatInfo, Context.CONTEXT_INCLUDE_CODE); } ComponentName component = r.intent.getComponent();//该Activity的组件名称,全限定名 if (component == null) { component = r.intent.resolveActivity( mInitialApplication.getPackageManager()); r.intent.setComponent(component); } if (r.activityInfo.targetActivity != null) { component = new ComponentName(r.activityInfo.packageName, r.activityInfo.targetActivity); } Activity activity = null; try { java.lang.ClassLoader cl = r.packageInfo.getClassLoader(); activity = mInstrumentation.newActivity( cl, component.getClassName(), r.intent);//首先通过Instrumentation加载这个Activity所在的类,并创建一个它的实例 StrictMode.incrementExpectedActivityCount(activity.getClass()); r.intent.setExtrasClassLoader(cl); r.intent.prepareToEnterProcess(); if (r.state != null) { r.state.setClassLoader(cl); } } catch (Exception e) { ... } try { Application app = r.packageInfo.makeApplication(false, mInstrumentation); if (localLOGV) Slog.v(TAG, "Performing launch of " + r);... if (activity != null) { Context appContext = createBaseContextForActivity(r, activity);//为该Activity创建ContextImple实例,初始化它的上下文环境 ... 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);//Activity::attach()调用 if (customIntent != null) { activity.mIntent = customIntent; } r.lastNonConfigurationInstances = null; activity.mStartedActivity = false;... activity.mCalled = false; if (r.isPersistable()) { mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState); } else { mInstrumentation.callActivityOnCreate(activity, r.state);//通过Instrumentation调用该Activity的onCreate()函数 } if (!activity.mCalled) { throw new SuperNotCalledException( "Activity " + r.intent.getComponent().toShortString() + " did not call through to super.onCreate()"); } r.activity = activity; r.stopped = true;//将stopped置为TRUE,在调用onStart()之前,Activity::stopped都是true; if (!r.activity.mFinished) {//mFinished只会在Activiy调用了finish()方法之后,才会被置为true activity.performStart();//在执行Activity::onResume()之前会去调用Activity::onStart()方法;调用Activity::onStart()方法 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; if (r.isPersistable()) { mInstrumentation.callActivityOnPostCreate(activity, r.state, r.persistentState); } else { mInstrumentation.callActivityOnPostCreate(activity, r.state); } if (!activity.mCalled) { throw new SuperNotCalledException( "Activity " + r.intent.getComponent().toShortString() + " did not call through to super.onPostCreate()"); } } } r.paused = true; mActivities.put(r.token, r);//token实际是指向一个AMS中的ActivityRecord实例,代表当前启动的Activity;将此次ActivityClientRecord对象保存到Map中 } catch (SuperNotCalledException e) { throw e; } catch (Exception e) { ... } return activity; }
首先获取当前Activity的全限定名,并通过ClassLoader来加载当前的Activity类,并创建该Activity的一个实例;随后会为当前应用创建上下文对象及其他信息,并与该Activity关联起来;这部分内容,后续再分析,此处我们只关注Activity生命周期相关的内容。接着:
- Instrumentation.callActivityOnCreate()函数会根据当前Activity的实例去调用它的onCreate()函数
- Activity.performStart()函数会去调用当前Activity的onStart()函数
- 会将当前当前启动的Activity信息保存到ActivityThread::mActivities集合中
即:
/**
* Perform calling of an activity's {@link Activity#onCreate}
* method. The default implementation simply calls through to that method.
*
* @param activity The activity being created.
* @param icicle The previously frozen state (or null) to pass through to onCreate().
*/
public void Instrumentation::callActivityOnCreate(Activity activity, Bundle icicle) {
prePerformCreate(activity);
activity.performCreate(icicle);
postPerformCreate(activity);
}
final void Activity::performCreate(Bundle icicle) {
restoreHasCurrentPermissionRequest(icicle);
onCreate(icicle);//onCreate()调用
mActivityTransitionState.readState(icicle);
performCreateCommon();
}
//------------------------------------------------
final void Activity::performStart() {
...
mInstrumentation.callActivityOnStart(this);
...
}
/**
* Perform calling of an activity's {@link Activity#onStart}
* method. The default implementation simply calls through to that method.
*
* @param activity The activity being started.
*/
public void Instrumentation::callActivityOnStart(Activity activity) {
activity.onStart();//onStart()调用
}
返回到ActivityThread::handleLaunchActivity(),随后会继续调用ActivityThread::handleResumeActivity()函数:
final void handleResumeActivity(IBinder token,performResumeActivity()函数会导致Activity::onResume()被调用:
boolean clearHide, boolean isForward, boolean reallyResume, int seq, String reason) {
ActivityClientRecord r = mActivities.get(token);//根据之前保存到Map中的信息获取当前Activity的ActivityClientRecord对象
if (!checkAndUpdateLifecycleSeq(seq, r, "resumeActivity")) {
return;
}
...
// TODO Push resumeArgs into the activity for consideration
r = performResumeActivity(token, clearHide, reason);//会借助Instrumentation.callActivityOnResume()函数调用当前Activity::onResume()
if (r != null) {
...
if (!r.onlyLocalRequest) {
r.nextIdle = mNewActivities;
mNewActivities = r;
if (localLOGV) Slog.v(
TAG, "Scheduling idle handler for " + r);
Looper.myQueue().addIdleHandler(new Idler());//使用了Idle(IdleHandler)空闲消息处理器
}
r.onlyLocalRequest = false;
// Tell the activity manager we have resumed.
if (reallyResume) {
try {
ActivityManagerNative.getDefault().activityResumed(token);//通知Activity已经resumed
} catch (RemoteException ex) {
throw ex.rethrowFromSystemServer();
}
}
} else {
...
}
}
public final ActivityClientRecord ActivityThread::performResumeActivity(IBinder token, boolean clearHide, String reason) { ActivityClientRecord r = mActivities.get(token); if (localLOGV) Slog.v(TAG, "Performing resume of " + r + " finished=" + r.activity.mFinished); if (r != null && !r.activity.mFinished) {... try { ... r.activity.performResume(); ... r.paused = false; r.stopped = false; r.state = null; r.persistentState = null; } catch (Exception e) { ... } } return r; }final void Activity::performResume() {... // mResumed is set by the instrumentation mInstrumentation.callActivityOnResume(this);//调用此次启动Activity的onResume()方法 ... } /** * Perform calling of an activity's {@link Activity#onResume} method. The * default implementation simply calls through to that method. * * @param activity The activity being resumed. */ public void Instrumentation::callActivityOnResume(Activity activity) { activity.mResumed = true; activity.onResume();//onResume()被调用 if (mActivityMonitors != null) { synchronized (mSync) { final int N = mActivityMonitors.size(); for (int i=0; i<N; i++) { final ActivityMonitor am = mActivityMonitors.get(i); am.match(activity, activity, activity.getIntent()); } } } }这里所分析的当前Activity的启动过程与我们所知的Activity启动的生命周期调用顺序是吻合的。当前启动的Activity resume之后,还需要通知AMS:
final void ActivityThread::handleResumeActivity(IBinder token, boolean clearHide, boolean isForward, boolean reallyResume, int seq, String reason) {... // Tell the activity manager we have resumed. if (reallyResume) { try { ActivityManagerNative.getDefault().activityResumed(token);//通知Activity已经resumed } catch (RemoteException ex) { throw ex.rethrowFromSystemServer(); } } } else { ... } }即:
@Override
public final void AMS::activityResumed(IBinder token) {
final long origId = Binder.clearCallingIdentity();
synchronized(this) {
ActivityStack stack = ActivityRecord.getStackLocked(token);
if (stack != null) {
stack.activityResumedLocked(token);
}
}
Binder.restoreCallingIdentity(origId);
}
final void ActivityStack::activityResumedLocked(IBinder token) {
final ActivityRecord r = ActivityRecord.forTokenLocked(token);
if (DEBUG_SAVED_STATE) Slog.i(TAG_STATES, "Resumed activity; dropping state of: " + r);
r.icicle = null;
r.haveState = false;
}
至此,在新进程中启动Activity的流程就分析完毕了。我们知道,Activity还可以在已有进程中启动,这部分流程与上面分析的流程有很大的共同性,最大的不同点就是在判断当前Activity的进程是否创建部分,如果此时系统检测到当前Activity需要运行的进程已经存在,则会直接调用ActivityStackSupervisor::realStartActivityLocked()去启动Activity,而不用在为Activity创建完进程后再去启动了。这部分代码可以参考上述内容中的注释。
回顾上述的分析流程,我们要对系统启动Activity所做的一些重要处理格外关注,对其他的一些非核心流程可以适当略过;这样可以让我们更深入理解Activity启动的核心内容。
PS:本篇中只侧重分析了Activity的启动流程及相关生命周期函数的调用时机;其中,AMS中为Activity创建进程及ActivityThread中为Activity初始化上下文环境、配置资源等内容都略过了,这两部分内容会在接下来的文章中做分析、记录。