赞
踩
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"?>
- <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>

我们以此Apk为例,简要分析从Launcher启动该Apk、并最终将HomeActivity显示给用户的流程。
当我们点击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
- category: android.intent.category.LAUNCHER //表明需要在Launcher上显示图标
- component:com.coder.lovebugs.HomeActivity //需要启动的Activity组件名称
由于options参数为null,则继续分析:
- 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)了,为了后续流程的分析,我们先明确下此处各个传参的基本含义:
接着进入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)
- 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;
- }
- ...
- }

这里直接调用Server端实现AMS中的同签名的startActivity()函数,处理这次请求调用;这样我们的Activity启动工作就正式进入了AMS。
AMS::startActivity()函数实现如下:
- @Override
- 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());//层次调用
- }
层次调用AMS::startActivityAsUser():
- @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,
- 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组件启动流程
-
- ...
- }
- }

首先通过resolveIntent()/resolveActivity()调用,从PackageManagerService中获取到当前需要启动的Activity的一些信息,保存到aInfo/rInfo中,然后继续调用startActivityLocked()函数处理后续流程:
- 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 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;
- }

最终的处理会在ActivityStack::resumeTopActivityInnerLocked()之中:
- 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有几个成员变量控制了这个过程,它们的含义大致如下:
首先调用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()函数的处理:
- /**
- * 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;
- }
- }

首先会重置ActivityStack中一些变量的状态,mResumedActivity置为null,mPausingActivity/mLastPausedActivity则指向当前正在进入pause状态的组件,即Launcher。紧接着进入Launcher组件的主线程中处理Activity的pause过程。
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,
- 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) {
- ...
- }
- }
- }

最终处理pause的过程是向ActivityThread::H发送了一个PAUSE消息,直接看这部分的处理:
- 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) {
- 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状态
- }

通过Instrumentation调用该Activity的onPause()函数:
- 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,
- 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;
- }
- }

传入的参数是代表Launcher组件的一个IBinder对象,AMS可以根据该实例找到对应的ActivityRecord实例;直接分析AMS::activityPaused()函数:
- @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()函数:
- //应用进程的入口函数
- 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");
- }

这里主要创建了ActivityThread实例并调用了attach()函数,紧接着并启动了消息循环。ActivityThread的构造函数并没有什么重要的工作,我们主要看attach()函数的实现:
- private void ActivityThrad::attach(boolean system) {
- 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 {
- ...
- }
- ...
- }

调用了AMS::attachApplication()函数,告知AMS当前为应用新创建的进程已经准备好了,可以开始启动Activity了;mAppThread的定义是:
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,
- 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;
- }

从代码可以得知,一个ActivityThread对象,即一个应用的主线程中只会存在一个LoadedApk、Instrumentation、Application等实例,它们在一个应用进程中被所有Activity共用。
接着调用ActivityStackSupervisor.attachApplicationLocked()在该进程启动当前的目标Activity:
- boolean ActivityStackSupervisor::attachApplicationLocked(ProcessRecord app) throws RemoteException {
- 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;
- }

首先得到当前任务栈顶端的Activity,它既是我们当前需要启动的目标。因为该Activity尚未启动,所以会去调用realStartActivityLocked()去启动:
- 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) {
- ...
- 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 {
- ...
- }
- }

分别会调用performLaunchActivity()和handleResumeActivity()来完成当前启动Activity的初始化及生命周期调用工作;首先看performLaunchActivity():
- 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生命周期相关的内容。接着:
即:
- /**
- * 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,
- 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 {
- ...
- }
- }

performResumeActivity()函数会导致Activity::onResume()被调用:
- 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初始化上下文环境、配置资源等内容都略过了,这两部分内容会在接下来的文章中做分析、记录。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。