如何为Google Navigation Graph生命周期作用域化依赖?求实现技巧
可以通过Navigation组件的NavBackStackEntry结合ViewModel来实现,核心是利用导航栈条目(对应整个Navigation Graph)的生命周期绑定依赖的生命周期,具体操作如下:
获取Graph对应的NavBackStackEntry
每个Navigation Graph在导航栈中对应一个NavBackStackEntry实例,通过navController.getBackStackEntry(R.id.your_nav_graph_id)可获取该Graph的栈条目,这个条目的生命周期和整个Graph完全同步——当Graph被从栈中移除时,该条目会被销毁。创建Graph作用域的ViewModel
以获取到的NavBackStackEntry作为ViewModel的所有者,创建ViewModel实例,该ViewModel的生命周期会和Graph绑定:val navGraphEntry = navController.getBackStackEntry(R.id.main_nav_graph) val graphScopedViewModel = ViewModelProvider(navGraphEntry)[GraphScopedViewModel::class.java]在ViewModel中管理依赖
将需要限定作用域的依赖放在这个ViewModel中,依赖的生命周期会跟随ViewModel,当Graph销毁时,ViewModel的onCleared()方法会被调用,可在此清理资源:class GraphScopedViewModel : ViewModel() { // 依赖实例,作用域限定在Graph生命周期内 val scopedDependency = YourCustomDependency() override fun onCleared() { super.onCleared() // 清理依赖资源 scopedDependency.dispose() } }Graph内Fragment共享依赖
同一个Graph下的所有Fragment,都可以通过相同的NavBackStackEntry获取到同一个ViewModel实例,从而共享同一依赖,保证依赖作用域严格限定在Graph内部。
如果使用Hilt,可以结合@ViewModelScoped注解将依赖注入到Graph作用域的ViewModel中,或者通过自定义EntryPoint从NavBackStackEntry中获取绑定的依赖,核心逻辑依然是基于NavBackStackEntry的生命周期。
需要注意:务必确保获取的NavBackStackEntry对应整个目标Navigation Graph,而非单个页面目的地,否则无法实现全局Graph的作用域控制。
内容的提问来源于stack exchange,提问作者Daniil Pozdnyakov

