如果 LiveData 和 Room 中不存在记录,会发生什么情况?



代码 A 来自项目播放计费示例,您可以在此处看到。

我想"SELECT * FROM gold_status LIMIT 1"可能不返回任何记录,我不知道fun getGoldStatus(): LiveData<GoldStatus>陈述是否正确,我认为应该是代码B,对吧?

代码 A

@Dao
interface EntitlementsDao {
@Query("SELECT * FROM gold_status LIMIT 1")
fun getGoldStatus(): LiveData<GoldStatus>
...
}

代码 B

@Dao
interface EntitlementsDao {
@Query("SELECT * FROM gold_status LIMIT 1")
fun getGoldStatus(): LiveData<GoldStatus>?
...
}

在Android上,我不是Room和SQLite的专家。但我想分享我自己对这个问题的看法和发现。

@P.Leibner 是正确的,对象本身会立即返回LiveData并且它不是空的。内容可能为空。

如果你查看 Dao 生成的代码,你会看到它是一个 Java 代码,如果没有与您的查询匹配的记录,它将返回 null。此外,也没有注释可以帮助 Kotlin 编译器检查可空性。

因此,如果我们返回非空对象,我们不会收到编译器错误或 lint 警告

// Compiles but we might get NullPointerException at runtime.
fun getGoldStatus(): LiveData<GoldStatus>
// or
fun getGoldStatus(): GoldStatus

但是,如果你在表中没有一行,你将在运行时遇到 NullPointerExceptions,如果你在 Kotlin 中将其标记为非空,你将开始对该对象执行某些操作。

注意:如果您返回List<GoldStatus>LiveData<List<GoldStatus>>,则不会发生这种情况。 如果没有匹配的行,它只会返回空列表。

直到遇到这些问题,我自己才知道这一点。也许我在了解房间时错过了一些解释。我们只需要知道,如果您查询单行和列表,则 room 将返回对象或 null,如果多行,则返回空列表。

我更喜欢在 Dao 方法的返回类型中指定可空性。这样,我以空安全的方式编写了与之配合使用的其他代码。

我会称之为代码C

// Runtime NullPointerException safe.
fun getGoldStatus(): LiveData<GoldStatus?>
// or
fun getGoldStatus(): GoldStatus?

你也可以看看这个答案来获取更多信息,并查看 Dao 生成的代码示例。

代码 A 是正确的,因为返回的不是来自数据库的数据,而是可观察的数据类持有者 (LiveData(,即使表中没有记录,也会返回。然后,您可以将观察器附加到此可观察量,一旦数据库发生更改,就会触发观察器(您可以在 Android 文档中找到几个示例(。如果尚未设置任何值,则 LiveData 对象的 getValue(( 方法可以返回 null,但通常您使用观察者来更改 LiveData。

没什么好说的。

您将收到LiveData(null)- 因此请记住这一点,因为可能存在空指针。您也不会收到此对象的进一步更改,因为它不存在。

随之而去

fun getGoldStatus(): LiveData<GoldStatus?>?

无论如何,它会更加安全。(带LivaData的房间仍然是一个非常有缺陷的组合(

希望对您有所帮助。

相关内容

最新更新