str*_*phe 4 android kotlin android-room kotlin-coroutines kotlin-flow
我刚刚开始研究 Room、Coroutines 和 Flow,并且遇到了一些奇怪的事情:我期望的空流实际上有一个空项目。
我的设置如下,T对于我的实际实体是通用的。
interface TDao {
@Query("SELECT * FROM Table WHERE date=:date")
fun getT(date: String): Flow<T>
}
Run Code Online (Sandbox Code Playgroud)
@Singleton
class TRepository @Inject constructor(
private val apiService: TApiService,
private val Tdao: TDao
) {
suspend fun getTFor(date: String): Flow<T> =
Tdao
.getT(date)
.map {
if (it == null) {
returnTFromDatabase()
} else {
it
}
}
Run Code Online (Sandbox Code Playgroud)
现在,当数据库中没有任何Tfor 时date,我希望它返回一个空流,其中没有任何项目。相反,它有一个null永远不会发生的元素,因为T它不可为空。
我为它写了这个测试:
@RunWith(AndroidJUnit4::class)
class TDatabaseTest {
private lateinit var db: TDatabase
private lateinit var underTest: TDao
@Before
fun setUp() {
val context = InstrumentationRegistry.getInstrumentation().context
db = Room.inMemoryDatabaseBuilder(context, TDatabase::class.java).build()
underTest = db.TDao()
}
@After
fun tearDown() {
db.close()
}
@Test
fun givenEmptyDatabase_thenHasNoItems() {
runBlocking {
val list = underTest.getT("1999").take(1).toList()
assertEquals(1, list.size)
}
}
}
Run Code Online (Sandbox Code Playgroud)
...它通过了,因为再次null返回了一件物品。
我错过了什么?这里有什么问题,因为我无法弄清楚。为什么我在具有不可为空元素的流中得到单个空元素?
小智 25
Room 如何处理可为空性取决于您如何定义查询函数的返回类型。文件说:
- 当返回类型为 时
Flow<T>,查询空表会引发空指针异常。- 当返回类型为 时
Flow<T?>,查询空表会发出一个null值。- 当返回类型为 时
Flow<List<T>>,查询空表会发出空列表。
上面的代码片段讨论了空表,但我假设相同的行为适用于任何不返回行的查询。
资料来源:房间文档查询
小智 9
Room 是一个用 Java 编写的数据库,这就是它忽略 Kotlin 可选的原因。我建议声明始终查询返回类型,或者在您的情况下,Flow<T?>类型为可选。如果您不想在流程中使用 null 类型,您可以使用如下filterNotNull()函数:
Tdao.getT(date).filterNotNull()
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
3153 次 |
| 最近记录: |