Skip to content

page-result-demo ​

1. 实验目标 ​

验证「子页面选完结果回传父页面」的最小正确写法,避免把一次性回传结果升级成全局状态:

  • 子页用 setResult(RESULT_OK, intent) + finish() 回传 EXTRA_RESULT
  • 父页用 registerForActivityResult 接收结果,只更新本页展示
  • 区分「页面回传结果」与 SavedStateHandle 恢复态的边界

2. 对应事故样板 ​

  • 为什么地址选择 / 支付结果不该塞进全局单例?
    • 一句话答:回传结果是页面间的一次性契约,父页收到后应落到本页 state;升级成全局状态会污染其他页面并难以清理。
  • 什么时候才该用 SavedStateHandle 而不是 EXTRA_RESULT?
    • 一句话答:EXTRA_RESULT 适合 Activity 栈内父子回传;SavedStateHandle 适合进程恢复时重建轻量锚点,不适合承载「刚选完要立刻消费」的脉冲结果。

3. 运行方式 ​

bash
cd labs/android/host
./gradlew installDebug

打开 Android Host → 打开页面返回结果实验室(由 host 入口接线后可见)。

4. 观察步骤 ​

  1. 首页点击「打开详情页选择结果」
  2. 详情页点击「携带结果返回」
  3. 回到首页,观察「上次返回结果」区域更新
  4. 再次打开详情并取消(按返回键不点按钮):首页结果应保持不变

5. 关键实现速览 ​

5.1 子页回传结果 ​

kotlin
val resultIntent = Intent().putExtra(EXTRA_RESULT, "detail-result-$selectionId")
setResult(RESULT_OK, resultIntent)
finish()

这段代码说明:回传结果走 Intent extra,生命周期随 Activity 结束而交付给父页 launcher。

完整源码:PageResultDetailActivity.kt

5.2 父页注册 launcher 接收 ​

kotlin
private val detailLauncher = registerForActivityResult(
    ActivityResultContracts.StartActivityForResult(),
) { result ->
    if (result.resultCode == RESULT_OK) {
        val value = result.data?.getStringExtra(PageResultDetailActivity.EXTRA_RESULT)
        if (value != null) {
            lastResultView.text = "上次返回结果:$value"
        }
    }
}

这段代码说明:父页只在回调里更新本页 UI,不把回传结果写入全局仓库或 SavedStateHandle。

完整源码:PageResultDemoActivity.kt

5.3 SavedStateHandle 边界(对照) ​

若结果需要跨进程恢复(例如筛选条件 key),才进入 SavedStateHandle;页面刚选完的回传结果应在父页 onActivityResult / launcher 回调中立刻消费,不应持久化到恢复态,否则进程重建后可能重复应用旧选择。

6. 对应知识库文档 ​

站点构建时间:2026/8/24 23:43:17