Kotlin中Room的insert方法加suspend关键字报错求解决方案
在Kotlin中为Room的insertConfCard方法添加suspend关键字时遭遇编译错误,求有效解决办法
错误信息
error: Type of the parameter must be a class annotated with @Entity or a collection/array of it. kotlin.coroutines.Continuation<? super java.lang.Long> continuation);
error: Not sure how to handle insert method's return type. public abstract java.lang.Object insertConfCard(@org.jetbrains.annotations.NotNull()
Execution failed for task ':app:kaptDebugKotlin'. > A failure occurred while executing org.jetbrains.kotlin.gradle.internal.KaptWithoutKotlincTask$KaptExecutionWorkAction > java.lang.reflect.InvocationTargetException (no error message)
我的DAO代码
@Dao interface ConfCardDao { @Insert(onConflict = OnConflictStrategy.REPLACE) fun insertConfCard(confCard: ConfCard): Long }
生成的DAO代码
import java.lang.System; @androidx.room.Dao() @kotlin.Metadata(mv = {1, 7, 1}, k = 1, d1 = {"\u0000\u0018\n\u0002\u0018\u0002\n\u0002\u0010\u0000\n\u0000\n\u0002\u0010\t\n\u0000\n\u0002\u0018\u0002\n\u0002\b\u0002\bg\u0018\u00002\u00020\u0001J\u0019\u0010\u0002\u001a\u00020\u00032\u0006\u0010\u0004\u001a\u00020\u0005H\u00a7@\u00f8\u0001\u0000\u00a2\u0006\u0002\u0010\u0006\u0082\u0002\u0004\n\u0002\b\u0019\u00a8\u0006\u0007"}, d2 = {"Lcom/example/stid_settings_kotlin/datamodel/data/local/ConfCardDao;", "", "insertConfCard", "", "confCard", "Lcom/example/stid_settings_kotlin/datamodel/data/local/ConfCard;", "(Lcom/example/stid_settings_kotlin/datamodel/data/local/ConfCard;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;", "app_debug"}) public abstract interface ConfCardDao { @org.jetbrains.annotations.Nullable() @androidx.room.Insert(onConflict = androidx.room.OnConflictStrategy.REPLACE) public abstract java.lang.Object insertConfCard(@org.jetbrains.annotations.NotNull() com.example.stid_settings_kotlin.datamodel.data.local.ConfCard confCard, @org.jetbrains.annotations.NotNull() kotlin.coroutines.Continuation<? super java.lang.Long> continuation); }
app模块build.gradle依赖配置
dependencies { implementation 'androidx.core:core-ktx:1.7.0' implementation 'androidx.appcompat:appcompat:1.5.1' implementation 'com.google.android.material:material:1.7.0' implementation 'androidx.constraintlayout:constraintlayout:2.1.4' testImplementation 'junit:junit:4.13.2' androidTestImplementation 'androidx.test.ext:junit:1.1.3' androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0' // Retrofit implementation 'com.squareup.retrofit2:retrofit:2.9.0' implementation 'com.squareup.retrofit2:converter-gson:2.9.0' // implementation "com.squareup.okhttp3:okhttp:4.9.0" // Coroutines implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-core:1.6.1' implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.6.1' // Coroutine Lifecycle Scopes implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:2.5.1" implementation "androidx.lifecycle:lifecycle-runtime-ktx:2.5.1" // Room implementation "androidx.room:room-runtime:2.3.0" kapt "androidx.room:room-compiler:2.3.0" // optional - Kotlin Extensions and Coroutines support for Room -- use room with coroutine implementation "androidx.room:room-ktx:2.3.0" }
项目根目录build.gradle
plugins { id 'com.android.application' version '7.2.0' apply false id 'com.android.library' version '7.2.0' apply false id 'org.jetbrains.kotlin.android' version '1.7.10' apply false } task clean(type: Delete) { delete rootProject.buildDir }
实体类ConfCard代码
@Entity(tableName = "confcard", indices = [Index(value = ["confName"], unique = true)]) class ConfCard { @PrimaryKey(autoGenerate = true) var id: Int = 0 @NotNull var confName: String @NotNull var name: String @NotNull var pid: String @NotNull var pver: String @NotNull var data: String @NotNull var kNew: String @NotNull var kCur: String @NotNull var uuid: String @NotNull var type: String // ScbvsOCB @NotNull var tkNeeded: String @NotNull var originatingServer: String constructor() { this.id = 0 this.confName = "" this.name = "" this.pid = "" this.pver = "" this.data = "" this.kNew = "" this.kCur = "" this.uuid = "" this.type = "" this.originatingServer = "" this.tkNeeded = "" } constructor( ConfName: String, Name: String, PartId: String, PartVer: String, Data: String, KNew: String, KCur: String, UUID: String, CardType: String, OriginatingServer: String, TkNeeded: String, ) { this.confName = ConfName this.name = Name this.pid = PartId this.pver = PartVer this.data = Data this.kNew = KNew this.kCur = KCur this.uuid = UUID this.type = CardType this.originatingServer = OriginatingServer this.tkNeeded = TkNeeded } @JvmName("getId1") fun getId(): Int = id @JvmName("setId1") fun setId(id: Int) { this.id = id } @JvmName("getConfName1") fun getConfName(): String = confName @JvmName("setConfName1") fun setConfName(confName: String) { this.confName = confName } @JvmName("getName1") fun getName(): String = name @JvmName("setName1") fun setName(name: String) { this.name = name } fun getPartId(): String = pid fun setPartId(pid: String) { this.pid = pid } fun getPartVer(): String = pver fun getPartVer(pver: String) { this.pver = pver } @JvmName("getData1") fun getData(): String = data @JvmName("setData1") fun setData(data: String) { this.data = data } @JvmName("getKNew1") fun getKNew(): String = kNew @JvmName("setKNew1") fun setKNew(kNew: String) { this.kNew = kNew } @JvmName("getKCur1") fun getKCur(): String = kCur @JvmName("setKCur1") fun setKCur(kCur: String) { this.kCur = kCur } fun getUUID(): String = uuid fun setUUID(uuid: String) { this.uuid = uuid } fun getCardType(): String = type fun setCardType(type: String) { this.type = type } @JvmName("getOriginatingServer1") fun getOriginatingServer(): String = originatingServer @JvmName("setOriginatingServer1") fun setOriginatingServer(originatingServer: String) { this.originatingServer = originatingServer } @JvmName("getTkNeeded1") fun getTkNeeded(): String = tkNeeded @JvmName("setTkNeeded1") fun setTkNeeded(tkNeeded: String) { this.tkNeeded = tkNeeded } }
解决办法
1. 修复实体类中的方法错误
实体类ConfCard里的getPartVer方法存在定义错误,把原本的setter写成了getter,导致Room无法正确解析实体字段:
// 错误写法 fun getPartVer(pver: String) { this.pver = pver } // 改为正确的setter fun setPartVer(pver: String) { this.pver = pver }
2. 升级Room版本以兼容Kotlin版本
当前使用的Room 2.3.0与Kotlin 1.7.10版本不兼容,Room从2.4.0开始才更好地支持Kotlin 1.6+版本。建议将Room相关依赖升级到稳定兼容版本,比如2.5.0:
// Room implementation "androidx.room:room-runtime:2.5.0" kapt "androidx.room:room-compiler:2.5.0" implementation "androidx.room:room-ktx:2.5.0"
3. 正确添加suspend关键字到DAO方法
修改DAO代码,在方法前添加suspend关键字,Room的ktx扩展会自动处理协程逻辑:
@Dao interface ConfCardDao { @Insert(onConflict = OnConflictStrategy.REPLACE) suspend fun insertConfCard(confCard: ConfCard): Long }
4. 清理并重新构建项目
执行Android Studio中的Clean Project,然后Rebuild Project,清除kapt生成的旧代码缓存,避免残留代码导致编译错误。
内容的提问来源于stack exchange,提问作者Ahmer Iqbal
相关产品推荐
相关产品推荐

