如何监听Jetpack Compose Navigator生命周期获取当前页面名称
你直接访问私有字段navController_field的做法不可取——这属于Jetpack Navigation的内部实现细节,不仅无法直接调用,还会因版本迭代出现兼容性问题。正确的方式是使用官方提供的API监听导航目标变化,以下是具体实现:
步骤1:正确获取NavController
对于继承自ComponentActivity的MasterActivity,通过布局中NavHost视图的ID即可获取NavController实例(假设你的NavHostID为nav_host):
val navController = Navigation.findNavController(p0, R.id.nav_host)
步骤2:添加导航目标监听
使用NavController.addOnDestinationChangedListener监听路由切换,每次页面跳转时都会触发回调,你可以在回调中直接获取当前路由名称:
class AppLifeCycleObserver : Application.ActivityLifecycleCallbacks { private val destinationListeners = mutableMapOf<Activity, NavController.OnDestinationChangedListener>() var currentRoute: String? = null private val TAG = "AppLifeCycleObserver" fun log(message: String) { Log.e(TAG, message) } override fun onActivityCreated(p0: Activity, p1: Bundle?) { log("onActivityCreated") } override fun onActivityStarted(p0: Activity) { log("onActivityStarted") if (p0 is MasterActivity) { // 获取NavController,处理找不到的异常情况 val navController = try { Navigation.findNavController(p0, R.id.nav_host) } catch (e: IllegalArgumentException) { log("Failed to find NavController: ${e.message}") return } // 创建路由变化监听 val listener = NavController.OnDestinationChangedListener { _, destination, _ -> currentRoute = destination.route log("Current route: $currentRoute") // 在此处将路由名称上报给SDK,完成页面流转追踪 } navController.addOnDestinationChangedListener(listener) // 保存监听引用,用于后续移除 destinationListeners[p0] = listener } } override fun onActivityResumed(p0: Activity) { log("onActivityResumed") } override fun onActivityPaused(p0: Activity) { log("onActivityPaused") } override fun onActivityStopped(p0: Activity) { log("onActivityStopped") } override fun onActivitySaveInstanceState(p0: Activity, p1: Bundle) {} override fun onActivityDestroyed(p0: Activity) { log("onActivityDestroyed") // 移除监听,避免内存泄漏 destinationListeners.remove(p0)?.let { listener -> (p0 as? MasterActivity)?.let { activity -> try { Navigation.findNavController(activity, R.id.nav_host) .removeOnDestinationChangedListener(listener) } catch (e: IllegalArgumentException) { log("Failed to remove listener: ${e.message}") } } } } }
关键说明
- 拒绝私有字段依赖:官方API是唯一可靠的交互方式,依赖内部字段会导致代码在Jetpack Navigation版本更新后崩溃。
- 内存泄漏防护:必须在Activity销毁时移除监听,否则会导致Activity实例无法被GC回收。
- 深度链接适配:无论导航触发方式是深度链接、按钮点击还是其他,
OnDestinationChangedListener都会捕获到目标页面的变化,完全适配你的场景。
内容的提问来源于stack exchange,提问作者Bilal Bangash
相关产品推荐
相关产品推荐

