AMS对客户端的回调
上文所述的还只是整个流程的中间部分:我们应用开发常见的部分,如果你想详细了解Android P版本AMS对客户端生命周期的调用可以参考这篇文章,我们挑和生命周期相关的部分来说。AMS和应用是通过binder通讯的,ActivityThread中有个类ApplicationThread是用来接收AMS消息的,比如启动应用时,scheduleTransaction方法就会被调用,参数ClientTransaction封装了客户端需要执行的操作,
ActivityThread.ApplicationThread.java
@Override
public void scheduleTransaction(ClientTransaction transaction) throws RemoteException {
//ActivityThread的父类ClientTransactionHandler实现了此方法
ActivityThread.this.scheduleTransaction(transaction);
}
ClientTransactionHandler.java
void scheduleTransaction(ClientTransaction transaction) {
transaction.preExecute(this);
//sendMessage在ActivityThread中实现
sendMessage(ActivityThread.H.EXECUTE_TRANSACTION, transaction);
}
ActivityThread.java
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);
}
sendMessage方法就把消息从binder线程发到主线程的MessageQueue中,MessageQueue把消息取出来分发给mH处理
ActivityThread.java
class H extends Handler {
public static final int EXECUTE_TRANSACTION = 159;
public void handleMessage(Message msg) {
case EXECUTE_TRANSACTION:
final ClientTransaction transaction = (ClientTransaction) msg.obj;
mTransactionExecutor.execute(transaction);
...
break;
}
Object obj = msg.obj;
if (obj instanceof SomeArgs) {
((SomeArgs) obj).recycle();
}
}
}
下图可以看出ClientTransaction封装了那些数据,我们重点关注标记的部分,大家调试的时候要注意,第一个AMS消息并不是这个,而是通知客户端窗口可见了。
image.png
这里可以说是生命周期回调的源头了
TransactionExecutor.java
public void execute(ClientTransaction transaction) {
//上图我们能看到callBack只有一个:LaunchActivityItem,
//如果你回到文章最前面的断点调式截图就能看到通过它onCreate得以调用
executeCallbacks(transaction);
//看下面方法
executeLifecycleState(transaction);
}
//文章前面那一坨关于onCreate方法执行完就开始了这个方法
private void executeLifecycleState(ClientTransaction transaction) {
...
// 在到达最终状态前,先执行中间状态也就是onStart
cycleToPath(r, lifecycleItem.getTargetState(), true /* excludeLastState */);
// 执行上图红色标记的最终状态ResumeActivity也就是onResume
lifecycleItem.execute(mTransactionHandler, token, mPendingActions);
//执行完向AMS汇报
lifecycleItem.postExecute(mTransactionHandler, token, mPendingActions);
}
看到这里大家也就清楚了,我们经常看到的onCreate、onStart、onResume三个方法只是整个流程的九牛一毛,虽然看上去是分离的,实际上是在主线程的一个方法中调用的。流程整理如下
AMS_Launcher.png
看到这你可能不禁想:那按返回键从onPause到onDestory是否同样?当我们返回的时候,收到的是这样的ClientTransaction
image.png
如红色标记,没有callback,只有LifecycleStateRequest,所以只执行executeLifecycleState
private void executeLifecycleState(ClientTransaction transaction) {
...
// 没有中间状态可执行
cycleToPath(r, lifecycleItem.getTargetState(), true /* excludeLastState */);
// 执行上图红色标记的PauseActivityItem
lifecycleItem.execute(mTransactionHandler, token, mPendingActions);
//执行完向AMS汇报
lifecycleItem.postExecute(mTransactionHandler, token, mPendingActions);
}
紧跟着我们收到AMS的另一条消息
image.png
同样没有callback,只执行executeLifecycleState
private void executeLifecycleState(ClientTransaction transaction) {
...
// 执行从Pause到Destroy的中间状态onStop
cycleToPath(r, lifecycleItem.getTargetState(), true /* excludeLastState */);
// 执行上图红色标记的DestroyActivityItem
lifecycleItem.execute(mTransactionHandler, token, mPendingActions);
//执行完向AMS汇报
lifecycleItem.postExecute(mTransactionHandler, token, mPendingActions);
}
流程如下,binder线程调用了两次,发了两个消息,一个消息只执行了onPause,另一个消息执行了onStop到onDestroy
从用户角度来看,只执行了启动和返回两个简单操作,但背后的逻辑还是相当长的,尽管如此,只要我们掌握了方法就可以自己分析Home键返回、旋转、多个Activity的跳转等等复杂的场景。下一篇将分析如何感应Activity生命周期
网友评论