本文主要介紹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