方法是哪个?“不确定如何将游标转换为此方法的返回类型”的房间:

116
Error:Not sure how to convert a Cursor to this method's return type
Error:Execution failed for task ':app:compileDebugJavaWithJavac'.
Compilation failed; see the compiler error output for details.

使用 Room 时,我遇到了这个错误,我想找出是哪个方法导致的。

我有多个 DAO,总共大约有60个方法,在添加一个方法后出现了这个错误(复制并粘贴自另一个完美工作的方法,只更改了字段)。

我可以发布整个 DAO 类,但是我要求知道失败的方法。 我尝试过使用 Run with --stacktraceRun with --info--debug option,但这些都没有显示任何有价值的信息。

我添加的方法是一个具有 @Query UPDATEInt 返回类型的方法,如文档所建议。

UPDATE 或 DELETE 查询可以返回 void 或 int。 如果它是 int,则该值是此查询影响的行数。

编辑:我想补充说明,我尝试删除该方法,将 DAO 恢复到正常状态,但仍会出现此错误。

编辑2:添加 Gradle 控制台输出,因为在注释中无法阅读:

error: Not sure how to convert a Cursor to this method's return type
error: Not sure how to convert a Cursor to this method's return type
2 errors

:app:compileDebugJavaWithJavac FAILED

FAILURE: Build failed with an exception.

* What went wrong:
Execution failed for task ':app:compileDebugJavaWithJavac'.
Compilation failed; see the compiler error output for details.

* Try:
Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output.

* Get more help at https://help.gradle.org

BUILD FAILED in 22s

1
Gradle控制台中的完整错误消息是什么? - pskink
@pskink将完整的错误信息添加到了问题中。 - David Corsalini
1
这是我的方法,它可以编译通过:@Query("SELECT * FROM user") LiveData<List<User>> loadUsers(); 当我将 List 更改为 Vector 时,例如:LiveData<Vector<User>> loadUsers(); 我会得到以下错误信息:在 Android Studio 的 Gradle Console 窗口中显示了行位置 UserDao.java:19,并打印出了错误的方法,错误信息为 error: Not sure how to convert a Cursor to this method's return type。更多信息请参见 https://developer.android.com/studio/run/index.html#gradle-console。 - pskink
1
我正在使用 Kotlin 进行构建,也许这就是为什么我不理解这一行的原因? - David Corsalini
5
今天我遇到了相同的问题(返回类型是rxjava2 Observable)。错误消息中没有任何关于问题所在的信息。我希望Google能够使错误消息更加详细。至少应该打印出方法名称或期望的返回类型... - ntoskrnl
显示剩余6条评论
32个回答

154

最近我遇到了同样的问题,但我是在Dao函数内使用协程,例如:

@Query("SELECT * FROM Dummy")
suspend fun get(): LiveData<List<Dummy>>

在删除了suspend之后,一切都顺利编译通过了。返回LiveData时不需要它。截至目前为止,suspendLiveData似乎不能一起使用。


