Ank*_*nkh 5 kotlin android-room kotlin-coroutines
我正在尝试将 @Dao 对象的所有方法转换为可挂起以供 Kotlin 协程使用。
当我将挂起修饰符添加到工作函数定义并尝试在 Android Studio 中构建时,它无法生成 XXXXDao_Impl.java 类
一个非常精简的例子:
import androidx.lifecycle.LiveData
import androidx.room.*
@Database(entities = [SomeData::class], version = 1)
abstract class SomeDatabase : RoomDatabase() {
abstract fun getDao(): SomeDataDao
}
@Entity
data class SomeData(@PrimaryKey val id: Int, val name: String)
@Dao
interface SomeDataDao {
@Query("SELECT * FROM SomeData") // Works
fun getAllSync(): List<SomeData>
@Query("SELECT * FROM SomeData") // Works
suspend fun getAllSuspend(): List<SomeData>
@Query("SELECT * FROM SomeData") // Works
fun getAllSyncLiveData(): LiveData<List<SomeData>>
@Query("SELECT * FROM SomeData") // Fails to generate code
suspend fun getAllSuspendLiveData(): LiveData<List<SomeData>>
}
Run Code Online (Sandbox Code Playgroud)
生成的代码失败:
import androidx.lifecycle.LiveData
import androidx.room.*
@Database(entities = [SomeData::class], version = 1)
abstract class SomeDatabase : RoomDatabase() {
abstract fun getDao(): SomeDataDao
}
@Entity
data class SomeData(@PrimaryKey val id: Int, val name: String)
@Dao
interface SomeDataDao {
@Query("SELECT * FROM SomeData") // Works
fun getAllSync(): List<SomeData>
@Query("SELECT * FROM SomeData") // Works
suspend fun getAllSuspend(): List<SomeData>
@Query("SELECT * FROM SomeData") // Works
fun getAllSyncLiveData(): LiveData<List<SomeData>>
@Query("SELECT * FROM SomeData") // Fails to generate code
suspend fun getAllSuspendLiveData(): LiveData<List<SomeData>>
}
Run Code Online (Sandbox Code Playgroud)
构建错误消息:
/Projects/Android/RawQuerySuspendTest/app/build/tmp/kapt3/stubs/debug/com/example/android/rawquerysuspendtest/SomeDataDao.java:24: error: Not sure how to convert a Cursor to this method's return type (androidx.lifecycle.LiveData<java.util.List<com.example.android.rawquerysuspendtest.SomeData>>).
public abstract java.lang.Object getAllSuspendLiveData(@org.jetbrains.annotations.NotNull()
Run Code Online (Sandbox Code Playgroud)
应用程序的 build.gradle
apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-android-extensions'
apply plugin: 'kotlin-kapt'
android {
compileSdkVersion 28
defaultConfig {
applicationId "com.example.android.rawquerysuspendtest"
minSdkVersion 21
targetSdkVersion 28
versionCode 1
versionName "1.0"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
}
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation"org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
implementation 'androidx.appcompat:appcompat:1.0.2'
implementation 'androidx.core:core-ktx:1.0.2'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'androidx.test:runner:1.2.0'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'
kapt "androidx.room:room-compiler:2.1.0-rc01"
implementation "androidx.room:room-runtime:2.1.0-rc01"
implementation "androidx.room:room-ktx:2.1.0-rc01"
implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.2.0-alpha01'
implementation 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.2.0-alpha01'
implementation 'androidx.lifecycle:lifecycle-livedata-ktx:2.2.0-alpha01'
implementation 'androidx.lifecycle:lifecycle-extensions:2.2.0-alpha01'
}
Run Code Online (Sandbox Code Playgroud)
我是否缺少依赖项或注释处理步骤?
当前实施间不支持协同程序用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)
| 归档时间: |
|
| 查看次数: |
3711 次 |
| 最近记录: |