在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 等相关类扮演角色尚未吃透,在仔细查看后将再次进行介绍

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

相关推荐
游戏开发爱好者81 分钟前
日常开发与测试的 App 测试方法、查看设备状态、实时日志、应用数据
android·ios·小程序·https·uni-app·iphone·webview
王码码20356 分钟前
Flutter for OpenHarmony 实战之基础组件:第三十一篇 Chip 系列组件 — 灵活的标签化交互
android·flutter·交互·harmonyos
黑码哥22 分钟前
ViewHolder设计模式深度剖析:iOS开发者掌握Android列表性能优化的实战指南
android·ios·性能优化·跨平台开发·viewholder
亓才孓34 分钟前
[JDBC]元数据
android
独行soc1 小时前
2026年渗透测试面试题总结-17(题目+回答)
android·网络·安全·web安全·渗透测试·安全狮
金融RPA机器人丨实在智能1 小时前
Android Studio开发App项目进入AI深水区:实在智能Agent引领无代码交互革命
android·人工智能·ai·android studio
科技块儿1 小时前
利用IP查询在智慧城市交通信号系统中的应用探索
android·tcp/ip·智慧城市
独行soc1 小时前
2026年渗透测试面试题总结-18(题目+回答)
android·网络·安全·web安全·渗透测试·安全狮
王码码20352 小时前
Flutter for OpenHarmony 实战之基础组件:第二十七篇 BottomSheet — 动态底部弹窗与底部栏菜单
android·flutter·harmonyos
2501_915106322 小时前
app 上架过程,安装包准备、证书与描述文件管理、安装测试、上传
android·ios·小程序·https·uni-app·iphone·webview