重新创建Activity时触发SQLiteDatabase已关闭报错如何解决?
问题原因分析
- 系统配置变更(切换语言、深色模式属于系统配置变更)默认就会触发Activity自动销毁重建,你额外添加的自替换重建逻辑(调用
startActivity(intent)+finish())导致重建流程被触发两次,最终生成多个Activity实例,仅1个实例留存,其余实例销毁时执行onDestroy的数据库关闭逻辑。 - SQLiteOpenHelper、SQLiteDatabase针对同一个数据库的连接是全局共享的,任意实例调用
close()都会关闭全局数据库连接,导致留存的Activity持有的数据库对象直接失效,操作时抛出已关闭的异常。
修复方案
- 临时快速修复:在
onDestroy中增加销毁场景判断,只有非配置变更导致的正常销毁才关闭数据库,配置变更导致的销毁不需要释放数据库资源:
override fun onDestroy() { super.onDestroy() // 仅页面正常销毁时关闭数据库,配置变更重建场景不关闭 if (!isChangingConfigurations) { db.close() oh.close() } }
- 优化重建逻辑:二选一即可避免重复创建Activity实例:
- 直接删除自定义的自替换重建代码,使用系统默认的配置变更重建逻辑即可
- 在AndroidManifest对应Activity节点添加配置
android:configChanges="uiMode|locale|layoutDirection",自行处理配置变更,不会触发系统自动重建,也不需要再调用自定义重建逻辑
- 最佳实践:重构数据库实例管理逻辑,全局使用单例模式管理SQLiteOpenHelper实例,整个App生命周期内只初始化一次数据库连接,不要在单个Activity的生命周期中关闭数据库,仅在App退出时按需释放资源,从根源避免单页面销毁影响全局数据库连接的问题。
内容的提问来源于stack exchange,提问作者Karol
相关产品推荐
相关产品推荐

