Android中Device File Explorer的Room数据库目录为空如何解决
问题根因
databases目录为空是三个核心错误导致的,数据库从未被正常触发创建:
- ViewModel未实例化:
MainActivity中仅声明了todoViewModel变量,从未完成初始化,调用插入方法时会直接触发未初始化崩溃,数据库操作逻辑根本没有执行 - Room注解处理器配置错误:Kotlin项目使用Room不能用Java的
annotationProcessor处理注解,否则Room无法生成数据库实现类,数据库创建逻辑完全失效 - 点击事件代码括号嵌套错误:
btnAddTodo的点击监听器大括号未正确闭合,btnDeleteTodo的点击逻辑被错误嵌套在添加按钮的回调内部,代码逻辑结构完全混乱
修复步骤
1. 修正Gradle配置
打开Module级别的build.gradle文件,先在plugins块中添加kapt插件:
plugins { id 'com.android.application' id 'org.jetbrains.kotlin.android' id 'kotlin-android-extensions' id 'kotlin-kapt' // 新增kapt插件支持 }
然后修改依赖块中的Room相关配置,替换注解处理器,补充ktx协程支持依赖:
dependencies { //ROOM 修正后的配置 def roomVersion = "2.4.2" implementation("androidx.room:room-runtime:$roomVersion") implementation("androidx.room:room-ktx:$roomVersion") kapt("androidx.room:room-compiler:$roomVersion") // 替换原annotationProcessor为kapt // 其余原有依赖保持不变 }
修改完成后同步Gradle。
2. 修正MainActivity代码
首先在onCreate中完成TodoViewModel的初始化,其次修正点击事件的括号嵌套问题,修正后的完整MainActivity代码如下:
package com.example.todoit import androidx.appcompat.app.AppCompatActivity import android.os.Bundle import androidx.lifecycle.ViewModelProvider import androidx.recyclerview.widget.LinearLayoutManager import com.example.todoit.data.Todo import com.example.todoit.data.TodoViewModel import kotlinx.android.synthetic.main.activity_main.* class MainActivity : AppCompatActivity() { private lateinit var todoAdapter: TodoAdapter private lateinit var todoViewModel: TodoViewModel override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) // 初始化ViewModel todoViewModel = ViewModelProvider( this, ViewModelProvider.AndroidViewModelFactory.getInstance(application) ).get(TodoViewModel::class.java) todoAdapter = TodoAdapter(mutableListOf()) rvTodoItems.layoutManager = LinearLayoutManager(this) rvTodoItems.adapter = todoAdapter btnAddTodo.setOnClickListener { val todoTitle = etTodoTitle.text.toString() if (todoTitle.isNotEmpty()) { val todo = Todo(0,todoTitle,false) etTodoTitle.text.clear() insertDataToDataBase(todo) todoAdapter.addTodo(todo) } } // 补全原代码缺失的闭合括号 // 删除按钮点击事件移到添加按钮回调外部 btnDeleteTodo.setOnClickListener { todoAdapter.deleteDoneTodos() } } private fun insertDataToDataBase(todo: Todo) { todoViewModel.addTodoToDataBase(todo) } }
3. 验证数据库生成的注意事项
- Room采用懒加载机制创建数据库:只有第一次执行实际的数据库读写操作时,数据库文件才会生成,也就是说安装App后需要至少点击一次添加按钮触发插入逻辑,才会生成db文件
- 查看文件时找对路径:依次进入
data/data/com.example.todoit/databases/目录,不要进错系统目录或者其他应用的目录 - 点击Device File Explorer顶部的同步刷新按钮,拉取设备上最新的文件列表,否则会因为缓存看不到新生成的文件
- 正常生成的数据库会包含三个文件:
todo_database、todo_database-shm、todo_database-wal,属于Room的WAL模式正常现象,不是错误
额外优化提示
当前代码仅将待办事项手动添加到RecyclerView的内存列表中,没有观察数据库的变更,后续可以给ViewModel中的readAllData加观察者,数据库内容变化时自动刷新列表,避免内存数据和数据库数据不一致。
内容的提问来源于stack exchange,提问作者Clivityy
相关产品推荐
相关产品推荐

