![](/img/trans.png)
[英]how to use Authenticator with suspend api function? Retrofit
[英]How to use suspend function on Room Db?
我在 kotlin 中使用協程使用 Room Db。 這是我的道界面:
@Dao
interface CheckListNameDao {
@Insert
suspend fun insertName(name: CheckListName)
@Query("SELECT * FROM CheckListNamesTable")
fun getAllNames(): LiveData<List<CheckListName>>
}
getAllNames()
方法工作正常。 問題在於insertName()
方法。 當我從insertName()
方法中刪除suspend
關鍵字時,它會引發此異常: java.lang.IllegalStateException: Cannot access database on the main thread since it may potentially lock the UI for a long period of time.
但是,當我使用suspend
關鍵字時,我無法再構建項目。 它顯示以下錯誤:
error: Methods annotated with @Insert can return either void, long, Long, long[], Long[] or List<Long>.
public abstract java.lang.Object insertName(@org.jetbrains.annotations.NotNull()
為什么顯示此錯誤? 我的代碼基於這個帶有視圖的 Android Room - Kotlin
編輯:這是我的存儲庫:
class MainRepository(application: Application) {
private var nameDao: CheckListNameDao = AppDatabase.getDatabase(application.applicationContext)
.checkListNameDao()
fun getAllNames(): LiveData<List<CheckListName>> {
return nameDao.getAllNames()
}
suspend fun setNewListName(checkListName: CheckListName) {
nameDao.insertName(checkListName)
}
}
這是視圖模型:
class MainViewModel(application: Application) : AndroidViewModel(application) {
private var mainRepository = MainRepository(application)
fun getAllNames(): LiveData<List<CheckListName>> {
return mainRepository.getAllNames()
}
fun setNewListName(name: String) {
viewModelScope.launch {
mainRepository.setNewListName(CheckListName(0, name))
}
}
}
編輯2:
添加suspend
關鍵字時,我也收到此錯誤:
error: Type of the parameter must be a class annotated with @Entity or a collection/array of it.
kotlin.coroutines.Continuation<? super kotlin.Unit> p1);
這是CheckListName
數據類:
@Entity(tableName = "CheckListNamesTable")
data class CheckListName(
@PrimaryKey(autoGenerate = true)
var id: Int,
var name: String
)
根據Room Declaring Dependencies 文檔,您需要對room-ktx
的依賴才能使用協程,並使用suspend
方法:
implementation "androidx.room:room-ktx:2.2.3"
編輯:您的代碼是正確的,它可以用於具有掛起功能的房間數據庫。 只需像下面這樣編輯您的 Gradle 依賴項即可修復該錯誤。
如果您使用 kotlin 版本 ( 1.7.0 ) 應該使用房間最新的 alpha 版本 ( 2.5.0-alpha02 )
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:1.7.0"
implementation "androidx.room:room-runtime:2.5.0-alpha02"
implementation "androidx.room:room-ktx:2.5.0-alpha02"
kapt "androidx.room:room-compiler:2.5.0-alpha02"
如果你想在穩定版本( 2.4.2 )中使用房間,應該使用 kotlin 版本( 1.6.20 )
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:1.6.20"
implementation "androidx.room:room-runtime:2.4.2"
implementation "androidx.room:room-ktx:2.4.2"
kapt "androidx.room:room-compiler:2.4.2"
我都試過了,它們都有效。 這是參考:問題跟蹤器
以下代碼片段包含一個示例數據庫配置,其中包含一個實體和一個 DAO:
@Entity
data class User(
@PrimaryKey val uid: Int,
@ColumnInfo(name = "first_name") val CheckListName: String?,
)
我在 kotlin 中使用協同程序使用 Room Db。 這是我的 Dao 界面:
@Dao
interface CheckListNameDao {
@Insert
suspend fun insertName(name: CheckListName)
@Query("SELECT * FROM CheckListNamesTable")
fun getAllNames(): LiveData<List<CheckListName>>
}
getAllNames()
方法工作正常。 問題出在insertName()
方法上。 當我從insertName()
方法中刪除suspend
關鍵字時,它會拋出以下異常: java.lang.IllegalStateException: Cannot access database on the main thread since it may potentially lock the UI for a long period of time.
但是,當我使用suspend
關鍵字時,我無法再構建項目。 它顯示以下錯誤:
error: Methods annotated with @Insert can return either void, long, Long, long[], Long[] or List<Long>.
public abstract java.lang.Object insertName(@org.jetbrains.annotations.NotNull()
為什么會顯示這個錯誤? 我的代碼基於此Android Room with a View - Kotlin
編輯:這是我的存儲庫:
class MainRepository(application: Application) {
private var nameDao: CheckListNameDao = AppDatabase.getDatabase(application.applicationContext)
.checkListNameDao()
fun getAllNames(): LiveData<List<CheckListName>> {
return nameDao.getAllNames()
}
suspend fun setNewListName(checkListName: CheckListName) {
nameDao.insertName(checkListName)
}
}
這是視圖模型:
class MainViewModel(application: Application) : AndroidViewModel(application) {
private var mainRepository = MainRepository(application)
fun getAllNames(): LiveData<List<CheckListName>> {
return mainRepository.getAllNames()
}
fun setNewListName(name: String) {
viewModelScope.launch {
mainRepository.setNewListName(CheckListName(0, name))
}
}
}
編輯2:
添加suspend
關鍵字時,我也收到此錯誤:
error: Type of the parameter must be a class annotated with @Entity or a collection/array of it.
kotlin.coroutines.Continuation<? super kotlin.Unit> p1);
這是CheckListName
數據類:
@Entity(tableName = "CheckListNamesTable")
data class CheckListName(
@PrimaryKey(autoGenerate = true)
var id: Int,
var name: String
)
暫停在 Room DAO 中不起作用,quires 返回 LiveData 並且 Kotlin 版本高於:1.4.32
更多請看這里: 鏈接
只改變你的樂趣:
@Insert(onConflict = OnConflictStrategy.REPLACE)
suspend fun insertName(name: CheckListName) : Long
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.