Android Room是Android开发中的一个持久性库处理大量结构化数据的应用可极大地受益于在本地保留这些数据。最常见的使用场景是缓存相关的数据,这样一来,当设备无法访问网络时,用户仍然可以在离线状态下浏览该内容。
Room 持久性库在 SQLite 上提供了一个抽象层,以便在充分利用 SQLite 的强大功能的同时,能够流畅地访问数据库。主要有以下几大优点:
- 在编译时校验 SQL 语句;
- 易用的注解减少重复和易错的模板代码;
- 简化的数据库迁移路径。
为什么Android Room在Android开发中如此重要?
- 类型安全的数据库访问: Room使用注解和编译时检查,确保SQL查询的类型安全性。
- 简化数据库操作: Room大大简化了SQLite数据库的使用。它提供了高级抽象,减少了编写复杂SQL查询的需要。
- 响应式数据管理: Room与Android架构组件(如LiveData和ViewModel)集成得很好,支持响应式编程。
- 数据库迁移支持: 当应用程序需要更改数据库结构时,Room提供了方便的数据库迁移工具。
- 官方支持: Room由Google官方提供和维护,因此它与Android平台的兼容性和可维护性都得到了保证。
Room数据库的使用
(将Room与Android架构组件如LiveData和ViewModel结合使用)
Room主要包含三个组件:
- Database:其中包含数据库持有者,并作为应用已保留的持久关系型数据的底层连接的主要接入点
- Entity:用于表示数据库中的表
- Dao:包含用于访问数据库的方法
其中三个组件的关系如下图所示
编辑切换为居中
添加图片注释,不超过 140 字(可选)
添加依赖 在应用或模块的 build.gradle 文件中添加所需工件的依赖项:
dependencies {
// Room数据库依赖
def room_version = "2.2.6"
implementation "androidx.room:room-runtime:$room_version"
kapt "androidx.room:room-compiler:$room_version"
// 协程依赖
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-core:1.4.0'
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.4.0'
//LiveData和ViewModel依赖
implementation 'androidx.lifecycle:lifecycle-livedata-ktx:2.2.0'
implementation 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.2.0'
}
创建实体类
@Entity
data class Record(
@PrimaryKey(autoGenerate = true)
val id: Long = 0,
val title: String,
val content: String)
使用id作为主键,令其默认值为0,这样在插入数据库时会自动为其赋值
创建Dao接口
@Dao
interface RecordDao {
@Query("select * from record where title = :title")
fun getAllRecordsByTitle(title: String): LiveData<List<Record>>
}
这里getAllRecords()方法返回LiveData
创建Database
@Database(version = 1, entities = [Record::class])
abstract class AppDatabase : RoomDatabase() {
abstract fun recordDao(): RecordDao
companion object {
private var instance: AppDatabase? = null
// 使用单例模式
@Synchronized
fun getDatabase(context: Context): AppDatabase {
instance?.let {
return it
}
return Room.databaseBuilder(context.applicationContext,
AppDatabase::class.java, "app_database")
.build().apply { instance = this }
}
}
在创建以上几个类时,注意添加对应的注解@Entity,@Dao,@Database
2.ViewModel与LiveData的使用 在MVVM架构中,Repository承担着统筹本地存储与网络数据访问的功能,这里我们仅使用本地存储
在Repository.kt中,添加方法
object Repository {
val recordDao = AppDatabase.getDatabase(DayRecordApplication.context).recordDao()
fun getAllRecordsByTitle(title: String): LiveData<List<Record>> =
return recordDao.getAllRecordsByTitle(title)
}
在viewModel.kt中,使用Transformations进行数据的转换:
private val _record = MutableLiveData<String>()
val records: LiveData<List<Record>> = Transformations.switchMap(_records) {
Repository.getAllRecordsByTitle(it)
}
由于数据库操作是耗时操作,因此需要使用协程来进行异步操作
fun getAllRecordsByTitle(title: String) = viewModelScope.launch{
_record.value = title
}
当_record数据发生变动时,会自动通知record数据进行更新
viewModel.kt全部代码如下
class viewModel : ViewModel() {
private val _record = MutableLiveData<String>()
val records: LiveData<List<Record>> = Transformations.switchMap(_record) {
Repository.getAllRecordsByTitle(it)
}
fun getAllRecordsByTitle(title: String) = viewModelScope.launch{
_record.value = title
}
}
在Activity中,添加Observer来对LiveData进行观察
open class MainActivity : AppCompatActivity() {
private val viewModel by lazy {
ViewModelProvider(this).get(viewModel::class.java)
}
private var records = ArrayList<Record>()
private lateinit var adapter: RecordAdapter
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
adapter = RecordAdapter(requireActivity(), records)
viewModel.records.observe(this) {
// 当viewModel中的records数据更新时
// 会执行此段代码,进行UI的更新
records.clear()
records.addAll(it)
adapter.notifyDataSetChanged()
}
button.setOnClickListener {
// 通知viewModel进行数据变更
viewModel.getAllRecordsByTitle(title)
}
}
当ViewModel中的records数据进行变更时,会通知adapter进行数据变更从而更新UI。至此,Room、ViewModel、LiveData的搭配使用就完成了。文章主要讲了在Android开发的数据库Room技术中如何去使用,以及简单背景介绍。更详细的Android进阶技术可以参考《Android核心技术手册》这个模块,里面包含30多个板块上千技术点。可点击查看详情类目。
总结
Android Room是一个强大的数据库持久性解决方案,它简化了数据库访问、提供了类型安全性,并与Android架构组件集成,为Android应用程序的数据管理提供了便利性和可维护性。这让它能成为Android应用程序开发中不可或缺的工具。