当前位置: 首页 > news >正文

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)@Updatesuspend fun update(note: Note)@Deletesuspend 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(): NoteDaocompanion object {@Volatileprivate var INSTANCE: NoteDatabase? = nullfun getDatabase(context: Context): NoteDatabase {return INSTANCE ?: synchronized(this) {val instance = Room.databaseBuilder(context.applicationContext,NoteDatabase::class.java,"note_database.db").build()INSTANCE = instanceinstance}}}
}
  • ​单例模式​​:避免重复打开数据库连接

  • @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: NoteRepositoryval 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)// 监听数据变化并更新 UIlifecycleScope.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自动处理数据差异

http://www.dtcms.com/a/318826.html

相关文章:

  • 力扣238:除自身之外数组的乘积
  • 快速开发实践
  • 使用Spring Boot + Angular构建安全的登录注册系统
  • 十八、MySQL-DML-数据操作-插入(增加)、更新(修改)、删除
  • LongVie突破超长视频生成极限:1分钟电影级丝滑视频,双模态控制告别卡顿退化
  • 本地组策略编辑器无法打开(gpedit.msc命令异常)
  • 编程之线性代数矩阵和概率论统计知识回顾
  • OpenCV 图像处理基础操作指南(一)
  • 基于人眼视觉特性的相关图像增强基础知识介绍
  • C++入门自学Day7-- String类的使用(续)
  • windows_exporter-0.13.0-amd64.exe 怎么安装?Windows服务安装与运行方法
  • 中国341个城市人力需求指数数据集
  • 【MATLAB】(十)符号运算
  • 一文读懂 C# 中的 Bitmap
  • 知识随记-----Qt 实用技巧:自定义倒计时按钮防止用户频繁点击
  • 3D 软件在游戏开发中的全链路应用:从原型到上线的实战解析
  • Docker Buildx最佳实践:多架构镜像构建指南
  • Mac/Windows跨平台PDF与AI高效解决方案
  • sigprocmask 函数深度解析
  • html页面使用jspdf预览及下载pdf模板
  • 使用驱动移除内核回调,
  • golang开源库之Syncthing
  • Unity URP渲染管线动态修改材质球状态
  • 基于 HT 引擎实现 3D 智慧物流转运中心一体化管控系统
  • 【CS创世SD NAND征文】小型夜灯为何需要存储芯片?从基础照明到智能存储的升级密码
  • 生成式AI时代,Data+AI下一代数智平台建设指南
  • EP04:【DL 第二弹】张量的线性代数运算
  • 内网穿透原理和部署教程
  • 京东关键字搜索商品列表接口开发实战:从参数优化到分布式调用
  • localforage的数据仓库、实例、storeName和name的概念和区别