从Android-28开始,AMS向客户端进程有关Activity部分的通信封装成一个统一的事务来操作,不再直接使用客户端进程ApplicationThread的本地代理了。
版本变化
以startPausingLocked()为例(通知客户端进程执行Activity暂停操作),看2个版本的变化。
Android-271
2
3
4
5
6
7
8
9
10
11
12
13#ActivityStack
final boolean startPausingLocked(boolean userLeaving, boolean uiSleeping,
ActivityRecord resuming, boolean pauseImmediately) {
...
if (prev.app != null && prev.app.thread != null) {
try {
prev.app.thread.schedulePauseActivity(prev.appToken, prev.finishing,
userLeaving, prev.configChangeFlags, pauseImmediately);
} catch (Exception e) {
}
}
...
}
Android-281
2
3
4
5
6
7
8
9
10
11
12
13
14#ActivityStack
final boolean startPausingLocked(boolean userLeaving, boolean uiSleeping,
ActivityRecord resuming, boolean pauseImmediately) {
...
if (prev.app != null && prev.app.thread != null) {
try {
mService.getLifecycleManager().scheduleTransaction(prev.app.thread, prev.appToken,
PauseActivityItem.obtain(prev.finishing, userLeaving,
prev.configChangeFlags, pauseImmediately));
} catch (Exception e) {
}
}
...
}
27版本,system_server进程的ActivityStack是直接操作客户端进程ApplicationThread的本地代理的;
28版本,变成AMS调用ClientLifecycleManager.scheduleTransaction()
完成,3个参数:客户端进程ApplicationThread的本地代理、客户端进程执行事务Activity所对应的Token、ActivityLifecycleItem,理解为哪个进程的哪个Activity执行什么操作。
AMS通知客户端暂停Activity过程
客户端准备启动Activity前,AMS会把当前栈或其他栈栈顶的Activiy设置为暂停状态。
(在ActivityStack.resumeTopActivityInnerLocked()调用ActivityStackSupervisor.startSpecificActivityLocked()之前)1
2
3
4
5
6
7
8
9
10
11
12
13
14ActivityStack
final boolean startPausingLocked(boolean userLeaving, boolean uiSleeping,
ActivityRecord resuming, boolean pauseImmediately) {
...
if (prev.app != null && prev.app.thread != null) {
try {
mService.getLifecycleManager().scheduleTransaction(prev.app.thread, prev.appToken,
PauseActivityItem.obtain(prev.finishing, userLeaving,
prev.configChangeFlags, pauseImmediately));
} catch (Exception e) {
}
}
...
}
mService:AMS。
mService.getLifecycleManager():ClientLifecycleManager。
ClientLifecycleManager.scheduleTransaction
1 | #1 |
scheduleTransaction方法#2、3、4最终均调用#1。其中:
- #2参数中的ActivityLifecycleItem是#3参数中ClientTransactionItem的子类;
- #4少了一个IBinder对象,是因为Activity有可能是ApplicationContext发起的,一个Activity被创建时AMS会同时为其创建一个Token对象,而Application则没有这个Token对象,所以传
null
; - #2、3、4均把参数揉合成一个ClientTransaction,然后调用#1;
- 这里调用的是#2方法,添加的是ActivityLifecycleItem,,并没有为ClientTransaction添加
Callback
。
ClientTransaction
1 | public class ClientTransaction implements Parcelable, ObjectPoolItem { |
可以看到,ClientTransaction仅仅是简单的封装了IApplicationThread本地代理、客户端的ActivityToken、代表具体操作的ClientTransactionItem列表和ActivityLifecycleItem。ClientTransaction具有跨进程通信能力,当然ClientTransactionItem也具有跨进程能力。
封装好ClientTransaction后,执行ClientTransaction.schedule()
,熟悉Binder通信的原理后可知,经由Binder驱动最终客户端进程的ApplicationThread.scheduleTransaction(ClientTransaction)
。后面的操作均在客户端进程中。
ApplicationThread.scheduleTransaction
1 | public void scheduleTransaction(ClientTransaction transaction) throws RemoteException { |
ClientTransactionHandler是ActivityThread的父类,scheduleTransaction方法由ClientTransactionHandler中实现
ClientTransactionHandler.scheduleTransaction
1 | void scheduleTransaction(ClientTransaction transaction) { |
sendMessage()在ActivityThread中实现1
2
3
4
5
6
7
8
9
10
11
12
13
14
15void sendMessage(int what, Object obj) {
sendMessage(what, obj, 0, 0, false);
}
private void sendMessage(int what, Object obj, int arg1, int arg2, boolean async) {
Message msg = Message.obtain();
msg.what = what;
msg.obj = obj;
msg.arg1 = arg1;
msg.arg2 = arg2;
if (async) {
msg.setAsynchronous(true);
}
mH.sendMessage(msg);
}
其中mH
是ActivityThread内部类H,是一个Handler,直接看handleMessage()
1
2
3
4
5
6
7
8
9
10
11public void handleMessage(Message msg) {
switch (msg.what) {
case EXECUTE_TRANSACTION:
final ClientTransaction transaction = (ClientTransaction) msg.obj;
mTransactionExecutor.execute(transaction);
if (isSystem()) {
transaction.recycle();
}
break;
}
}
mTransactionExecutor:TransactionExecutor,客户端统一处理事务的类。
TransactionExecutor
1 | public class TransactionExecutor { |
execute()处理ClientTransaction,先调用executeCallbacks()取出ClientTransaction中的ClientTransactionItem列表,便利然后调用ClientTransactionItem的execute()和postExecute();然后调用executeLifecycleState(),取出ClientTransaction中的ActivityLifecycleItem,调用ClientTransactionItem的execute()和postExecute()。转了一圈,终于执行ClientTransactionItem了。
关于cycleToPath()方法的作用是。当Activity的生命周期的状态从状态A切换到状态B时,执行其中间未执行到的状态。例:
- Activity从前台进入后台,RESUME到PAUSE,中间没有其他状态则实际没有执行什么;
- Activity从创建到显示,CREATE到RESUME,会执行CREATE到RESUME中间的START状态(
见ActivityStackSupervisor.realStartActivityLocked()
)。
这就解释了为什么AMS创建并显示Activity时,只使用了LaunchActivityItem和ResumeActivityItem,但也执行了AT.handleStartActivity()
的缘故。
回到暂停Activity的代码中,这里没有向ClientTransaction添加Callback
,而ClientTransaction中的ActivityLifecycleItem便是PauseActivityItem。
PauseActivityItem
1 | public class PauseActivityItem extends ActivityLifecycleItem { |
主要方法:
obtain():生成PauseActivityItem对象并对属性赋值。
execute():客户端进程ActivityThread准备执行的方法(ClientTransactionHandler定义ActivityThread实现)。
postExecute():给AMS的反馈。
execute()方法调用了ActivityThread.handlePauseActivity()
ActivityThread.handlePauseActivity
1 | public void handlePauseActivity(IBinder token, boolean finished, boolean userLeaving, |
到这里就是熟悉的代码了,不再分析。
总结大致流程
AMS跨进程和客户端进程通信有关Activity的重要的生命周期,均由ClientLifecycleManager.scheduleTransaction()完成。
把Activity准备执行的行为抽象到ActivityLifecycleItem中,根据不同的场景编写相应代码;把Activity准备执行必备参数和ActivityLifecycleItem封装到ClientTransaction中。
AMS跨进程传输ClientTransaction,客户端进程ApplicationThread接收,然后发送到主线程ActivityThread,最后由TransactionExecutor统一解析。
AMS封装并传输ClientTransaction,统一接口;客户端进程接收ClientTransaction并使用TransactionExecutor解析AMS的请求,再根据ActivityLifecycleItem执行不同的代码。
ActivityLifecycleItem的实现在“…/android-28/android/app/servertransaction/”目录下,Activity生命周期相关的方法LaunchActivityItem、ResumeActivityItem、PauseActivityItem、StopActivityItem、DestroyActivityItem,Activity的Configuration变化的回调、ActivityResult、onNewIntent等等。基本上其他的ActivityLifecycleItem是一样的原理。均在execute()方法中调用ActivityThread相关方法的。