Android MVVM架构下屏幕旋转时如何避免Fragment的ViewModel实例被重新创建?
问题根源
你遇到的ViewModel重建问题核心原因有两点:
- 屏幕旋转触发Activity重建时,
onCreate方法未做状态判断,每次重建都会执行Fragment事务替换出新的PersonalInfFragment实例,旧Fragment实例被销毁后,绑定其生命周期的ViewModel也会被同步回收。 - 若你需要
InformationViewModel的数据在多个Fragment间共享,当前将ViewModel绑定到Fragment生命周期的写法也会导致跨Fragment访问时拿到不同实例。
修复方案
1. 修正Activity的Fragment添加逻辑
仅在Activity首次初始化(savedInstanceState为空)时添加Fragment,系统重建Activity时会自动恢复已存在的Fragment实例,无需重复创建:
class TestingActivity : AppCompatActivity() { private lateinit var loginViewModel: LoginPageViewModel override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_testing) loginViewModel=ViewModelProvider(this).get(LoginPageViewModel::class.java) loginViewModel.getApiTokenRest(20234561, "ladevi31") TempDataStorage.initializeSharedPreferences(this) // 增加savedInstanceState判空逻辑 if (savedInstanceState == null) { supportFragmentManager.beginTransaction() .replace(R.id.container, PersonalInfFragment()).commit() } } }
修改后绑定到Fragment生命周期的ViewModel就会跟随Fragment实例保留,旋转屏幕不会重建。
2. 可选:将ViewModel绑定到Activity生命周期
如果你的InformationViewModel需要在多个同属该Activity的Fragment间共享数据,或者需要生命周期和页面整体保持一致,可以将Fragment中ViewModel的初始化宿主改为Activity:
// 原写法 绑定Fragment生命周期 // personalViewModel = ViewModelProvider(this).get(InformationViewModel::class.java) // 新写法 绑定宿主Activity生命周期 personalViewModel = ViewModelProvider(requireActivity()).get(InformationViewModel::class.java)
该写法下即使Fragment实例重建,ViewModel也会跟随Activity生命周期保留,不会重复创建。
3. 补充优化(避免重复请求)
修改后如果不需要每次Fragment视图重建都重新请求数据,可以在ViewModel的startRequesting方法中增加数据缓存判断,已有数据的情况下无需重复发起请求。
内容的提问来源于stack exchange,提问作者Bekzhan
相关产品推荐
相关产品推荐

