Jetpack之LifeCycle(二)

2019-06-10  本文已影响0人  风骚无俩

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

AMS_Destroy.png
从用户角度来看,只执行了启动和返回两个简单操作,但背后的逻辑还是相当长的,尽管如此,只要我们掌握了方法就可以自己分析Home键返回、旋转、多个Activity的跳转等等复杂的场景。下一篇将分析如何感应Activity生命周期
上一篇下一篇

猜你喜欢

热点阅读