在onCreate post的message 与onResume究竟谁先执行

前言

有一个朋友A在面试中被问到了这个问题,由于项目框架原因,很少与Activity打交道,今天我来一探究竟

onResume先执行

很简单,我们加上日志测试下

kotlin 复制代码
override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    Log.i(TAG, "onCreate")
    Handler(Looper.getMainLooper()).apply {
        post {
            Log.i(TAG, " do onCreate post handle ")
        }
    }
} 
override fun onResume() {
    Log.i(TAG, "onResume")
    super.onResume()
}

显然,onResume先执行

为什么onResume先执行

既然这个问题与handle有关,那我们分别打印下messageQueue中的message列表观察下顺序

kotlin 复制代码
override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    Log.i(TAG, "onCreate")
    Handler(Looper.getMainLooper()).apply {
        post {
            Log.i(TAG, " do onCreate post handle ")
        }
    }
    printMessage("onCreate")
}

override fun onResume() {
    Log.i(TAG, "onResume")
    printMessage("onResume")
    super.onResume()
}

在onCreat末尾打印,

在onResume开头打印

很明显,最后一个message就是我们post的message。两次打印中第一个meassage对象的哈希值相同,是同一个message,说明onCreat与onResume在同一个message中执行。

看到这里,这个问题已经清晰了,但是我的同学A还是很疑惑,执行onCreat之后是如何执行onResume呢

执行onCreat之后是如何执行onResume

由于对源码不是很熟悉,我们打断点观察下它们的调用栈

可以看到差异点在TransactionExecutor.excute(),那我们去从这里入手去看看

kotlin 复制代码
public void execute(ClientTransaction transaction) {
	...
    executeCallbacks(transaction); //通过调用栈可以看出这里继续递归会调用oncreat

    executeLifecycleState(transaction);//这里继续递归会调用onresume

    ...
   
}

我们先看下executeCallbacks

kotlin 复制代码
public void executeCallbacks(ClientTransaction transaction) {
    final List<ClientTransactionItem> callbacks = transaction.getCallbacks();
    ...

    final int size = callbacks.size();
    for (int i = 0; i < size; ++i) {
    	...
    	// 根据调用栈可以看出item一定有一个LaunchAcitivityItem,后续执行兴趣可根据调用栈继续查看,
        //最后会调用ActivityThread.handleCreateActivity()
        item.execute(mTransactionHandler, token, mPendingActions);
        item.postExecute(mTransactionHandler, token, mPendingActions);
    	 ...
    }
}

再看下executeLifecycleState,这个方法的注释很有意思:转换到这个事务请求的最中状态。

根据调用栈可知,lifecycleItem 是ResumeAcitivityItem

kotlin 复制代码
/** Transition to the final state if requested by the transaction. */
private void executeLifecycleState(ClientTransaction transaction) {
    final ActivityLifecycleItem lifecycleItem = transaction.getLifecycleStateRequest();
    if (lifecycleItem == null) {
        // No lifecycle request, return early.
        return;
    }

    final IBinder token = transaction.getActivityToken();
    final ActivityClientRecord r = mTransactionHandler.getActivityClient(token);
    if (DEBUG_RESOLVER) {
        Slog.d(TAG, tId(transaction) + "Resolving lifecycle state: "
               + lifecycleItem + " for activity: "
               + getShortActivityName(token, mTransactionHandler));
    }

    if (r == null) {
        // Ignore requests for non-existent client records for now.
        return;
    }

    // Cycle to the state right before the final requested state.
    cycleToPath(r, lifecycleItem.getTargetState(), true /* excludeLastState */, transaction);

    // Execute the final transition with proper parameters.
    //执行lifecycleItem,也就是ResumeAcitivityItem
    //最后会调用ActivityThread.handleResumeActivity()
    lifecycleItem.execute(mTransactionHandler, token, mPendingActions); 
    lifecycleItem.postExecute(mTransactionHandler, token, mPendingActions);
}

在这里,可能有的同学有个疑问,onCreate 和onResume中间还有一个onStart,这个去哪了呢

那就不得不看下cycleToPath 这个方法,它上面的注释也很清晰的回答了我们的问题,我们仔细看下他的实现,注意下path的获取方式

