Android 之 Jetpack - Room

以下是一个使用 Kotlin 和 Android Jetpack Room 的完整示例,涵盖 ​​实体定义 → DAO 接口 → 数据库构建 → MVVM 集成​​ 的全流程,采用协程和 Flow 实现异步操作与数据监听。

1. ​​添加依赖(build.gradle.kts)

dependencies {
    val roomVersion = "2.7.2"
    implementation("androidx.room:room-runtime:$roomVersion")
    kapt("androidx.room:room-compiler:$roomVersion") // Kotlin 注解处理
    implementation("androidx.room:room-ktx:$roomVersion") // 协程支持
    implementation("androidx.lifecycle:lifecycle-runtime-ktx:2.8.0") // ViewModel 协程
}

2. ​​定义实体类(Entity)

@Entity(tableName = "notes")
data class Note(
    @PrimaryKey(autoGenerate = true) 
    val id: Int = 0,
    val title: String,
    val content: String,
    @ColumnInfo(name = "created_at") 
    val createdAt: Long = System.currentTimeMillis()
)
  • @Entity:声明数据库表名

  • @PrimaryKey:自增主键

  • @ColumnInfo:自定义列名(可选)

3. ​​定义 DAO 接口

@Dao
interface NoteDao {
    @Insert(onConflict = OnConflictStrategy.REPLACE)
    suspend fun insert(note: Note)

    @Update
    suspend fun update(note: Note)

    @Delete
    suspend fun delete(note: Note)

    @Query("SELECT * FROM notes ORDER BY createdAt DESC")
    fun getAllNotes(): Flow<List<Note>> // 使用 Flow 实时监听数据变化

    @Query("SELECT * FROM notes WHERE title LIKE :query")
    suspend fun searchNotes(query: String): List<Note>
}
  • ​协程支持​​:所有写操作(Insert/Update/Delete)使用 suspend

  • ​Flow 监听​​:查询返回 Flow,数据变化时自动更新 UI 

4. ​​构建数据库类

@Database(entities = [Note::class], version = 1, exportSchema = false)
abstract class NoteDatabase : RoomDatabase() {
    abstract fun noteDao(): NoteDao

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

        fun getDatabase(context: Context): NoteDatabase {
            return INSTANCE ?: synchronized(this) {
                val instance = Room.databaseBuilder(
                    context.applicationContext,
                    NoteDatabase::class.java,
                    "note_database.db"
                ).build()
                INSTANCE = instance
                instance
            }
        }
    }
}
  • ​单例模式​​:避免重复打开数据库连接

  • @Volatilesynchronized:确保线程安全

5. ​​实现 Repository 层(数据抽象)​

class NoteRepository(private val noteDao: NoteDao) {
    val allNotes: Flow<List<Note>> = noteDao.getAllNotes()

    suspend fun insert(note: Note) = noteDao.insert(note)
    suspend fun update(note: Note) = noteDao.update(note)
    suspend fun delete(note: Note) = noteDao.delete(note)
    suspend fun search(query: String) = noteDao.searchNotes(query)
}

职责分离​​:ViewModel 不直接操作数据库,通过 Repository 中转

6. ​​创建 ViewModel​

class NoteViewModel(application: Application) : AndroidViewModel(application) {
    private val repository: NoteRepository

    val allNotes: Flow<List<Note>>

    init {
        val dao = NoteDatabase.getDatabase(application).noteDao()
        repository = NoteRepository(dao)
        allNotes = repository.allNotes
    }

    fun insert(note: Note) = viewModelScope.launch(Dispatchers.IO) {
        repository.insert(note)
    }

    fun delete(note: Note) = viewModelScope.launch(Dispatchers.IO) {
        repository.delete(note)
    }
}
  • ​协程作用域​​:viewModelScope自动管理生命周期,避免内存泄漏

  • ​后台线程​​:使用 Dispatchers.IO执行数据库操作

7. ​​在 Activity 中使用(UI 层)

class MainActivity : AppCompatActivity() {
    private val viewModel: NoteViewModel by viewModels {
        NoteViewModelFactory(NoteDatabase.getDatabase(this).noteDao())
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        // 监听数据变化并更新 UI
        lifecycleScope.launch {
            repeatOnLifecycle(Lifecycle.State.STARTED) {
                viewModel.allNotes.collect { notes ->
                    notesAdapter.submitList(notes)
                }
            }
        }

        // 添加新笔记
        binding.fabAdd.setOnClickListener {
            val note = Note(title = "新笔记", content = "内容...")
            viewModel.insert(note)
        }
    }
}

// ViewModelFactory(用于依赖注入)
class NoteViewModelFactory(private val dao: NoteDao) : ViewModelProvider.Factory {
    override fun <T : ViewModel> create(modelClass: Class<T>): T {
        return NoteViewModel(Application(), NoteRepository(dao)) as T
    }
}
  • ​生命周期感知​​:repeatOnLifecycle确保只在界面活跃时收集数据

  • ​RecyclerView 适配器​​:使用 ListAdapter自动处理数据差异

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值