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

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

相关推荐
深海呐3 小时前
Android 最新的AndroidStudio引入依赖失败如何解决?如:Failed to resolve:xxxx
android·failed to res·failed to·failed to resol·failed to reso
解压专家6663 小时前
安卓解压软件推荐:高效处理压缩文件的实用工具
android·智能手机·winrar·7-zip
Rverdoser3 小时前
Android 老项目适配 Compose 混合开发
android
️ 邪神5 小时前
【Android、IOS、Flutter、鸿蒙、ReactNative 】标题栏
android·flutter·ios·鸿蒙·reatnative
努力遇见美好的生活6 小时前
Mysql每日一题(行程与用户,困难※)
android·数据库·mysql
图王大胜8 小时前
Android Framework AMS(17)APP 异常Crash处理流程解读
android·app·异常处理·ams·crash·binderdied·讣告
ch_s_t8 小时前
电子商务网站之首页设计
android
豆 腐10 小时前
MySQL【四】
android·数据库·笔记·mysql
想取一个与众不同的名字好难12 小时前
android studio导入OpenCv并改造成.kts版本
android·ide·android studio
Jewel10513 小时前
Flutter代码混淆
android·flutter·ios