应用旋转时Room数据库表不存在及ViewModel创建失败问题求助
问题解决方案
一、解决旋转时Room错误"no such table: room_table_modification_log"
问题原因
你在MainActivity.onDestroy()中调用了dbClose()手动关闭数据库,但屏幕旋转属于配置变更,此时Activity会被销毁并重建,手动关闭数据库会导致Room内部维护的元数据表(如room_table_modification_log)状态异常,重建后重新获取数据库实例时就会触发该错误。Room会自动管理数据库连接的生命周期,无需手动干预。
解决方案
直接移除MainActivity.onDestroy()中调用dbClose()的代码,让Room自行处理数据库连接的开闭逻辑。
二、解决navGraphViewModels无法创建SensorViewModel的问题
问题原因
使用navGraphViewModels时传入了defaultViewModelProviderFactory,但默认工厂并不了解你的SensorViewModel对SensorRepo的依赖,无法创建需要自定义参数的ViewModel实例。
解决方案
为每个ViewModel指定对应的自定义Factory,修改navGraphViewModels的调用方式:
// ActuatorDeviceInfoViewModel示例 private val actDevInfVM: ActuatorDeviceInfoViewModel by navGraphViewModels(R.id.main_nav_graph) { ActuatorDeviceInfoViewModel.ActuatorDeviceInfoViewModelFactory((ctx.application as MyApp).actuatorDeviceInfoRepo) } // SensorViewModel同理 private val sensorVM: SensorViewModel by navGraphViewModels(R.id.main_nav_graph) { SensorViewModel.SensorViewModelFactory((ctx.application as MyApp).sensorRepo) }
如果希望统一管理依赖,可以在Application类中封装通用的ViewModelFactory,或者引入依赖注入框架(如Hilt)简化传递逻辑,但上述直接传入对应Factory的方式最直接有效。
三、关于配置变更时的状态保存
不需要通过onSaveInstanceState保存数据库相关数据:
- 用
viewModels或navGraphViewModels创建的ViewModel会在配置变更时自动保留实例,内部的StateFlow等数据流也会维持原有状态。 - 只需确保ViewModel中的数据逻辑正确(比如在ViewModel初始化时调用
fetchAll(),或在数据流为空时自动触发加载),旋转后ViewModel会复用原有实例,数据无需额外保存。
内容的提问来源于stack exchange,提问作者rminaj
相关产品推荐
相关产品推荐

