从第二个Fragment访问时ViewModel存储的状态丢失如何解决?
你使用的默认by viewModel()扩展获取ViewModel时,作用域为当前Fragment本身,因此Fragment A和Fragment B获取到的是两个完全独立的LoginViewModel实例,各自存储的数据无法互通。
默认情况下,by viewModel()会将ViewModel实例绑定到当前Fragment的ViewModelStore,实例生命周期和当前Fragment完全对齐,Fragment A销毁时其对应的ViewModel也会被回收,导航到Fragment B后获取的是全新的ViewModel实例,自然无法拿到之前在Fragment A中设置的数据。
根据你的业务场景选择对应作用域即可:
方案1:绑定到共同宿主Activity的作用域
若两个Fragment挂载在同一个Activity下,将ViewModel获取方式替换为by activityViewModels(),两个Fragment会拿到宿主Activity持有的同一ViewModel实例,数据可正常共享:// Fragment A、Fragment B中同步修改ViewModel的声明方式 private val viewModel: LoginViewModel by activityViewModels()该方案下ViewModel生命周期和宿主Activity对齐,适合需要在整个Activity生命周期内共享登录数据的场景。
方案2:绑定到Jetpack Navigation导航图作用域
如果你使用了Jetpack Navigation组件管理页面路由,可以将ViewModel绑定到登录流程对应的导航图作用域,仅在导航流程生效期间共享数据:// 需提前导入navigation-fragment-ktx依赖 private val viewModel: LoginViewModel by navGraphViewModels(R.id.登录流程导航图对应的ID)该方案下ViewModel生命周期和导航图绑定,登录流程结束导航图出栈时,ViewModel会同步销毁,不会长期占用内存,更适合单次登录流程的数据共享场景。
内容的提问来源于stack exchange,提问作者Cody

