本文主要介绍room数据库配合其它Library的使用介绍,基本用法请查看Android Jetpack ROOM数据库用法介绍 java
room
数据库默认不容许在ui线程
操做数据库react
好比查询数据只能先建立一个子线程操做android
@Dao
abstract class UserDao {
@Query("select * from tab_user")
abstract fun getAll(): List<User>
}
class RoomActivity : AppCompatActivity() {
private var adapter: RoomAdapter? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_room)
title = "Room Example"
AppDataBase.getInstance().mockData()
initRecyclerView()
}
fun queryUser(view: View) {
loadUser()
}
private fun loadUser() {
//必须在子线程操做
Thread {
val data = AppDataBase.getInstance().userDao().getAll()
runOnUiThread {
adapter?.data = data
}
}.start()
}
...
}
复制代码
固然能够调用allowMainThreadQueries()
方法改变room
数据库的默认配置,容许在ui线程
查询数据,但我的强烈不建议这么作git
可使用如下几种方式操做数据库github
首先添加LiveData
须要的相关依赖(通常下面的依赖会自动导入)数据库
implementation "androidx.lifecycle:lifecycle-runtime:2.0.0"
implementation "androidx.lifecycle:lifecycle-extensions:2.0.0"
kapt "androidx.lifecycle:lifecycle-compiler:2.0.0"
复制代码
而后将Dao
层抽象方法的返回值改为LiveData<T>
ide
@Dao
abstract class UserDao {
@Query("select * from tab_user")
abstract fun getAll(): LiveData<List<User>>
}
复制代码
在activity中的使用以下post
class RoomActivity : AppCompatActivity() {
...
private fun loadUser() {
AppDataBase.getInstance().userDao().getAll().observe(this, Observer {
adapter!!.data = it
})
}
...
}
复制代码
UserDao
的getAll()
方法返回的是一个RoomTrackingLiveData
(继承LiveData
)对象, 当你调用observe
方法的时候, 会在LiveData
的onActive()
回调中执行查询操做,会使用AppDataBase
的QueryExecutor
(默认是大小为4的线程池)对象在子线程中执行查询操做,查询完成以后,会经过LiveData
的postValue(value)
方法将结果在主线程中通知到你的Observer
回调ui
因为LiveData
的observe
会绑定Activity
的生命周期,因此它还有一个优点是 只会在界面可见的时候才会把数据回调给你 去刷新uithis
若是你不须要绑定activity
生命周期,可调用observeForever()
方法
AppDataBase.getInstance().userDao().getAll().observeForever {
adapter!!.data = it
}
复制代码
若是你关心结合MVVM
的具体用法,请参考googlesamples
的 android-architecture-components 的 BasicSample
项目
首先添加rxjava2
须要的相关依赖
implementation "androidx.room:room-rxjava2:2.1.0"
implementation "io.reactivex.rxjava2:rxjava:2.2.10"
implementation "io.reactivex.rxjava2:rxandroid:2.1.1"
复制代码
而后将Dao
层抽象方法的返回值改为Flowable<T>
@Dao
abstract class UserDao {
@Query("select * from tab_user")
abstract fun getAll(): Flowable<List<User>>
}
复制代码
在activity中的使用以下
class RoomActivity : AppCompatActivity() {
...
AppDataBase.getInstance().userDao().getAll()
.observeOn(AndroidSchedulers.mainThread())
.subscribe({
adapter!!.data = it
}, {
Log.i("TAG", "error")
})
...
}
复制代码
结合rxjava2
使用也不须要手动建立子线程去执行查询操做,只须要将返回值定义成Flowable
,当执行subscribe
方法的时候,里面会自动使用AppDataBase
的QueryExecutor
(默认是大小为4的线程池)对象在子线程中执行查询操做,而后通知给观察者,因为使用了observeOn指定了观察者的回调线程是在主线程,因此最后的回调在主线程中
若是你对rxjava
很是了解,相信结合rxjava
的各类操做符,会更加方便你处理更加复杂的业务场景
详细的结合rxjava2
的用法,请参考googlesamples
的 android-architecture-components 的 BasicRxJavaSampleKotlin
项目和BasicRxJavaSample
项目
首先添加guava
须要的相关依赖
implementation "androidx.room:room-guava:2.1.0"
implementation "com.google.guava:guava:28.0-android"
复制代码
而后将Dao
层抽象方法的返回值改为ListenableFuture<T>
@Dao
abstract class UserDao {
@Query("select * from tab_user")
abstract fun getAll(): ListenableFuture<List<User>>
}
复制代码
在activity中的使用以下
class RoomActivity : AppCompatActivity() {
...
Futures.addCallback(AppDataBase.getInstance().userDao().getAll(), object: FutureCallback<List<User>> {
override fun onSuccess(result: List<User>?) {
runOnUiThread {
adapter!!.data = result!!
}
}
override fun onFailure(t: Throwable) {
}
}, MoreExecutors.directExecutor())
...
}
复制代码
结合guava使用也是会使用AppDataBase
的QueryExecutor
(默认是大小为4的线程池)对象在子线程中执行查询操做,经过使用Futures
的addCallback
的静态方法添加 FutureCallback
回调 获取查询结果,可是因为没办法直接指定在主线程中执行回调,因此必须手动调用runOnUiThread
方法在主线程刷新ui