Pin*_*kin 10 android android-room android-architecture-components kotlin-coroutines
我正在使用Room并实现了Dao,它返回了LiveData
。添加下面的依赖关系,它工作正常。
implementation "androidx.room:room-runtime:2.1.0-alpha04"
kapt "androidx.room:room-compiler:2.1.0-alpha04"
Run Code Online (Sandbox Code Playgroud)
但是,当我添加新的Room协程依赖性时,如下所述。
implementation "androidx.room:room-runtime:2.1.0-alpha04"
implementation "androidx.room:room-coroutines:2.1.0-alpha04"
kapt "androidx.room:room-compiler:2.1.0-alpha04"
Run Code Online (Sandbox Code Playgroud)
下面是编译的代码
@Dao
interface AccountDao{
@Query("SELECT * FROM account_master")
suspend fun getAllAccounts(): List<Account>
}
Run Code Online (Sandbox Code Playgroud)
下面是给出错误的代码。
@Dao
interface AccountDao{
@Query("SELECT * FROM account_master")
suspend fun getAllAccounts(): LiveData<List<Account>>
}
Run Code Online (Sandbox Code Playgroud)
开始收到错误。
PlayGround/app/build/tmp/kapt3/stubs/debug/com/playground/www/x/datasource/dao/AccountDao.java:11: error: Not sure how to convert a Cursor to this method's return type (androidx.lifecycle.LiveData<java.util.List<com.playground.www.x.datasource.entity.Account>>).
public abstract java.lang.Object getAllAccounts(@org.jetbrains.annotations.NotNull()
Run Code Online (Sandbox Code Playgroud)
有人面临类似问题吗?
mit*_*tch 14
删除挂起功能。LiveData 已经是异步的。不需要挂起功能。
@Dao
interface AccountDao{
@Query("SELECT * FROM account_master")
fun getAllAccounts(): LiveData<List<Account>>
}
Run Code Online (Sandbox Code Playgroud)
Mic*_*ovo 11
我认为这里的解决方案实际上是不使用Coroutines就返回LiveData。LiveData开箱即用,返回LiveData时无需使用协程。
使用LiveData时,它已经在后台线程上对其进行了处理。当不使用LiveData时,在这种情况下,您可以使用协程(可能最终是协程通道)或RxJava2。
有关示例,请参见此代码实验室:https : //codelabs.developers.google.com/codelabs/android-room-with-a-view-kotlin。在这里,它们需要用于插入的后台线程,而不需要用于返回的LiveData的后台线程。
注意:在实际的代码实验室中,DAO没有返回LiveData似乎是一个错误。我已在下面的示例中对此进行了更正。
@Dao
interface WordDao {
@Query("SELECT * from word_table ORDER BY word ASC")
fun getAllWords(): LiveData<List<Word>>
@Insert
suspend fun insert(word: Word)
@Query("DELETE FROM word_table")
fun deleteAll()
}
class WordRepository(private val wordDao: WordDao) {
val allWords: LiveData<List<Word>> = wordDao.getAllWords()
@WorkerThread
suspend fun insert(word: Word) {
wordDao.insert(word)
}
}
Run Code Online (Sandbox Code Playgroud)
Room的当前实现不支持带有的协程LiveData
。作为一种解决方法,您可以像下面这样实现:
@Dao
interface AccountDao{
@Query("SELECT * FROM account_master")
suspend fun getAllAccounts(): List<Account>
}
Run Code Online (Sandbox Code Playgroud)
在ViewModel
类的实现中,您可以创建类LiveData
并为其分配一个值,该值可以从数据库中检索:
class MainViewModel : ViewModel() {
private val dao: AccountDao = ...// initialize it somehow
private var job: Job = Job()
private val scope = CoroutineScope(job + Dispatchers.Main)
lateinit var accounts: MutableLiveData<List<Account>>
override fun onCleared() {
super.onCleared()
job.cancel()
}
fun getAccounts(): LiveData<List<Account>> {
if (!::accounts.isInitialized) {
accounts = MutableLiveData()
scope.launch {
accounts.postValue(dao.getAllAccounts())
}
}
return accounts
}
}
Run Code Online (Sandbox Code Playgroud)
要使用Dispatchers.Main
导入:
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.1.1'
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
2237 次 |
最近记录: |