繁体   English   中英

Room Dao LiveData 作为返回类型导致编译时错误

[英]Room Dao LiveData as return type causing compile time error

我使用的客房DAO实现该收益LiveData 添加了以下依赖项后,它运行良好。

implementation "androidx.room:room-runtime:2.1.0-alpha04"
kapt "androidx.room:room-compiler:2.1.0-alpha04"

但是当我添加新的 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"

下面是编译的代码

@Dao
interface AccountDao{

    @Query("SELECT * FROM account_master")
    suspend fun getAllAccounts(): List<Account>
}

下面是给出错误的代码。

@Dao
interface AccountDao{

    @Query("SELECT * FROM account_master")
    suspend fun getAllAccounts(): LiveData<List<Account>>
}

开始接收错误。

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()

任何人面临类似的问题?

我认为这里的解决方案实际上是在不使用Coroutines的情况下返回LiveData LiveData开箱即用,返回LiveData时没有理由使用Coroutines。

使用LiveData时,它已经在后台线程上处理它。 当不使用LiveData时,那么在这种情况下你可以使用Coroutines(可能最终是Coroutines Channels)或RxJava2。

请参阅此codelab以获取示例: 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)
    }
}

Room的当前实现不支持使用LiveData 协同程序 作为一种解决方法,您可以像下面这样实现它:

@Dao
interface AccountDao{

@Query("SELECT * FROM account_master")
    suspend fun getAllAccounts(): List<Account>
}

ViewModel类的实现中,您可以创建LiveData并为其分配值,从DB中检索:

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
    }
}

要使用Dispatchers.Main导入:

implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.1.1'

删除暂停功能。 LiveData已经是异步的。 无需暂停功能。

@Dao
interface AccountDao{

    @Query("SELECT * FROM account_master")
    fun getAllAccounts(): LiveData<List<Account>>
}

正如Michael Vescovo所指出的,实现异步调用有两种可能的方法:

@Dao
interface AccountDao{
    @Query("SELECT * FROM account_master")
    suspend fun getAllAccounts(): List<Account>
}

@Dao
interface AccountDao{
    @Query("SELECT * FROM account_master")
    fun getAllAccounts(): LiveData<List<Account>>
}

你将使用哪一个取决于你的用例。 例如,如果我的DAO使用者(通常是存储库)将为模型创建LiveData(在我不需要观察本地数据库的更改的情况下),我将使用第一个。

如果我需要观察本地数据库中的更改(例如,其他一些服务可以同时更新数据库),我会使用第二个。

不一样,但相似。 RoomWordSample CodeLab 运行良好,直到我更新了 Android Studio 和 Gradle 插件。

失败的代码来自 WordDao 类。 无法识别流。

@Query("SELECT * FROM word_table ORDER BY word ASC")
fun getAlphabetizedWords(): Flow<List<Word>>

我使用了以下导入,它以前有效,但在更新后失败。

import kotlinx.util.concurrent.Flow

我不得不按如下方式更改导入语句:

import kotlinx.coroutines.flow.Flow

我也进行了很多依赖项更改,但此修复可能需要更改协程。

ext {
    activityVersion = '1.4.0'
    appCompatVersion = '1.4.0'
    lifecycleVersion = '2.4.0'
    coroutines = '1.5.2'
    roomVersion = '2.3.0'
}

dependencies {

implementation "androidx.appcompat:appcompat:$rootProject.appCompatVersion"
implementation "androidx.activity:activity-ktx:$activityVersion"

// Dependencies for working with Architecture components
// You'll probably have to update the version numbers in build.gradle (Project)

// Room components
implementation "androidx.room:room-ktx:$rootProject.roomVersion"
kapt "androidx.room:room-compiler:$rootProject.roomVersion"
androidTestImplementation "androidx.room:room-testing:$rootProject.roomVersion"

implementation 'androidx.core:core-ktx:1.7.0'
implementation 'androidx.appcompat:appcompat:1.4.0'
implementation 'com.google.android.material:material:1.4.0'
implementation 'androidx.constraintlayout:constraintlayout:2.1.2'
implementation 'androidx.room:room-common:2.3.0'
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-core:1.5.2'
implementation 'androidx.room:room-ktx:2.3.0'
testImplementation 'junit:junit:4.13.2'
androidTestImplementation 'androidx.test.ext:junit:1.1.3'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'

// Lifecycle components
implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:$rootProject.lifecycleVersion"
implementation "androidx.lifecycle:lifecycle-livedata-ktx:$rootProject.lifecycleVersion"
implementation "androidx.lifecycle:lifecycle-common-java8:$rootProject.lifecycleVersion"

// Kotlin components
//implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
implementation 'org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.6.0'
api "org.jetbrains.kotlinx:kotlinx-coroutines-core:$rootProject.coroutines"
api "org.jetbrains.kotlinx:kotlinx-coroutines-android:$rootProject.coroutines"

}

另一个失败是由于缺少@Dao 注释。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM