You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何监听Jetpack Compose Navigator生命周期获取当前页面名称

解决方案:监听Jetpack Navigation路由变化(无Fragment场景)

你直接访问私有字段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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.20 17:06:32