3
为了支持Co-routines,我添加了implementation "androidx.room:room-coroutines:${versions.room}"依赖项,但是构建失败并显示错误信息:**`ERROR: Failed to resolve: androidx.room:room-coroutines:2.2.1'**。 - iCantC
5
这是我的问题。当返回 LiveData 时,不应该使用挂起函数,因为它们不兼容(也不需要)。 - E.T.
1
@iCantC 你可以直接导入 implementation "androidx.room:room-ktx:$room_version",这是集成 Room 协程支持的最新变体。还可以参考官方文档:https://developer.android.com/jetpack/androidx/releases/room - Jeehut
5
请注意,“room-coroutines”已在版本2.1.0-alpha05中更名为“room-ktx”。但是,我在我的项目中已经使用了这个版本,但它并没有解决错误。根据这个答案的建议删除suspend确实为我解决了错误。 - tytk
你的回答救了我的一天。通过阅读Android文档,我将我的DAO函数转换为挂起函数。现在我需要将它转换回非挂起函数。 - Antroid
显示剩余2条评论

87

我在这个问题上花了一整天的时间,解决方案非常简单。我以前使用的是类似于以下内容的东西

@Query("SELECT * FROM myTable")
fun getAll(): MutableLiveData<ArrayList<myData>>

现在当我将 ArrayList 更改为 List,MutableLiveData 更改为 LiveData 时,它可以正常工作。

@Query("SELECT * FROM myTable")
fun getAll(): LiveData<List<myData>>

根据此问题的答案和评论,我认为房间只支持List和LiveData,因为我已经尝试过MutableLiveData和ArrayList,但没有一个组合起来能用。

希望这会帮助一些人节省几个小时。


1
我在以下代码中遇到了相同的错误: @Query("SELECT * FROM category_table") LiveData<List<Category>> getCategories(); - Shubham Anand
2
这是因为Room将拥有自己的List类型,而不是ArrayList。您应该始终引用List作为您的类型,唯一使用ArrayList直接进行构建。 - Brill Pappin
34
在我的情况下,我正在使用“暂停(suspend)”。 - Jorge Casariego
9
如果你在使用LiveData或Flow时结合了suspend,你会遇到相同的错误。 - iboalali
哦我的天,挂起(suspend)是我的问题所在,谢谢@jorg。 - rysv
这个问题可能有很多原因,我的情况是更新了Kotlin到1.5。当我回退到1.4.32时,问题消失了。 - Chapz

55
对于任何来到这里的人,如果你意外地让函数挂起,使用协程 Flow作为返回类型,你将会得到这个错误。由于它正在返回一个Flow,所以没有必要挂起。
因此,不要这样做:
@Query("SELECT * FROM myTable WHERE id = :id")
suspend fun findById(id: Long): Flow<MyDataType>

使用此代码(不带suspend修饰符):

@Query("SELECT * FROM myTable WHERE id = :id")
fun findById(id: Long): Flow<MyDataType> 

7
你拯救了我的一天! - Jonas
1
@gMale 由于它不再是一个暂停的函数,我在收集“Flow”时是否应该调用.flowOn(Dispatchers.IO) - theapache64
即使不返回Flow,我仍然遇到了相同的错误。看起来与挂起函数有关的一个bug,它曾经是可以工作的。 - Allan Veloso
但当我将“kapt”替换为“ksp”时,问题得到了解决。因此,如果使用Kotlin挂起函数,请使用“ksp”。 - Allan Veloso
1
@theapache64,回复晚了,你可能现在已经知道了,但对于未来的读者来说,没有理由使用flowOn标记函数。如果API返回的Flow尚未在任何线程/调度程序池上运行以进行安全使用,则设计将非常糟糕,就像API公开必须在特定调度程序上调用才能安全使用的挂起函数一样(这违反了编码约定)。Room正确处理这两种情况并在内部使用正确的调度程序。 - Tenfour04
@Tenfour04 ack.. - theapache64

39

根据您在评论中提到的内容,您不允许在Dao内更改返回类型为List以外的任何内容。我猜测Room不知道如何处理其他返回类型。请在Dao外部获取List并将其转换为所需的类型。


14

与 Kotlin 的 @Metadata 注释的更改相关的问题,以及 Room 读取它的方式有关。 Room 2.4.2 使用较旧版本的 kotlinx-metadata-jvm 库,不支持读取 Kotlin 1.7.x 的信息,而在 Room 2.5.0 中 Google 更新了该库。

为解决此问题,请通过将其添加到您的注释处理器路径来强制升级依赖项,例如如果您使用 Room 2.4.x,请添加 kapt "org.jetbrains.kotlinx:kotlinx-metadata-jvm:0.5.0"

或者您也可以使用 Room 2.5.0-alpha02,它将解决这个问题。

结论

如果您只想解决错误,请将此添加到 app/gradle 文件中。

kapt "org.jetbrains.kotlinx:kotlinx-metadata-jvm:0.5.0"

或使用这些版本的房间与 Kotlin 1.7.x

implementation 'androidx.room:room-ktx:2.5.0-alpha02'
kapt 'androidx.room:room-compiler:2.5.0-alpha02'

来源

更新

现在你可以使用更新 Room 2.4.3Kotlin 1.7.10 版本而不会遇到任何问题。


非常感谢您解决了我的问题。我们还需要实现multidex。// Room implementation 'androidx.room:room-ktx:2.3.0' implementation "androidx.room:room-runtime:2.3.0" kapt "androidx.room:room-compiler:2.3.0" kapt "org.jetbrains.kotlinx:kotlinx-metadata-jvm:0.5.0" - FreddicMatters
不客气,具体实现取决于你使用的 Kotlin 版本和 Room 版本,这将使您选择要实现的依赖关系。在我的情况下,我使用的是 Room 2.4.2 和 Kotlin 1.7.10。 - Marawan Mamdouh
更新 Room 到 2.4.3 版本解决了我在 Kotlin 1.7.0 中遇到的问题。 - diAz
是的,现在 Room 版本 2.4.3 解决了 2.4.2 中出现的问题。感谢 @diAz。 - Marawan Mamdouh

12

我将最新版的Room更新后,它就不见了 - 房间版本 = "2.4.0"


8
@Query("select * from movie_action")
    suspend fun getMovieActionRoom() : LiveData<List<MoviesActionModel>>

有时候,只需删除“suspend”即可消除错误。


6

在我的情况下,当我在Dao类中使用 LiveData<ArrayList<Example Class>> 从Room获取所有内容时,出现了这个问题。当我将 ArrayList 更改为 List 后问题得到解决。

示例(Kotlin):

@Dao
interface ExampleDao {
@Query("SELECT * from example_table")
fun getAllExample():LiveData<List<Example>>
}

你在这个例子中使用的是哪些版本的Room?而LiveData不是问题,对吧? - Tanasis
我使用的版本是“1.1.1”。 在我的情况下,我是这样修复的! - Fidan Bacaj
我明白了。谢谢! - Tanasis
1
如果您想修改 LiveData<List<Example>> 而不出现错误,请将其更改为 LiveData<MutableList<Example>> - lasec0203
这是因为Room返回了List的不同实现,但你试图将其强制转换为ArrayList。 - Brill Pappin

3
在我的情况下,我在升级到Kotlin 1.9和Room 2.5.2之后开始出现错误。通过将room的编译方式从kapt切换到ksp,问题得到了解决。

3

在我的情况下,我正在使用Roomandroidx依赖项和ViewModelLiveData的[旧版]依赖项,所以我收到了这个消息

解决方案: 要么使用所有androidx依赖项,要么使用所有旧版android.arch的依赖项


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接