/** * 第 3 章配套代码 · Pager 生命周期演示 * * 文件位置:shared/src/commonMain/kotlin/com/example/kuikly/pages/LifecycleDemoPage.kt * * 本示例演示 Pager 生命周期 4 个核心方法的触发时机: * created() → 对象刚创建(读 pageData、初始化) * body() → 第一次构建 UI * pageDidAppear() → 页面真正显示到屏幕(埋点、起动画) * pageWillDestroy()→ 页面即将销毁(取消请求、解绑监听) * * 跑起来观察日志,即可建立"什么时候做什么事"的肌肉记忆。 */ package com.example.kuikly.pages import com.tencent.kuikly.core.annotations.Page import com.tencent.kuikly.core.base.Color import com.tencent.kuikly.core.base.ViewBuilder import com.tencent.kuikly.core.log.KLog import com.tencent.kuikly.core.pager.Pager import com.tencent.kuikly.core.reactive.handler.observable import com.tencent.kuikly.core.views.Text import com.tencent.kuikly.core.views.View private const val TAG = "Lifecycle" @Page("LifecycleDemoPage") internal class LifecycleDemoPage : Pager() { private var userId: String = "" private var fromSource: String = "" private var elapsedSec by observable(0) private var timerHandle: Any? = null // ──────────────────────────────────────────────────────── // ① created:页面对象刚刚创建 // 适合:读 pageData、做字段初始化、订阅长期数据流 // 注意:此时 UI 还没渲染,不能直接操作 view // ──────────────────────────────────────────────────────── override fun created() { super.created() userId = pageData.params.optString("userId", "") fromSource = pageData.params.optString("from", "unknown") KLog.i(TAG, "① created userId=$userId, from=$fromSource") } // ──────────────────────────────────────────────────────── // ② body:每次需要构建/重建 UI 都会调 // 第一次执行发生在 created() 之后、pageDidAppear() 之前 // 后续:根容器需要重建时 // ──────────────────────────────────────────────────────── override fun body(): ViewBuilder { KLog.i(TAG, "② body() called") val ctx = this return { attr { allCenter() backgroundColor(Color(0xFF1E1E1EL)) } Text { attr { text("已停留 ${ctx.elapsedSec} 秒") fontSize(22f) color(Color.WHITE) fontWeightBold() } } View { attr { marginTop(20f) paddingHorizontal(20f) paddingVertical(8f) borderRadius(8f) backgroundColor(Color(0xFF424242L)) } Text { attr { text("userId=$userId, from=$fromSource") fontSize(12f) color(Color(0xFFBDBDBDL)) } } } } } // ──────────────────────────────────────────────────────── // ③ pageDidAppear:页面真正显示 // 适合:发 PV 埋点、起入场动画、启动定时器、申请权限 // ──────────────────────────────────────────────────────── override fun pageDidAppear() { super.pageDidAppear() KLog.i(TAG, "③ pageDidAppear -> 上报 PV 埋点") // 启动一个 1 秒一次的"停留时长"计时器 // 真实工程一般用 TimerModule,这里只示意 startElapsedTimer() } // ──────────────────────────────────────────────────────── // ④ pageWillDestroy:页面即将销毁 // 适合:取消所有正在进行的网络请求、移除监听、停止定时器 // 若不清理,会导致 Pager 实例无法回收 → 内存泄漏 // ──────────────────────────────────────────────────────── override fun pageWillDestroy() { super.pageWillDestroy() KLog.i(TAG, "④ pageWillDestroy -> 取消计时器、上报停留时长 ${elapsedSec}s") stopElapsedTimer() } // ──────────────────────────────────────────────────────── // 辅助:模拟一个简单计时器 // 真实项目应使用 TimerModule(第 8 章会讲) // ──────────────────────────────────────────────────────── private fun startElapsedTimer() { // 伪代码:acquireModule(...).schedule(1000) { elapsedSec++ } timerHandle = Any() } private fun stopElapsedTimer() { timerHandle = null } }