Activity
管理
Activity
是最复杂的一个组件,它负责UI
的显示以及处理各种输入事件。Activity
提供窗口供应用在其中绘制界面,同时也提供了各种各样的控件方便开发。Activity 官网传送门
另外,
Android
中并没有对外提供启动进程的接口,只是在启动Activity
或Service
时,由系统根据需要来启动进程。
Activity
的生命周期
关于Activity
的生命周期,我们先看下官方图示:
Activity
的生命周期图中隐含了Activity
运行时的三种状态,分别是:
- 激活态:新启动的
Activity
位于屏幕的最前端,可以接受用户输入的状态 - 暂停态:当
Activity
被一个透明或半透明的Activity
覆盖,此时Activity
虽然不能接收用户的输入,但还是可见的 - 停止态:当一个
Activity
完全被另一Activity
覆盖,不能接受用户输入也不可见时
当一个Activity
对象的状态发生变化时,会调用上图中定义的抽象接口来通知应用。相关描述如下:
onCreate()
:当Activity
对象被创建时调用onStart()
:当Activity
在Framework
中的数据结构准备完毕后调用onResume()
:当Activity
来到栈的最前端变成激活态时调用onPause()
:当Activity
从栈的最前端切换到后台时,进入暂停态,并调用该方法onStop()
:当Activity
已经完全不可见时调用onDestroy()
:在销毁Activity
前,系统会先调用该方法
上面的知识在初学Android
时我们就已经知道了,接下来我们要从AMS
的角度看下这几个方法是如何调用的,不过在此之前我们先熟悉下另外的几个相关知识:Intent
、Task
与LaunchMode
Intent
、Task
与LaunchMode
理解Intent
Intent
是所请求执行动作的抽象描述,通常作为参数来使用,用于完成各个组件之间的消息传递。更为详细的姿势可以参考官网描述:官网传送门
Intent
类的相关定义如下:
public class Intent implements Parcelable, Cloneable {
private String mAction;
private Uri mData;
private String mType;
private String mPackage;
private ComponentName mComponent;
private int mFlags;
private ArraySet<String> mCategories;
private Bundle mExtras;
private Rect mSourceBounds;
private Intent mSelector;
private ClipData mClipData;
}
常用字段含义如下:
mAction
是一个字符串,用来指明要执行的操作是什么。- 在
Intent
类中定义了大量的Action
,例如ACTION_VIEW
、ACTION_SEND
等。 - 这些
Action
的作用与具体的功能模块相关,表达要执行的意图
- 在
mData
储存需要传递的数据,类型是URI
。URI
是统一资源标识符(Uniform Resources Identifier
)的简称- 最初用于表示
Web
中的各种资源,如HTML文档、图片、文件等 URL(Uniform Resource Locator)
是URI
的一种
mType
是MIME
格式的字符串,表示数据类型。MIME
是多功能Internet
邮件扩充服务(Multipurpose Internet Mail Extensions
)的缩写- 最早英语电子邮件系统,后来应用到浏览器。格式例如:
text/plain``application/x-gzip
等 - 通常该数据类型不需要指定,如果设置了这个字段,可以加快
Intent
的匹配速度
mComponent
用于指定接收Intent
的目标组件的名称mComponent
的类型是ComponentName
,它包含两个字符串:mPackage
和mClass
,前者用于指定包名,后者用于指定类名Intent
中如果定义了mComponent
,该Intent
将直接发送到指定的组件,不会在通过其他属性组合查找
mFlags
称为标志,在Intent
类中定义了很多flag
的相关常量。主要分为两种- 以
FLAG_ACTIVITY_...
开头的,用来控制Activity
启动的相关参数,如FLAG_ACTIVITY_NEW_TASK
- 以
FLAG_RECEIVER_...
开头的,用来进行广播的参数
- 以
mCategories
一个包含应处理Intent
组件类型的附加信息的字符串。常见的类别有两种:CATEGORY_BROWSABLE
:目标Activity
允许本身通过网络浏览器启动,以显示链接引用的数据CATEGORY_LAUNCHER
:该Activity
是任务的初始Activity
- 可以将任意数量的类别描述放入一个
Intent
中,但大多数Intent
均不需要类别
mExtras
表示所有附加信息的集合。mExtras
数据类型是Bundle
- 可以使用各种
putExtra()
方法添加extra数据
,每种方法均接受两个参数:key
和value
Task
Task
是Activity
的集合。Android把用户一次相关操作中使用的Activity
按照先后顺序保存在Task
中,这样当按back键
时就能按照相反的顺序回退。
Task
像一个栈,以后进先出的方式管理着Activity
。系统运行时内存中会存在着多个Task
,当我们按recent
键时,会弹出一个选择列表,这个列表就是系统中存在的Task
的集合,选择一个Task
将把它所包含的Activity
作为一个整体带到前台。Task
中的Activity
的顺序通常是不能改变的,只能通过出栈入栈的方式来增加或移除。
AMS
中使用ActivityStack
来管理Task
,它管理的Task
都存放在成员变量mTaskHistory
中,定义如下:
class ActivityStack{
private final ArrayList<TaskRecord> mTaskHistory = new ArrayList<>();
}
mTaskHistory
是一个列表,储存的是TaskRecord
对象。TaskRecord
对象表示一个Task
,它的成员变量mActivities
也是一个列表,储存了该Task
中所有的ActivityRecord
对象。mActivities
的定义如下:
class TaskRecord{
final ArrayList<ActivityRecord> mActivities;
}
那么,如何才能开始一个新的Task
呢?
Intent
中定义了一个标志FLAG_ACTIVITY_NEW_TASK
,在startActivity()
的Intent
参数中加入该标志就能开启一个新的Task
- 但是如果系统中已经有相同
affinity
的Task
存在,并不会再启动一个Task
,而是将旧的Task
带到前台
那么,affinity
在哪里定义的呢?
affinity
的意思是亲和度,是通过<activity>
标签的android:taskAffinity
属性来定义的- 当使用标志
FLAG_ACTIVITY_NEW_TASK
启动一个Activity
时,这个Activity
的taskAffinity
属性中的字符串就会成为Task
的affinity
- 以后加入这个
Task
的Activity
,即使它们的taskAffinity
属性定义了一个不同的字符串,也不会改变Task
已有的affinity
- 如果
<activity>
标签中没有指定android:taskAffinity
属性,这个Activity
会继承<application>
标签的android:taskAffinity
属性 - 如果
<application>
标签的android:taskAffinity
属性也没有定义,将会使用应用包名作为缺省值- 正因为如此,如果在应用中启动本应用的另一个
Activity
,即使使用了FLAG_ACTIVITY_NEW_TASK
标志也不一定会启动一个新的Task
- 除非这个
Activity
定义了不同的taskAffinity
属性
- 正因为如此,如果在应用中启动本应用的另一个
LaunchMode
Activity
的启动模式隐含的是Activity
对象的复用问题,关于启动模式官网的介绍也很详细:官方传送门
当启动一个Activity
时,如果系统的后台Task
中已经有一个该Activity
的实例存在了,系统是创建一个新的Activity
还是将已经存在的Activity
切换到前台呢?
答案是都有可能,有多种因素可以影响结果。包括Activity
的属性值以及Intent
中指定的标志
我们先看下Activity
的属性launchMode
会有哪些影响:
standard
模式:默认。standard
模式下的Activity
每次启动时都会创建该Activity
的实例对象- 同一个
Task
中可以同时存在该Activity
的多个实例 - 一个
Activity
的多个实例可以出现在多个Task
栈中
singleTop
模式- 如果目标
Task
的顶部已存在该Activity
实例,则系统会通过调用该实例的onNewIntent()
方法向其传送Intent
,而非创建新的Activity
实例。 - 如果不在栈顶,这
standard
模式一样创建新的实例对象
- 如果目标
singleTask
模式- 设置
singleTask
模式的Activity
具有系统唯一性,只能在系统中创建该Activity
的一个实例对象 - 启动设置为
singleTask
模式的Activity
时,如果系统中已经存在该Activity
的实例对象,则将其所在的Task
中排在它前面的Activity
都弹出栈,将该Activity
带到栈顶,并调用其onNewIntent()
方法传递新的Intent
对象 - 如果系统中不存在该
Activity
的实例对象,则会创建一个该Activity
的实例对象- 如果该
Activity
的taskAffinity
属性值和当前Task
的affinity
值相同,它会加入当前的Task
中 - 否则,即使启动该
Activity
的Intent
中没有指定FLAG_ACTIVITY_NEW_TASK
标志,也会启动新的Task
,并将Activity
至于其中
- 如果该
- 设置
singleInstance
模式- 设置为
singleInstance
模式的Activity同样具有系统唯一性,系统中只有该Activity的一个实例对象 - 同时系统不会将任何其他
Activity
启动到包含该Activity
实例的Task
中 - 该
Activity
始终是其Task
中的唯一Activity
- 设置为
通常情况下,一个Activity
创建出来后,会停留在某个Task
中,直到它被销毁
- 但是,如果
Activity
的allowTaskReparenting
属性设置为true
,该Activity
可以在不同的Task
之间转移 - 不过,这个属性只有在启动
Activity
的Intent
中设置了FLAG_ACTIVITY_RESET_TASK_IF_NEEDED
标志时才起作用
除了上面介绍的内容,Activity
和Task
的工作逻辑大家可以参考官网:任务和返回堆栈
比如,下面部分提到的技巧就很重要(摘抄自官网):
只有当 Activity 具有 ACTION_MAIN 和 CATEGORY_LAUNCHER 过滤器时,才应使用 “singleTask” 和 “singleInstance” 这两种启动模式,它们会将 Activity 标记为始终启动任务。比如,可以想象一下,如果缺少该过滤器会发生什么情况:intent 会启动 “singleTask” Activity,随之启动新任务,用户花了一些时间在该任务上。然后,用户按主屏幕按钮。此时,该任务会转到后台,不再可见。现在,用户无法返回到该任务,因为它未显示在应用启动器中。
了解ClientTransactionHandler
的作用
ClientTransactionHandler
是在Android 9.0
上出现的,用来串联起AMS
和Activity
的整个生命周期管理的类,很重要
我们已经知道应用的入口是ActivityThread
类的main()
函数,仔细看下类结构的话会发现要ActivityThread
继承了一个特殊的类。定义如下
public final class ActivityThread extends ClientTransactionHandler {
...
}
可以看到ActivityThread
继承了ClientTransactionHandler
类。这个类是在Android 9.0
加入的,关键定义如下:
public abstract class ClientTransactionHandler {
void scheduleTransaction(ClientTransaction transaction) {
transaction.preExecute(this);
sendMessage(ActivityThread.H.EXECUTE_TRANSACTION, transaction);
}
......
public abstract void handleDestroyActivity(...);
public abstract void handlePauseActivity(...);
public abstract void handleResumeActivity(...);
public abstract void handleStopActivity(...);
......
public abstract Activity handleLaunchActivity(...);
public abstract void handleStartActivity(...);
......
public abstract void handleNewIntent(...);
......
}
类中定义了和声明周期有关的方法,机智的我们可以猜到,AMS
后面生命周期的回调控制应该就是通过它来实现的,相关类继承关系如下:
可以Android
把Activity
相关的生命周期要做的事情抽象了出来,在上面定义的类中,真正业务实现包括:
LaunchActivityItem
就是要执行launch activity
任务resume activity
则是通过ResumeActivityItem
实现pause activity
则是通过PauseActivityItem
实现stop activity
则是通过StopActivityItem
实现destroy activity
则是通过DestoryActivityItem
实现
ClientTransaction
的调用逻辑
我们看下整个调用流程:
在ActivityThread
中的ApplicationThread
类有一个scheduleTransaction()
方法,
ApplicationThread
类是一个Binder
服务类,AMS
会作为client
调用这个服务类,当然也就可以调用它的scheduleTransaction()
方法
scheduleTransaction()
方法内容如下:
@Override
public void scheduleTransaction(ClientTransaction transaction) throws RemoteException {
ActivityThread.this.scheduleTransaction(transaction);
}
调用的是ActivityThread
的scheduleTransaction()
方法,也就是ClientTransactionHandler
类的scheduleTransaction()
方法,方法如下:
void scheduleTransaction(ClientTransaction transaction) {
transaction.preExecute(this);
sendMessage(ActivityThread.H.EXECUTE_TRANSACTION, transaction);
}
发送了一个EXECUTE_TRANSACTION
消息给ActivityThread
的Handler
实现类H
,消息处理如下:
case EXECUTE_TRANSACTION:
final ClientTransaction transaction = (ClientTransaction) msg.obj;
mTransactionExecutor.execute(transaction);
if (isSystem()) {
transaction.recycle();
}
break;
消息处理中使用了mTransactionExecutor.execute()
,不出意外,执行逻辑肯定在TransactionExecutor
中了,我们看下:
public void execute(ClientTransaction transaction) {
final IBinder token = transaction.getActivityToken();
executeCallbacks(transaction);
executeLifecycleState(transaction);
mPendingActions.clear();
}
public void executeCallbacks(ClientTransaction transaction) {
final List<ClientTransactionItem> callbacks = transaction.getCallbacks();
if (callbacks == null) {
return;
}
......
final int size = callbacks.size();
for (int i = 0; i < size; ++i) {
......
item.execute(mTransactionHandler, token, mPendingActions);
item.postExecute(mTransactionHandler, token, mPendingActions);
......
}
}
private void executeLifecycleState(ClientTransaction transaction) {
final ActivityLifecycleItem lifecycleItem = transaction.getLifecycleStateRequest();
if (lifecycleItem == null) {
// No lifecycle request, return early.
return;
}
......
// 很重要的一个方法
cycleToPath(r, lifecycleItem.getTargetState(), true /* excludeLastState */);
// Execute the final transition with proper parameters.
lifecycleItem.execute(mTransactionHandler, token, mPendingActions);
lifecycleItem.postExecute(mTransactionHandler, token, mPendingActions);
}
可以看到,最后分别在executeCallbacks()
和executeLifecycleState()
两个方中执行了item.execute()
和lifecycleItem.execute()
两个方法
executeCallbacks()
和executeLifecycleState()
目的分别是干什么呢?结合类关系图我们可以这样推断:
executeCallbacks()
遍历执行的是ClientTransaction
类中List<ClientTransactionItem> mActivityCallbacks
集合中的元素ClientTransactionItem
类的直接子类实现只有LaunchActivityItem
类- 也就是说
executeCallbacks()
主要执行的是launch activity
的通知操作
executeLifecycleState()
执行的是ClientTransaction
类中的ActivityLifecycleItem mLifecycleStateRequest
mLifecycleStateRequest
被称为final state
- 从继承关系上可以看到,
resume activity
、pasue activity
、stop activity
、destory activity
都在这里
了解完调用流程会发现,实现类中并没有StartActivityItem
,为什么呢?那怎么调用onStart()
函数呢?
核心就在cycleToPath()
函数身上
TransactionExecutor.cycleToPath()
针对
Activity
的生命周期,Android
并没有定义出所有的*ActivityItem
类,例如StartActivityItem
就并不存在,那么怎么去执行这个start
阶段的函数呢?
请留意类图中ActivityLifecycleItem
有关生命周期的常量定义,Android
在这里通过cycleToPath()
采用了一种比较取巧的操作,核心逻辑就是:
- 指定一个
Activity
的final state
- 根据
Activity
的当前状态去计算过程中需要的状态,并保存到集合中 - 最后按顺序执行集合中的状态
以文章后面的realStartActivityLocked()
方法为例
- 将
LaunchActivityItem
类型的对象添加到callback
中TransactionExecutor
会先执行LaunchActivityItem
类- 执行完后
Activity
进入到ON_CREATE
状态
- 方法中指定了
final state
为ResumeActivityItem
TransactionExecutor
通过cycleToPath()
计算当前状态与final state
的差异- 当前状态为
ON_CREATE
状态,final state
为ON_RESUME
TransactionExecutor
通过帮助类的getLifecyclePath
方法将两者之间缺失的状态整理到集合中- 然后调用
performLifecycleSequence()
循环处理
performLifecycleSequence()
方法如下:
private void performLifecycleSequence(ActivityClientRecord r, IntArray path) {
final int size = path.size();
for (int i = 0, state; i < size; i++) {
state = path.get(i);
switch (state) {
case ON_CREATE:
mTransactionHandler.handleLaunchActivity(...);
break;
case ON_START:
mTransactionHandler.handleStartActivity(r, mPendingActions);
break;
case ON_RESUME:
mTransactionHandler.handleResumeActivity(...);
break;
case ON_PAUSE:
mTransactionHandler.handlePauseActivity(...);
break;
case ON_STOP:
mTransactionHandler.handleStopActivity(...);
break;
case ON_DESTROY:
mTransactionHandler.handleDestroyActivity(...);
break;
case ON_RESTART:
mTransactionHandler.performRestartActivity(...);
break;
default:
throw new IllegalArgumentException("Unexpected lifecycle state: " + state);
}
}
}
PauseActivityItem
的调用分析
以PauseActivityItem
类为例,我们看看具体的执行逻辑:
public class PauseActivityItem extends ActivityLifecycleItem {
......
@Override
public void execute(ClientTransactionHandler client, IBinder token,
PendingTransactionActions pendingActions) {
......
client.handlePauseActivity(token, mFinished, mUserLeaving, mConfigChanges, pendingActions,
"PAUSE_ACTIVITY_ITEM");
......
}
}
执行的是ClientTransactionHandler
抽象类,其实也就是ActivityThread
类的handlePauseActivity()
方法。
handlePauseActivity()
方法调用了ActivityThread
类的performPauseActivity()
方法,最后调用到的是performPauseActivityIfNeeded()
方法,代码如下:
private void performPauseActivityIfNeeded(ActivityClientRecord r, String reason) {
......
mInstrumentation.callActivityOnPause(r.activity);
......
}
执行的是Instrumentation
类的callActivityOnPause()
方法,内容如下:
public void callActivityOnPause(Activity activity) {
activity.performPause();
}
很简洁,继续查看:
public class Activity{
final void performPause() {
mDoReportFullyDrawn = false;
mFragments.dispatchPause();
mCalled = false;
onPause();
writeEventLog(LOG_AM_ON_PAUSE_CALLED, "performPause");
mResumed = false;
......
}
}
有木有!有木有!onPause();
终于调用到了。。。。。。
我们已经从应用端找到了调用的流程,但是,对于AMS
来说它是怎么触发的呢?
接下来,我们分析下Activity
的启动,在Activity
启动的过程我们就可以找到AMS
触发声明周期的例子
启动Activity
研究
Activity
生命周期的调用细节,我们还是得从最熟悉的地方入手,也就是常用的Activity
对象的startActivity (Intent intent)
方法
Activty.startActivty()
跟踪startActivity (Intent intent)
方法,发现调用关系如下:
class Activity{
public void startActivity(Intent intent, @Nullable Bundle options) {
if (options != null) {
startActivityForResult(intent, -1, options);
} else {
startActivityForResult(intent, -1);
}
}
public void startActivityForResult(...) {
......
Instrumentation.ActivityResult ar =
mInstrumentation.execStartActivity(
this, mMainThread.getApplicationThread(), mToken, who,
intent, requestCode, options);
......
}
}
class Instrumentation{
public ActivityResult execStartActivity(...) {
IApplicationThread whoThread = (IApplicationThread) contextThread;
......
try {
intent.migrateExtraStreamToClipData();
intent.prepareToLeaveProcess(who);
int result = ActivityManager.getService()
.startActivity(...);
checkStartActivityResult(result, intent);
} catch (RemoteException e) {
throw new RuntimeException("Failure from system", e);
}
return null;
}
}
class ActivityManagerService{
public final int startActivity(...) {
return startActivityAsUser(...);
}
public final int startActivityAsUser(...) {
......
return mActivityStartController.obtainStarter(intent, "startActivityAsUser")
...
.execute();
}
}
我们看到最后是调用的是AMS
的startActivityAsUser
方法。跟踪startActivityAsUser
方法的调用过程就会发现最后执行的是ActivityStarter
类的execute()
方法来执行Activity
的启动,相关代码如下:
class ActivityStater{
int execute() {
try {
if (mRequest.mayWait) {
return startActivityMayWait(...);
} else {
return startActivity(...);
}
} finally {
onExecutionComplete();
}
}
}
我们看到execute()
有两个启动Activity
的方法,接下来我们以startActivityMayWait()
方法继续分析,因为最后也会走到startActivity()
中。
ActivityStarter.startActivityMayWait()
简要代码如下:
private int startActivityMayWait(...) {
......
// 获取要启动的 Activity 的信息
ActivityInfo aInfo = mSupervisor.resolveActivity(intent, rInfo, startFlags, profilerInfo);
synchronized (mService) {
......
int res = startActivity(caller, ...);
......
if (outResult != null) { // 需要返回结果
outResult.result = res;
final ActivityRecord r = outRecord[0];
switch(res) {
case START_SUCCESS: {
// 添加到特定集合中
mSupervisor.mWaitingActivityLaunched.add(outResult);
do {
try {
// 等待应用进程中的 Activity 启动完成
mService.wait();
} catch (InterruptedException e) {
}
} while (outResult.result != START_TASK_TO_FRONT
&& !outResult.timeout && outResult.who == null);
......
break;
}
......
}
}
return res;
}
}
startActivityMayWait()
方法的流程如下:
- 首先调用
resolveActivity()
方法来获取要启动的Activity
的信息 - 得到
Activity
的信息后,继续调用startActivity()
方法来继续启动Activity
- 如果启动
Activity
的应用需要获取返回结果,则调用mService
对象的wait()
方法挂起线程等待启动的结果
接下来就是调用ActivityStarter
的startActivity()
方法的代码,我们看下部分细节:
private int startActivity(IApplicationThread caller, ...) {
int err = ActivityManager.START_SUCCESS;
......
if (caller != null) {
// 获取启动Activity的进程的信息
callerApp = mService.getRecordForAppLocked(caller);
if (callerApp != null) {
callingPid = callerApp.pid;
callingUid = callerApp.info.uid;
} else {
err = ActivityManager.START_PERMISSION_DENIED;
}
}
final int userId = aInfo != null && aInfo.applicationInfo != null
? UserHandle.getUserId(aInfo.applicationInfo.uid) : 0;
......// 省略很多错误检查
// 检查调用者的相关权限
boolean abort = !mSupervisor.checkStartAnyActivityPermission(...);
// 检查 Intent 防火墙是否屏蔽了该 Intent
abort |= !mService.mIntentFirewall.checkStartActivity(...);
......
if (mService.mController != null) {
try {
// 将 Activity 启动的消息通知监听系统Activity变动的接口 IActivityControler
Intent watchIntent = intent.cloneFilter();
abort |= !mService.mController.activityStarting(watchIntent,
aInfo.applicationInfo.packageName);
} catch (RemoteException e) {
mService.mController = null;
}
}
......
if (abort) {
......// 如果 abort 为true,直接退出
return START_ABORTED;
}
......
// 创建 ActivityRecord 对象
ActivityRecord r = new ActivityRecord(...);
if (outActivity != null) {
outActivity[0] = r;
}
......
// 当前用户正在操作的 ActivityStack
final ActivityStack stack = mSupervisor.mFocusedStack;
// 针对经常切换进程的情况,检查调用者是否有权限进行进程切换
if (voiceSession == null && (stack.getResumedActivity() == null
|| stack.getResumedActivity().info.applicationInfo.uid != realCallingUid)) {
if (!mService.checkAppSwitchAllowedLocked(callingPid, callingUid,
realCallingPid, realCallingUid, "Activity start")) {
// 对于不能切换进程的情况,把 Activity 信息放入 mPendingActivityLaunches 列表中
mController.addPendingActivityLaunch(new PendingActivityLaunch(r,
sourceRecord, startFlags, stack, callerApp));
ActivityOptions.abort(checkedOptions);
return ActivityManager.START_SWITCHES_CANCELED;
}
}
if (mService.mDidAppSwitch) {
mService.mAppSwitchesAllowedTime = 0;
} else {
mService.mDidAppSwitch = true;// 打开开关,允许进程间切换
}
// 启动挂起等待的 Activity,其实就是逐个启动 mPendingActivityLaunches 列表中的 Activity。
// 最后也是调用了 startActivity
// 个人理解,大多数情况下 mPendingActivityLaunches 列表应该是空的吧
mController.doPendingActivityLaunches(false);
......
// 调用startActivity另一个重载方法,第一个参数为 ActivityRecord
return startActivity(r, ...);
}
private int startActivity(final ActivityRecord r, ...) {
int result = START_CANCELED;
......
result = startActivityUnchecked(r, ...);
......
return result;
}
这里其实不用记录太多细节,重要的是了解启动Activity
方法的调用流程,这里最后调用的是startActivityUnchecked()
方法,我们来继续看下。
ActivityStarter.startActivityUnchecked()
方法如下:
private int startActivityUnchecked(final ActivityRecord r, ...) {
// 初始化环境和lunchModeFlags
setInitialState(r, options, inTask, doResume, startFlags, sourceRecord, voiceSession,
voiceInteractor);
computeLaunchingTaskFlags();
computeSourceStack();
mIntent.setFlags(mLaunchFlags);
// 判断 Activity 是否需要插入新的 Task,以下情况 reusedActivity 不为空
// 1.设置了FLAG_ACTIVITY_NEW_TASK:
// 2.启动模式为singleTask:
// 3.启动模式为singleInstance
ActivityRecord reusedActivity = getReusableIntentActivity();
......
final boolean dontStart = top != null && mStartActivity.resultTo == null
&& top.realActivity.equals(mStartActivity.realActivity)
&& top.userId == mStartActivity.userId
&& top.app != null && top.app.thread != null
&& ((mLaunchFlags & FLAG_ACTIVITY_SINGLE_TOP) != 0
|| isLaunchModeOneOf(LAUNCH_SINGLE_TOP, LAUNCH_SINGLE_TASK));
if (dontStart) { // 不需要启动的情况
// For paranoia, make sure we have correctly resumed the top activity.
topStack.mLastPausedActivity = null;
if (mDoResume) {
mSupervisor.resumeFocusedStackTopActivityLocked();
}
......
deliverNewIntent(top);
......
return START_DELIVERED_TO_TOP;
}
boolean newTask = false;
final TaskRecord taskToAffiliate = (mLaunchTaskBehind && mSourceRecord != null)
? mSourceRecord.getTask() : null;
// 判断当前 Activity 是否需要一个新的 Task
int result = START_SUCCESS;
if (mStartActivity.resultTo == null && mInTask == null && !mAddingToTask
&& (mLaunchFlags & FLAG_ACTIVITY_NEW_TASK) != 0) {
newTask = true;
result = setTaskFromReuseOrCreateNewTask(taskToAffiliate, topStack);
} else if (mSourceRecord != null) {
result = setTaskFromSourceRecord();
} else if (mInTask != null) {
result = setTaskFromInTask();
} else {
// This not being started from an existing activity, and not part of a new task...
// just put it in the top task, though these days this case should never happen.
setTaskToCurrentTopOrCreateNewTask();
}
......
// 启动 Activity
// startActivityLocked 这里主要是将 ActivityRecord 对象加入到 Task 的顶部
// 同时将 Task 添加到 mTaskHistory 的顶部
mTargetStack.startActivityLocked(mStartActivity, topFocused, newTask, mKeepCurTransition,
mOptions);
// 利用 WindowManager 使 Activity 可见
if (mDoResume) {
final ActivityRecord topTaskActivity = mStartActivity.getTask().topRunningActivityLocked();
if (!mTargetStack.isFocusable() || (topTaskActivity != null && topTaskActivity.mTaskOverlay && mStartActivity != topTaskActivity)) {
mTargetStack.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
mService.mWindowManager.executeAppTransition(); // 此处应该是执行应用间的切换动画
} else {
.......
mSupervisor.resumeFocusedStackTopActivityLocked(mTargetStack, mStartActivity,
mOptions);
}
} else if (mStartActivity != null) {
mSupervisor.mRecentTasks.add(mStartActivity.getTask());
}
......
return START_SUCCESS;
}
startActivityUnchecked()
方法主要是通过Intent
的标志和Activity
的属性来确定Activity
的Task
,然后将其调整至栈顶,细节我们先略过,需要重点关注的方法是mSupervisor.resumeFocusedStackTopActivityLocked()
方法的调用。跟踪调用就会发现,最后执行的是ActivityStack
类的resumeTopActivityInnerLocked()
方法
ActivityStack.resumeTopActivityInnerLocked()
我们前面已经知道
resumeFocusedStackTopActivityLocked()
方法最终会调用ActivityStack
类的resumeTopActivityInnerLocked()
方法。
resumeTopActivityInnerLocked()
方法主要的作用是将位于栈顶的Activity
显示出来,不过在此之前,旧的Activity
(变量mResumedActivity
引用的就是)还显示在屏幕上。方法内容如下:
private boolean resumeTopActivityInnerLocked(ActivityRecord prev, ActivityOptions options) {
if (!mService.mBooting && !mService.mBooted) {
// Not ready yet!
return false;
}
// 从要 mTaskHistory 中查找要启动的 Activity
// 这里这样做应该是因为前面已经将 Activity 放入堆栈中了
final ActivityRecord next = topRunningActivityLocked(true /* focusableOnly */);
final boolean hasRunningActivity = next != null;
......
if (!hasRunningActivity) {
// There are no activities left in the stack, let's look somewhere else.
return resumeTopActivityInNextFocusableStack(prev, options, "noMoreActivities");
}
next.delayedResume = false;
// 如果当前显示的 Activity 就是要启动的 Activity,直接返回
if (mResumedActivity == next && next.isState(RESUMED)
&& mStackSupervisor.allResumedActivitiesComplete()) {
executeAppTransition(options);
return false;
}
// 如果正在休眠或者关机,直接返回
if (shouldSleepOrShutDownActivities()
&& mLastPausedActivity == next
&& mStackSupervisor.allPausedActivitiesComplete()) {
executeAppTransition(options);
return false;
}
// user 状态检查
if (!mService.mUserController.hasStartedUserState(next.userId)) {
return false;
}
// 将要启动的 Activity 从相关队列中移除
mStackSupervisor.mStoppingActivities.remove(next);
mStackSupervisor.mGoingToSleepActivities.remove(next);
next.sleeping = false;
mStackSupervisor.mActivitiesWaitingForVisibleActivity.remove(next);
// 检查是否有正在 Pause 的 Activity
if (!mStackSupervisor.allPausedActivitiesComplete()) {
return false;
}
// 设置要启动的 applicationInfo
mStackSupervisor.setLaunchSource(next.info.applicationInfo.uid);
......
boolean pausing = mStackSupervisor.pauseBackStacks(userLeaving, next, false);
if (mResumedActivity != null) {
// 暂停当前 Activity
// startPausingLocked() 中便会触发 旧Activity 的 onPause() 操作
pausing |= startPausingLocked(userLeaving, false, next, false);
}
......
ActivityStack lastStack = mStackSupervisor.getLastStack();
if (next.app != null && next.app.thread != null) {
// 如果 Activity 所在的应用已经存在,只需要把 Activity 显示出来
......
synchronized(mWindowManager.getWindowManagerLock()) {
// This activity is now becoming visible.
if (!next.visible || next.stopped || lastActivityTranslucent) {
next.setVisibility(true);
}
......
try {
final ClientTransaction transaction = ClientTransaction.obtain(next.app.thread,
next.appToken);
......
// 如果当前 Activity 还有等待返回的结果,添加 ActivityResultItem,
// 其中会执行 onActivityResult 回调
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);
transaction.addCallback(ActivityResultItem.obtain(a));
}
}
// 添加 NewIntentItem,其中会执行 onNewIntent
if (next.newIntents != null) {
transaction.addCallback(NewIntentItem.obtain(next.newIntents,
false /* andPause */));
}
transaction.setLifecycleStateRequest(
ResumeActivityItem.obtain(next.app.repProcState,
mService.isNextTransitionForward()));
mService.getLifecycleManager().scheduleTransaction(transaction);
......
} catch (Exception e) {
// Whoops, need to restart this activity!
......
mStackSupervisor.startSpecificActivityLocked(next, true, false);
if (DEBUG_STACK) mStackSupervisor.validateTopActivitiesLocked();
return true;
}
}
......
} else {
// Whoops, need to restart this activity!
......
mStackSupervisor.startSpecificActivityLocked(next, true, true);
}
......
return true;
}
resumeTopActivityInnerLocked()
代码比较长作了精简,核心逻辑如下:
- 先是通过
startPausingLocked()
暂停旧的Activity
,startPausingLocked()
方法如下:final boolean startPausingLocked(boolean userLeaving, boolean uiSleeping, ActivityRecord resuming, boolean pauseImmediately) { ...... mService.getLifecycleManager().scheduleTransaction(prev.app.thread, prev.appToken, PauseActivityItem.obtain(prev.finishing, userLeaving, prev.configChangeFlags, pauseImmediately)); ...... }
- 这里四不四就和前面的
ClientTransaction
呼应上了,嘿嘿
- 这里四不四就和前面的
- 如果
Activity
所在的应用已经启动,对Activity
进行显示处理,创建ResumeActivityItem
进行生命周期通知- 最终会导致
Activity
对象的onResume()
方法的执行
- 最终会导致
- 如果应用还没有启动,则调用
startSpecificActivityLocked()
方法继续处理,方法如下:void startSpecificActivityLocked(ActivityRecord r, boolean andResume, boolean checkConfig) { // 获取 Activity 对应的进程 ProcessRecord app = mService.getProcessRecordLocked(r.processName, r.info.applicationInfo.uid, true); if (app != null && app.thread != null) { try { ...... // 如果应用进程已经存在的情况,执行 realStartActivityLocked() // andResume = true realStartActivityLocked(r, app, andResume, checkConfig); // 然后返回 return; } catch (RemoteException e) { } } // Activity 对应的进程为空,通过 AMS 的 startProcessLocked() 创建新的进程 mService.startProcessLocked(r.processName, r.info.applicationInfo, true, 0, "activity", r.intent.getComponent(), false, false, true); }
- 核心方法是
realStartActivityLocked()
,就算是重新启动进程的情况,最后执行的也是realStartActivityLocked()
- 核心方法是
ActivityStackSupervisor.realStartActivityLocked()
对于realStartActivityLocked()
方法,我们简单看下和生命周期相关的内容:
final boolean realStartActivityLocked(ActivityRecord r, ProcessRecord app,
boolean andResume, boolean checkConfig) throws RemoteException {
......
// Create activity launch transaction.
final ClientTransaction clientTransaction = ClientTransaction.obtain(app.thread,
r.appToken);
// 添加 LaunchActivityItem,这个会触发 onCreate 方法
clientTransaction.addCallback(LaunchActivityItem.obtain(new Intent(r.intent), ...);
// 设置最终状态,resume 还是 pause
final ActivityLifecycleItem lifecycleItem;
// 根据前面的调用参数可以确定,andResume = true
if (andResume) {
// 设置最终状态为 ON_RESUME
lifecycleItem = ResumeActivityItem.obtain(mService.isNextTransitionForward());
} else {
lifecycleItem = PauseActivityItem.obtain();
}
clientTransaction.setLifecycleStateRequest(lifecycleItem);
// Schedule transaction.
mService.getLifecycleManager().scheduleTransaction(clientTransaction);
......
return true;
}
方法中添加了LaunchActivityItem
和ResumeActivityItem
类的对象,并调用了scheduleTransaction()
方法。
LaunchActivityItem
属于比较复杂的调用逻辑
以LaunchActivityItem
类为例,我们来看跟踪下调用关系:
public class LaunchActivityItem extends ClientTransactionItem {
@Override
public void execute(ClientTransactionHandler client, IBinder token,
PendingTransactionActions pendingActions) {
......
client.handleLaunchActivity(r, pendingActions, null /* customIntent */);
......
}
}
调用的是ActivityThread
中handleLaunchActivity()
的方法:
public Activity handleLaunchActivity(ActivityClientRecord r,
PendingTransactionActions pendingActions, Intent customIntent) {
......
final Activity a = performLaunchActivity(r, customIntent);
......
return a;
}
private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
......
Activity activity = null;
try {
java.lang.ClassLoader cl = appContext.getClassLoader();
activity = mInstrumentation.newActivity(cl, component.getClassName(), r.intent);
......
} catch (Exception e) {
...
}
try {
......
if (activity != null) {
......
activity.mCalled = false;
if (r.isPersistable()) {
mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);
} else {
mInstrumentation.callActivityOnCreate(activity, r.state);
}
if (!activity.mCalled) {
throw new SuperNotCalledException(
"Activity " + r.intent.getComponent().toShortString() +
" did not call through to super.onCreate()");
}
r.activity = activity;
}
// 将状态设置为 ON_CREATE
r.setState(ON_CREATE);
} catch (SuperNotCalledException e) {
throw e;
} catch (Exception e) {
......
}
return activity;
}
调用的是Instrumentation.callActivityOnCreate()
方法,内容如下:
public void callActivityOnCreate(Activity activity, Bundle icicle) {
prePerformCreate(activity);
activity.performCreate(icicle);
postPerformCreate(activity);
}
最后通过是调用的Activity.performCreate()
方法:
final void performCreate(Bundle icicle, PersistableBundle persistentState) {
......
if (persistentState != null) {
onCreate(icicle, persistentState);
} else {
onCreate(icicle);
}
......
}
到这里,LaunchActivityItem
的逻辑就结束了,也执行完了onCreate()
回调,状态设置为了ON_CREATE
。
但是由于realStartActivityLocked()
中设置的最终状态为ON_RESUME
,当前Activity
的状态不是最终状态,所以TransactionExecutor
还会继续执行。