Docs 菜单
Docs 主页
/ /
Atlas Device SDKs
/

使用 Realm 文件 — .NET SDK

在此页面上

  • Realm生命周期
  • 多进程
  • Realm 模式
  • 同步 Realm
  • 查找您的Realm文件
  • Realm 文件大小
  • 限制活动版本的最大数量
  • 压缩 Realm
  • 备份和恢复 Realm
  • 模块

是一设立符合预定义模式的相关对象。 Realm 可以包含多种类型的数据,只要每种类型都存在模式。

每个域将数据存储在单独的域文件中,该文件包含域中每个对象的二进制编码。 您可以跨多个域自动同步 Realm,并设立响应式事件处理程序,以便在每次创建、修改或删除域中的对象时调用函数。

每个域实例都会消耗大量资源。 打开和关闭域都是昂贵的操作,但保持域打开也会产生大量资源开销。 为了最大限度地提高应用程序的性能,您应该在任何给定时间最大限度地减少打开 Realm 的数量,并限制使用的打开和关闭操作的次数。

然而,打开一个域并不总是那么昂贵。 如果域已在同一进程或线程中打开,则打开额外的实例所需的资源更少:

  • 如果未在同一进程中打开 Realm,则打开 Realm 的开销很高。

  • 如果 Realm 已在同一进程内的不同线程上打开,则打开 Realm 的成本较低,但仍然很重要。

  • 如果已在同一进程内的同一线程上打开 Realm,则打开该 Realm 只需最少的额外资源。

当您首次打开域时, Realm会执行在域中读取和写入数据所需的内存映射和模式验证。 同一线程上该域的其他实例使用相同的根本的资源。 不同线程上该域的实例使用一些相同的根本的资源。

当一个域的所有连接在一个线程中关闭时, Realm会释放用于连接该域的线程资源。 当进程中与某个域的所有连接都关闭时, Realm会释放用于连接该域的所有资源。

作为最佳实践,我们建议将 Realm 实例生命周期与观察域的视图的生命周期绑定在一起。实例,考虑一个通过RecyclerView 显示RealmResults 数据的Fragment 。您可以:

  • Fragment.onCreateView()生命周期方法中打开一个包含该视图数据的单个域 。

  • Fragment.onDestroyView()生命周期方法中关闭同一域 。

注意

如果您的域特别大,则在Fragment.onCreateView()中获取域实例可能会短暂区块渲染。 如果在onCreateView()中打开您的域会导致性能问题,请考虑改为从Fragment.onStart()Fragment.onStop()管理该域 。

如果多个Fragment实例需要访问同一数据集,您可以在封闭的Activity中管理单个 Realm:

  • Activity.onCreate()生命周期方法中打开域 。

  • Activity.onDestroy()生命周期方法中关闭 Realm。

您无法从不同进程同时访问权限加密同步Realm。 但是,本地 Realm 通常可以跨进程运行,因此您可以读取、写入多个 APK 和接收来自多个 APK 的通知。

Realm 模式是有效对象模式的列表,每个模式定义应用程序可以持久保存的对象类型。 Realm 中的所有对象都必须符合域Realm 模式。

默认情况下,SDK 会自动将项目中从 RealmObject 派生的所有类添加到 Realm 模式中。

客户端应用程序在打开域时提供Realm 模式。 如果域已包含数据,则Realm会验证每个现有对象,以确保为其类型提供了对象模式,并且满足模式中指定的所有约束。

例子

包含图书馆中图书基本数据的域可能会使用如下模式:

[
{
"type": "Library",
"properties": {
"address": "string",
"books": "Book[]"
}
},
{
"type": "Book",
"primaryKey": "isbn",
"properties": {
"isbn": "string",
"title": "string",
"author": "string",
"numberOwned": { "type": "int?", "default": 0 },
"numberLoaned": { "type": "int?", "default": 0 }
}
}
]

使用Atlas Device Sync的应用可以打开同步域。

使用 Flexible Sync 时,可以通过订阅查询自定义客户端应用程序同步的数据。这些查询在应用程序后端搜索数据,并且 Flexible Sync realm 同步与查询匹配的数据。客户端应用程序只能同步用户具有适当读写权限以访问数据的数据。

