You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Room数据库数据不持久化问题:Android+Dagger配置求助

Room数据库调试重启后数据丢失问题排查与解决

核心问题分析

断开调试时数据正常保留,但调试重启后数据丢失,这类问题通常和调试配置、数据持久化路径或依赖注入的实例管理有关,以下是针对性排查和解决方案:

1. 关闭调试启动时的"清除应用数据"选项

Android Studio默认调试配置如果开启了**"Clear app data on launch"**,每次启动调试都会清空应用的所有本地数据(包括Room数据库):

  • 操作路径:Run/Debug Configurations → 选中你的应用配置 → 切换到General标签页 → 取消勾选Clear app data

2. 验证Room数据库的持久化路径

调试时可以打印数据库的实际存储路径,确认数据是否写入到持久化目录:

// 在AppDB的getAppDBInstance方法中添加日志
val dbPath = context.applicationContext.getDatabasePath("TransitPayDB.db3").absolutePath
Log.d("AppDB", "数据库存储路径:$dbPath")

重启调试后,检查该路径下的数据库文件是否存在。如果路径指向临时目录,会导致数据无法持久化。

3. 简化Dagger与Room的单例管理

你的AppDB同时实现了手动单例和Dagger的@Singleton注解,虽然逻辑上不冲突,但可以简化配置,直接让Dagger管理Room实例,避免潜在的实例重复创建问题:
修改AppDB,移除手动单例实现:

@Database(entities = [User::class], version = 1, exportSchema = true)
abstract class AppDB : RoomDatabase() {
    abstract fun userRepository(): IUserRepository
}

修改AppModule中的Room实例提供方法:

@Singleton
@Provides
fun getRoomDBInstance(context: Context): AppDB {
    return Room.databaseBuilder(
        context.applicationContext,
        AppDB::class.java,
        "TransitPayDB.db3"
    ).allowMainThreadQueries()
    .build()
}

4. 确认数据库事务正确提交

虽然调试时能看到数据,但要确保所有数据库操作都完成事务提交:

  • Room会自动为@Insert/@Update/@Delete注解的DAO方法处理事务
  • 自定义复杂操作时,需在DAO方法上添加@Transaction注解保证原子性:
@Transaction
fun batchUpdateUsers(users: List<User>) {
    users.forEach { update(it) }
}

5. 修复SharedPreferences未初始化问题(非直接相关,但避免异常)

你的BaseViewModel中使用了sharedPrefs但未初始化,可能引发其他异常,补充初始化逻辑:

open class BaseViewModel(application: Application) : AndroidViewModel(application) {

    @Inject lateinit var userRepository: IUserRepository
    private val sharedPrefs = application.getSharedPreferences("AppPrefs", Context.MODE_PRIVATE)

    init {
        (application as MyApp).getAppComponent().inject(this)
        sharedUserId = sharedPrefs.getInt("userId",0)
        sharedCompanyId = sharedPrefs.getInt("companyId",0)
        sharedRoleId = sharedPrefs.getInt("roleId",0)
        sharedFullName = sharedPrefs.getString("fullName","")
        sharedApiToken = sharedPrefs.getString("apiToken","")
    }
}

总结

优先检查调试配置中的"清除应用数据"选项,这是此类问题最常见的原因。如果问题仍存在,再依次验证数据库路径、事务提交和Dagger配置。

内容的提问来源于stack exchange,提问作者wenreloz

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.20 17:38:13