Android Room KSP可空性处理异常问题咨询
问题描述
我的Android应用中有如下Room DAO函数:
@RawQuery @Transaction abstract suspend fun queryOneOrNone(query: SupportSQLiteQuery): TEntity?
kapt生成的Java代码如下:
@Override public Object queryOneOrNone(final SupportSQLiteQuery query, final Continuation<? super MyEntity> $completion) { final CancellationSignal _cancellationSignal = DBUtil.createCancellationSignal(); return CoroutinesRoom.execute(__db, true, _cancellationSignal, new Callable<MyEntity>() { @Override @Nullable public MyEntity call() throws Exception { __db.beginTransaction(); try { final Cursor _cursor = DBUtil.query(__db, query, false, null); try { final MyEntity _result; if (_cursor.moveToFirst()) { _result = __entityCursorConverter_persistenceStorageMyEntity(_cursor); } else { _result = null; } __db.setTransactionSuccessful(); return _result; } finally { _cursor.close(); } } finally { __db.endTransaction(); } } }, $completion); }
而KSP生成的代码如下:
public override suspend fun queryOneOrNone(query: SupportSQLiteQuery): MyEntity? { val _cancellationSignal: CancellationSignal? = createCancellationSignal() return execute(__db, true, _cancellationSignal, object : Callable<MyEntity?> { public override fun call(): MyEntity? { __db.beginTransaction() try { val _cursor: Cursor = query(__db, query, false, null) try { val _result: MyEntity if (_cursor.moveToFirst()) { _result = __entityCursorConverter_persistenceStorageMyEntity(_cursor) } else { error("The query result was empty, but expected a single row to return a NON-NULL object of type <MyEntity>.") } __db.setTransactionSuccessful() return _result } finally { _cursor.close() } } finally { __db.endTransaction() } } }) }
应用运行时抛出错误:
"The query result was empty, but expected a single row to return a NON-NULL object of type <MyEntity>."
目前我可以通过在Gradle中添加如下配置缓解问题,但更希望保留KSP生成Kotlin代码的功能:
ksp { arg("room.generateKotlin", "false") }
请问这是KSP的问题,还是我的应用代码存在错误?
结论与解决方案
这是Room KSP处理器的bug,和你的应用代码无关。
从代码对比可以明确看出:
- kapt生成的代码正确适配了可空返回类型
TEntity?:当查询无结果时返回null - KSP生成的代码存在逻辑错误:尽管返回类型标注为可空的
MyEntity?,但在查询无结果时却调用error()抛出异常,而非返回null
解决办法:
- 升级Room版本:该bug在Room 2.5.0及后续版本中已被修复,建议直接升级Room依赖到对应版本
- 临时替代方案:如果暂时无法升级,可继续使用你提到的Gradle配置
room.generateKotlin=false,让KSP生成Java代码以规避该bug
内容的提问来源于stack exchange,提问作者Hector
相关产品推荐
相关产品推荐

