在 Room 数据库实体上实现 Parcelable 是一种好习惯吗?

Posted

技术标签:

【中文标题】在 Room 数据库实体上实现 Parcelable 是一种好习惯吗?【英文标题】:Is it good practice implementing Parcelable on a Room database entity? 【发布时间】:2019-09-27 05:45:45 【问题描述】:

我正在学习我的 android 开发技能,并且一直在玩架构组件。因此,我使用Room 注释创建了一个实体类以持久保存到数据库,并在实体类上实现Parcelable,部分目的是为了将实体对象放入Intent 对象并在活动/片段之间传递它。我只是想知道这是一个很好的做法。使用诸如数据库泄漏或安全漏洞之类的方法有什么缺点吗?只是好奇。

【问题讨论】:

【参考方案1】:

我只是想知道这是否是一个好习惯。

恕我直言,在现代 Android 应用开发中,不,有几个原因,包括:

存储库模式:Android 应用架构中的当前模式是隔离数据存储并将关注点转移到“存储库”对象中。存储库知道数据来自和去往的详细信息(Room、Realm、Retrofit 等)。应用程序的其余部分既不知道也不关心,因为应用程序的其余部分只是与存储库对话。使用这种模式,您将在活动和片段之间传递标识符,并且存储库将根据这些标识符移交模型对象。

隐藏实现细节:您的 UI 应该使用一组理想的模型类,这些模型类与数据存储或传输的特定实现无关。这样,如果您选择更改您的实现(例如,从 Room 到 Realm),您的更改仍然是孤立的,并且对 UI 的影响应该很小。如果您使用存储库,该存储库将负责将 Room 实体和 Retrofit 响应转换为应用程序其余部分知道如何使用的标准化模型对象。

单一事实来源:一旦你开始通过Intent 附加对象传递对象,你就是在复制。如果您的应用程序的一部分然后希望修改该模型对象......应用程序的其余部分(持有其他数据副本)将如何知道这些更改?理想情况下,您有一个带有反应式 API 的存储库,其中存储库是进行数据更改的一方。然后,它可以将数据更改通知其他相关方,提供模型对象的最新版本。

IPC 内存限制:每次使用IntentstartActivity()startActivityForResult()setResult() 等时,都会传递Intent 的内容到核心操作系统进程......即使正在启动的活动与请求启动该活动的代码在同一个进程中。 Intent 的大小有内存限制(粗略地说,1MB 或更低)。传递完整的模型对象现在可能工作得很好,但以后如果有人在模型中添加 Bitmap 字段或其他内容,您可能会遇到麻烦。

【讨论】:

你好,关于“repository”类的问题,所有数据库都应该是1?或者我必须为每个表创建一个存储库。最佳做法是什么? @Nicolas400:这在很大程度上取决于数据库的复杂性。我将使用“每个表一个存储库”作为起点,并在适当的情况下合并存储库。对于相当小的数据库(只有几个表)来说,单个存储库就可以了。

以上是关于在 Room 数据库实体上实现 Parcelable 是一种好习惯吗?的主要内容,如果未能解决你的问题,请参考以下文章

Android Room:使用 Room 插入关系实体

为啥 Room 实体不适用于 Android 中的不可变属性

Android Room Database:如何处理实体中的 Arraylist?

Room 不会更新现有的预定义数据库

如何在 Room MVVM 架构中实现 Koin 依赖注入

在独立的 watchOS 应用上实现核心数据