如何从Room获取LiveData? [英] How to get LiveData from Room?

查看:147
本文介绍了如何从Room获取LiveData?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试从Room获取LiveData.因此,如果数据库中的任何内容发生更改,我的RecycleView都可以进行实时更新

I'm trying to get LiveData from Room. So my RecycleView can have Live updates if anything in database is changed

我已经尝试使用LiveData了,并且可以使用,但是当我添加总是显示此错误的LiveData时.

I have tried with out LiveData and that works, but when i add LiveData that always shows this error.

error: Not sure how to convert a Cursor to this method's return type     (androidx.lifecycle.LiveData<java.util.List<com.example.models.Club>>).
public abstract java.lang.Object     getAll(@org.jetbrains.annotations.NotNull()

我用谷歌搜索并在该站点上寻找解决方案,但是每一个遇到此问题的人都使用过rxjava,rxandroid,rxkotlin或ArrayList. 对于他们来说,解决方案是用List替换ArrayList,让RX尝试协程. 好吧,我正在使用协程和列表,仍然没有进展.

I googled and looked on this site for solution, but every on with this issue have used rxjava, rxandroid, rxkotlin or ArrayList. And for them solution is to replace ArrayList with List, and for RX to try coroutine. Well i am using Coroutine and List and still no progress.

这是我的ClubDao

This is my ClubDao

ClubDao
@Query("SELECT * FROM club")
suspend fun getAll(): LiveData<List<Club>>

在俱乐部中,我具有此属性

In Club i have this attributes

Club
@Entity
data class Club(@PrimaryKey var id: Int,
            @ColumnInfo(name = "logo_url") var logoUrl: String,
            @ColumnInfo(name = "name") var name: String,
            @ColumnInfo(name = "town") var town: String,
            @ColumnInfo(name = "address") var address: String,
            @ColumnInfo(name = "contact_name") var contactName: String,
            @ColumnInfo(name = "phone_numbers") var phoneNumbers: String,
            @ColumnInfo(name = "email") var email: String)

phoneNumbers应该是List,但是我使用TypeConverters将它们与json相互转换

phoneNumbers should be List, but i convert those to and from json with TypeConverters

TypeConverter在这里

TypeConverter is here

TypeConverter
class ConvertersDB {
    @TypeConverter
    fun fromString(value: String): ArrayList<String> {
        val listType = object : TypeToken<ArrayList<String>>() {

        }.type
        return Gson().fromJson(value, listType)
    }

    @TypeConverter
    fun fromArrayList(list: ArrayList<String>): String {
        val gson = Gson()
        return gson.toJson(list)
    }
}

还有我的数据库

DataBase
@Database(entities = [Club::class], version = 1, exportSchema = false)
@TypeConverters(ConvertersDB::class)
abstract class AppDatabase : RoomDatabase() {
    abstract fun clubDao(): ClubDao

    companion object {
        @Volatile
        private var instance: AppDatabase? = null
        private val LOCK = Any()

        operator fun invoke(context: Context) = instance ?: synchronized(LOCK) {
            instance ?: buildDatabase(context).also { instance = it }
        }

        private fun buildDatabase(context: Context) = Room.databaseBuilder(context,
                AppDatabase::class.java, "pss.db")
                .allowMainThreadQueries()
                .build()
    }
}

在我的片段中,我需要通过ViewModel和Repository从数据库中观察所有俱乐部,并将它们发送到RecycleView

In my fragment i need to observe all the clubs from database via ViewModel and Repository and send them to RecycleView

现在我遇到了错误:

error: Not sure how to convert a Cursor to this method's return type     (androidx.lifecycle.LiveData<java.util.List<com.example.models.Club>>).
public abstract java.lang.Object     getAll(@org.jetbrains.annotations.NotNull()

有人知道解决方案吗?

Gradle
apply plugin: 'com.android.application'
apply plugin: 'androidx.navigation.safeargs'
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-android-extensions'
apply plugin: 'kotlin-kapt'


android {
    compileSdkVersion 28
    defaultConfig {
        applicationId "com.overswayit.plesnisavezsrbije"
        minSdkVersion 24
        targetSdkVersion 28
        versionCode 1
        versionName "1.0"
        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
    compileOptions {
        sourceCompatibility JavaVersion.VERSION_1_8
        targetCompatibility JavaVersion.VERSION_1_8
    }
    dataBinding {
        enabled true
    }
    packagingOptions {
        exclude 'META-INF/atomicfu.kotlin_module'
    }
}

dependencies {
    implementation fileTree(dir: 'libs', include: ['*.jar'])
    implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.3.31"
    implementation 'com.jakewharton:butterknife:10.1.0'
    implementation 'com.google.android.material:material:1.1.0-alpha07'
    implementation 'androidx.cardview:cardview:1.0.0'
    implementation 'androidx.appcompat:appcompat:1.1.0-beta01'
    implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
    implementation 'androidx.legacy:legacy-support-v4:1.0.0'

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

    // Room and RxJava
    implementation "androidx.room:room-rxjava2:$rootProject.roomVersion"

    // Lifecycle components
    implementation "androidx.lifecycle:lifecycle-extensions:$rootProject.archLifecycleVersion"
    kapt "androidx.lifecycle:lifecycle-compiler:$rootProject.archLifecycleVersion"
    androidTestImplementation "androidx.arch.core:core-testing:$rootProject.androidxArchVersion"

    // ViewModel Kotlin support
    implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:$rootProject.archLifecycleVersion"

    //LiveData Kotlin
    implementation "androidx.lifecycle:lifecycle-livedata:$rootProject.archLifecycleVersion"
    implementation "androidx.lifecycle:lifecycle-livedata-ktx:$rootProject.archLifecycleVersion"

    implementation "androidx.lifecycle:lifecycle-runtime-ktx:$rootProject.archLifecycleVersion"

    // Coroutines
    api "org.jetbrains.kotlinx:kotlinx-coroutines-core:$rootProject.coroutines"
    api "org.jetbrains.kotlinx:kotlinx-coroutines-android:$rootProject.coroutines"

    //RxJava
    implementation 'io.reactivex.rxjava2:rxandroid:2.1.1'
    implementation "io.reactivex.rxjava2:rxjava:2.2.6"
    implementation 'com.jakewharton.rxbinding3:rxbinding:3.0.0-alpha2'

    implementation "org.jetbrains.kotlin:kotlin-stdlib:1.3.31"
    annotationProcessor 'com.jakewharton:butterknife-compiler:10.1.0'
    implementation 'com.squareup.picasso:picasso:2.71828'
    implementation 'com.kaopiz:kprogresshud:1.0.5'
    implementation 'com.squareup:otto:1.3.8'
    implementation 'agency.tango.android:avatar-view:0.0.2'
    implementation 'agency.tango.android:avatar-view-picasso:0.0.2'
    implementation 'com.mikhaellopez:circularimageview:3.2.0'
    implementation 'com.googlecode.libphonenumber:libphonenumber:8.1.0'

    // Data Binding
    kapt "com.android.databinding:compiler:3.1.4"

    testImplementation 'junit:junit:4.12'
    androidTestImplementation 'androidx.test:runner:1.2.0'
    androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'
    implementation project(path: ':tuple')

    // Navigation Component
    implementation 'androidx.navigation:navigation-fragment-ktx:2.0.0'
    implementation 'androidx.navigation:navigation-ui-ktx:2.0.0'

    //Gson
    implementation 'com.google.code.gson:gson:2.8.5'
}

kapt {
    generateStubs = true
}

顶级摇篮

buildscript {

    repositories {
        google()
        jcenter()
    }
    dependencies {
        classpath 'com.android.tools.build:gradle:3.4.1'
        classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:1.3.31"
        classpath "android.arch.navigation:navigation-safe-args-gradle-plugin:1.0.0"


        // NOTE: Do not place your application dependencies here; they belong
        // in the individual module build.gradle files
    }
}

allprojects {
    repositories {
        google()
        jcenter()
    }
}

task clean(type: Delete) {
    delete rootProject.buildDir
}

ext {
    roomVersion = '2.1.0'
    archLifecycleVersion = '2.2.0-alpha01'
    androidxArchVersion = '2.0.0'
    coroutines = '1.2.0'
}

推荐答案

如注释中所述,删除suspend. 当一个方法返回一个可观察对象时,没有理由将其挂起,因为它只返回对象,并且在观察到该对象之前不会运行任何查询.

As mentioned in the comments, remove suspend. When a method returns an observable, there is no reason to make it suspend since it just returns and object, does not run any query until it is observed.

@Query("SELECT * FROM club")
fun getAll(): LiveData<List<Club>>

Room的协程集成带来了返回挂起值的功能,但是当值本身为asnyc时,就没有理由使用它了.

Room's coroutines integration brings ability to return suspend values but when the value itself is asnyc, there is no reason to use it.

这篇关于如何从Room获取LiveData?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