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

向ROOM数据库写入数据时App崩溃:如何初始化UserDatabase?

解决kotlin.UninitializedPropertyAccessException:lateinit属性userDB未初始化的问题

错误日志:

2022-08-03 15:41:29.243 21219-21250/com.example.roomdatabasetest E/AndroidRuntime: FATAL EXCEPTION: DefaultDispatcher-worker-1
    Process: com.example.roomdatabasetest, PID: 21219
    kotlin.UninitializedPropertyAccessException: lateinit property userDB has not been initialized
        at com.example.roomdatabasetest.MainActivity$writeData$1.invokeSuspend(MainActivity.kt:52)
        at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
        at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:106)
        at kotlinx.coroutines.scheduling.CoroutineScheduler.runSafely(CoroutineScheduler.kt:571)
        at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.executeTask(CoroutineScheduler.kt:750)
        at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.runWorker(CoroutineScheduler.kt:678)
        at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.run(CoroutineScheduler.kt:665)

问题原因:

你声明了lateinit var userDB : UserDatabase,但在调用userDB.userDao().insertAll(user)前未对其初始化,导致抛出未初始化异常。

初始化UserDatabase的步骤:

1. 确认UserDatabase类的正确定义

你的UserDatabase必须是Room数据库的抽象类,带有@Database注解,示例如下:

import androidx.room.Database
import androidx.room.RoomDatabase

@Database(entities = [User::class], version = 1)
abstract class UserDatabase : RoomDatabase() {
    abstract fun userDao(): UserDao
}

2. 用单例模式管理数据库实例(推荐)

为避免重复创建数据库连接,给UserDatabase添加单例实现:

@Database(entities = [User::class], version = 1)
abstract class UserDatabase : RoomDatabase() {
    abstract fun userDao(): UserDao

    companion object {
        @Volatile
        private var INSTANCE: UserDatabase? = null

        fun getDatabase(context: Context): UserDatabase {
            return INSTANCE ?: synchronized(this) {
                val instance = Room.databaseBuilder(
                    context.applicationContext, // 使用全局上下文避免内存泄漏
                    UserDatabase::class.java,
                    "user_database" // 数据库文件名
                ).build()
                INSTANCE = instance
                instance
            }
        }
    }
}

3. 在MainActivity中初始化userDB

修改onCreate方法,添加初始化代码:

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_main)
    btnWriteData = findViewById(R.id.btnWriteData)
    btnReadData = findViewById(R.id.btnReadData)
    etFirstName = findViewById(R.id.etFirstName)
    etLastName = findViewById(R.id.etLastName)

    // 初始化userDB
    userDB = UserDatabase.getDatabase(this)

    btnWriteData.setOnClickListener{
        writeData()
    }

    btnReadData.setOnClickListener{
        readData()
    }
}

额外提示:

  • 首次创建数据库存在IO耗时,Room.databaseBuilder().build()允许在主线程调用,但正式环境建议在IO协程中初始化;测试阶段可临时添加allowMainThreadQueries(),但不推荐用于生产环境
  • 使用applicationContext初始化数据库,避免Activity销毁引发的内存泄漏

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.24 07:36:22