kotlin 复制代码
private void cycleToPath(ActivityClientRecord r, int finish, boolean excludeLastState,
                         ClientTransaction transaction) {
    final int start = r.getLifecycleState();
    if (DEBUG_RESOLVER) {
        Slog.d(TAG, tId(transaction) + "Cycle activity: "
               + getShortActivityName(r.token, mTransactionHandler)
               + " from: " + getStateName(start) + " to: " + getStateName(finish)
               + " excludeLastState: " + excludeLastState);
    }
    final IntArray path = mHelper.getLifecyclePath(start, finish, excludeLastState);
    performLifecycleSequence(r, path, transaction);
}

里面只是执行了performLifecycleSequence,我们继续看下

kotlin 复制代码
/** Transition the client through previously initialized state sequence. */
private void performLifecycleSequence(ActivityClientRecord r, IntArray path,
                                      ClientTransaction transaction) {
    final int size = path.size();
    for (int i = 0, state; i < size; i++) {
        state = path.get(i);
        if (DEBUG_RESOLVER) {
            Slog.d(TAG, tId(transaction) + "Transitioning activity: "
                   + getShortActivityName(r.token, mTransactionHandler)
                   + " to state: " + getStateName(state));
        }
        switch (state) {
            case ON_CREATE:
            mTransactionHandler.handleLaunchActivity(r, mPendingActions,
                                                         null /* customIntent */);
            break;
            case ON_START:
            mTransactionHandler.handleStartActivity(r, mPendingActions);
            break;
            case ON_RESUME:
            mTransactionHandler.handleResumeActivity(r.token, false /* finalStateRequest */,
                                                         r.isForward, "LIFECYCLER_RESUME_ACTIVITY");
            break;
            case ON_PAUSE:
            mTransactionHandler.handlePauseActivity(r.token, false /* finished */,
                                                        false /* userLeaving */, 0 /* configChanges */, mPendingActions,
                                                        "LIFECYCLER_PAUSE_ACTIVITY");
            break;
            case ON_STOP:
            mTransactionHandler.handleStopActivity(r.token, false /* show */,
                                                       0 /* configChanges */, mPendingActions, false /* finalStateRequest */,
                                                       "LIFECYCLER_STOP_ACTIVITY");
            break;
            case ON_DESTROY:
            mTransactionHandler.handleDestroyActivity(r.token, false /* finishing */,
                                                          0 /* configChanges */, false /* getNonConfigInstance */,
                                                          "performLifecycleSequence. cycling to:" + path.get(size - 1));
            break;
            case ON_RESTART:
            mTransactionHandler.performRestartActivity(r.token, false /* start */);
            break;
            default:
            throw new IllegalArgumentException("Unexpected lifecycle state: " + state);
        }
    }
}

原来如此,还记得path怎么计算的么,显然是这里分发了start事件。我们再次打印下onStart的调用栈

呕吼,没错,就是这样。

后言

查看源码过程中,源于对activityManage了解不够,对于启动activity信息的接受ActivityThread.H,信息的传递ClientTransaction 等相关类扮演角色尚未吃透,在仔细查看后将再次进行介绍

#关于我 一个希望友友们能提出建议的代码下毒糕手

相关推荐
千里马学框架2 天前
一起学 Android 14:ShellTransition 屏幕旋转过程深度剖析
android·智能手机·性能优化·framework·性能·屏幕旋转·rotation
美狐美颜SDK开放平台2 天前
开发直播APP时如何接入视频美颜SDK?开发流程与注意事项
android·人工智能·计算机视觉·音视频·直播美颜sdk
AFinalStone2 天前
Android7 SystemUI源码解析(七)Keyguard锁屏模块深度解析
android·systemui
致远ccc2 天前
Google Play 上架前如何测试 App?多国家 Android 环境测试
android·app测试·googleplay·多国家应用测试
ttyyttemo2 天前
Kotlin 协程中的 Job 结构化并发与取消
android
sun0077002 天前
tbox 4g/5g切换,导致wan ip 改变,导致车机旧网络不可用。需要重启车机才行
android
其实防守也摸鱼2 天前
内网穿透与反向代理:原理、工具与实战指南
android·大数据·运维·安全·网络安全·自动化·渗透
AFinalStone2 天前
Android7 SystemUI 源码解析(四)NavigationBar 导航栏与 SystemBars
android·systemui
JMchen2 天前
属性动画原理与高级动画实现
android·kotlin·canvas
AFinalStone2 天前
Android7 SystemUI 源码解析(二)启动流程深度解析
android·systemui