当您使用基于分区的同步时,同步的 Realm 表示 Atlas 数据的分区。 每个 Realm 对应于应用数据源中数据的一个子集。 您可以使用应用程序的 分区键 自定义数据 分区 。分区键的唯一值(称为分区值)与各个 Realm 相对应。

在配置Realm规则时,您可以自定义同步 Realm 可以从您的应用程序读取和写入的数据的权限。

有关更多信息,请参阅配置同步Realm - Java SDK。

Realm将域中每个对象和类型的二进制编码版本存储在单个.realm文件中。

运行Realm Studio的机器无法直接访问 Android 模拟器使用的文件系统。 您必须先从模拟器下载该文件,然后才能访问权限。

首先,在模拟器上找到该文件的路径:

// Run this on the device to find the path on the emulator
Realm realm = Realm.getDefaultInstance();
Log.i("Realm", realm.getPath());

然后,使用 ADB下载文件。 您可以在应用运行时执行此操作。

> adb pull <path>

您还可以使用 ADB 再次上传修改后的文件,但前提是应用未运行。 在应用运行时上传修改后的文件可能会损坏该文件。

> adb push <file> <path>

提示

另请参阅:辅助Realm文件

Realm会为每个域创建附加文件。 要学习;了解有关这些文件的更多信息,请参阅Realm内部。

Realm通常比同等的 SQLite数据库占用更少的磁盘空间。 但是,为了向您提供一致的数据视图, Realm会对域的多个版本进行操作。 如果同时打开某个域的多个版本,则该域文件可能需要额外的磁盘空间。

这些版本占用的空间量取决于每个事务中的更改量。 许多小型事务的开销与少量大型事务相同。

文件大小意外增长通常由以下三个原因之一造成:

  1. 您在背景线程上打开一个域 ,却忘记再次将其关闭。 因此, Realm在背景线程上保留了对旧版本数据的引用。 由于Realm会在带有 Looper 的线程上自动将 Realm 更新到最新版本,因此用户界面线程和其他 Looper 线程不存在此问题。

  2. 您引用了过多多版本的冻结对象。冻结对象会保留首次冻结对象时存在的 Realm 版本。如果需要冻结大量对象,请考虑使用 Realm.copyFromRealm(),而不是仅保留您需要的数据。

  3. 您从域中读取了一些数据。然后,您可以通过长时间运行的操作来区块线程。同时,您在其他线程上多次向域写入。 这会导致Realm创建许多中间版本。 您可以通过以下方式避免这种情况:

    • 批处理写入

    • 避免让域保持打开状态,否则会阻塞背景线程。

您可以在构建RealmConfiguration时设置maxNumberOfActiveVersions() ,以便在应用程序打开的 Realm 版本超过允许数量时引发IllegalStateException 。 版本是在执行写事务时创建的。

一旦您的应用程序不再使用旧版本的数据, Realm就会自动删除这些数据。 但是, Realm不会释放旧版本数据所使用的空间;相反,该空间用于对域进行新的写入。

您可以通过压缩Realm 文件来删除未使用的空间:

重要

压缩所有生产应用程序

每个生产应用程序都应实施压缩,以定期减小 Realm 文件的大小。

Realm 使用 Android 设备上的文件将 Realm 持久保存到磁盘上。要备份 Realm,找到 Realm 文件并将其复制到安全位置。您应该在复制 Realm 之前关闭该 Realm 的所有实例。

或者,也可以使用 realm.writeCopyTo() 将 Realm 的压缩版本写入目标文件。

提示

另请参阅:

如果要将域备份到外部位置(例如 Google 云端硬盘),请参阅以下文章系列:( 部分1 第2 部分3 , 第 部分 )。

Realm 模块描述了可以存储在 Realm 中的一组 Realm 对象。默认情况下,Realm 会自动创建一个 Realm 模块,其中包含应用程序中定义的所有 Realm 对象。您可以定义一个 RealmModule,将 Realm 限制为应用程序中定义的类的子集。如果您生成一个使用 Realm 的库,则可以使用 Realm 模块来显式地仅将库中定义的 Realm 对象包含在您的 Realm 中。这样,包含您的库的应用程序也可以使用 Realm,而无需管理与库定义的 Realm 对象的对象名称冲突和迁移。

后退

Java SDK