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

打开和关闭 Realm — Java SDK

在此页面上

  • 默认 Realm
  • 本地 Realm
  • 本地 Realm 配置
  • 打开本地 Realm
  • 只读 Realm
  • 内存 Realms
  • 动态域
  • 关闭 Realm
  • 配置要在 Realm 模式中包含的类

与 Android 应用程序中的 Realm 交互使用以下一系列高级步骤:

  1. 为要打开的 Realm 创建配置。

  2. 通过 config 打开 Realm。

  3. 完成后,关闭 Realm以释放资源。

您可以使用 setDefaultConfiguration() 方法将任何 RealmConfiguration SyncConfiguration 保存为应用程序的默认值:

RealmConfiguration config = new RealmConfiguration.Builder()
.name("default-realm")
.allowQueriesOnUiThread(true)
.allowWritesOnUiThread(true)
.compactOnLaunch()
.inMemory()
.build();
// set this config as the default realm
Realm.setDefaultConfiguration(config);
val config = RealmConfiguration.Builder()
.name("default-realm")
.allowQueriesOnUiThread(true)
.allowWritesOnUiThread(true)
.compactOnLaunch()
.inMemory()
.build()
// set this config as the default realm
Realm.setDefaultConfiguration(config)

然后,你可以使用 getDefaultConfiguration () 来访问该配置,或者使用 getDefaultInstance() 来打开一个具有该配置的域:

Realm realm = Realm.getDefaultInstance();
Log.v("EXAMPLE","Successfully opened the default realm at: " + realm.getPath());
val realm = Realm.getDefaultInstance()
Log.v("EXAMPLE","Successfully opened the default realm at: ${realm.path}")

本地域仅在客户端设备上存储数据。您可以使用 RealmConfiguration 自定义本地域的设置。

要配置 Realm 的设置,请使用 RealmConfiguration.Builder 创建 RealmConfiguration 。以下示例将本地 Realm 配置为:

  • 文件名“alternate-realm”

  • 用户界面线程上显式允许的同步读取

  • 用户界面线程上显式允许的同步写入

  • 启动 Realm 时自动压缩,节省文件空间

RealmConfiguration config = new RealmConfiguration.Builder()
.name("alternate-realm")
.allowQueriesOnUiThread(true)
.allowWritesOnUiThread(true)
.compactOnLaunch()
.build();
Realm realm = Realm.getInstance(config);
Log.v("EXAMPLE", "Successfully opened a realm at: " + realm.getPath());
val config = RealmConfiguration.Builder()
.name("alternate-realm")
.allowQueriesOnUiThread(true)
.allowWritesOnUiThread(true)
.compactOnLaunch()
.build()
val realm = Realm.getInstance(config)
Log.v("EXAMPLE", "Successfully opened a realm at: ${realm.path}")

重要

UI 线程上的同步读写

默认情况下,只能使用异步事务在应用程序的用户界面线程中读取或写入域。也就是说,除非您明确允许使用同步方法,否则您只能在 Android 应用程序的主线程中使用名称以单词 Async 结尾的 Realm 方法。

此限制是为了应用程序用户的利益:在 UI 线程上执行读写操作,可能导致 UI 交互无响应或速度缓慢,所以通常来说,最好以异步方式或在后台线程中处理这些操作。但是,如果应用程序需要在 UI 线程上使用同步 Realm 读取或写入,则可以通过以下 SyncConfiguration 选项明确支持使用同步方法:

SyncConfiguration config = new SyncConfiguration.Builder(app.currentUser(), PARTITION)
.allowQueriesOnUiThread(true)
.allowWritesOnUiThread(true)
.build();
Realm.getInstanceAsync(config, new Realm.Callback() {
@Override
public void onSuccess(Realm realm) {
Log.v(
"EXAMPLE",
"Successfully opened a realm with reads and writes allowed on the UI thread."
);
}
});
val config = SyncConfiguration.Builder(app.currentUser(), PARTITION)
.allowQueriesOnUiThread(true)
.allowWritesOnUiThread(true)
.build()
Realm.getInstanceAsync(config, object : Realm.Callback() {
override fun onSuccess(realm: Realm) {
Log.v("EXAMPLE", "Successfully opened a realm with reads and writes allowed on the UI thread.")
}
})

要打开 Realm,请使用 RealmConfiguration.Builder 创建 RealmConfiguration ,并将生成的 传递给RealmConfiguration getInstance() getInstanceAsync():

RealmConfiguration config = new RealmConfiguration.Builder()
.allowQueriesOnUiThread(true)
.allowWritesOnUiThread(true)
.build();
Realm realm;
try {
realm = Realm.getInstance(config);
Log.v("EXAMPLE", "Successfully opened a realm at: " + realm.getPath());
} catch (RealmFileException ex) {
Log.v("EXAMPLE", "Error opening the realm.");
Log.v("EXAMPLE", ex.toString());
}
val config = RealmConfiguration.Builder()
.allowQueriesOnUiThread(true)
.allowWritesOnUiThread(true)
.build()
var realm: Realm
try {
realm = Realm.getInstance(config)
Log.v("EXAMPLE", "Successfully opened a realm at: ${realm.path}")
} catch(ex: RealmFileException) {
Log.v("EXAMPLE", "Error opening the realm.")
Log.v("EXAMPLE", ex.toString())
}

有时,随应用程序提供一个准备好的 Realm 文件会很有用,其中包含不经常更改的共享数据。 在配置 Realm 时,可以使用readOnly()方法将其设置为只读。 这可以防止对 Realm 的意外写入,并导致 Realm 在发生写入时抛出IllegalStateException

警告

只读 Realm 文件是可写的

只读域仅在进程中强制为只读。Realm 文件本身仍可写入。

RealmConfiguration config = new RealmConfiguration.Builder()
.assetFile("bundled.realm")
.readOnly()
.modules(new BundledRealmModule())
.build();
val config = RealmConfiguration.Builder()
.assetFile("readonly.realm")
.readOnly()
.modules(BundledRealmModule())
.build()

您可以创建完全在内存中运行而不写入文件的域 。当 Android 设备上的内存不足时,内存中的 Realm 可能会 交换 暂时从主内存转移到磁盘空间。在以下情况下,SDK 会删除内存中域创建的所有文件:

  • Realm 关闭

  • 所有对该领域的引用都超出了范围

要创建内存中的 Realm,请在配置域时使用inMemory()

RealmConfiguration config = new RealmConfiguration.Builder()
.inMemory()
.name("java.transient.realm")
.build();
Realm realm = Realm.getInstance(config);
val config = RealmConfiguration.Builder()
.inMemory()
.name("kt.transient.realm")
.build()
val realm = Realm.getInstance(config)

传统 Realm 使用RealmObject子类或RealmModel接口定义模式。 DynamicRealm使用字符串在运行时定义模式。 打开动态 Realm 使用与传统 Realm 相同的配置,但动态 Realm 会忽略所有已配置的模式、迁移和模式版本。

动态 Realm 提供了灵活性,但牺牲了类型安全和性能。因此,只有在需要灵活性时,如迁移、手动重置客户端以及处理 CSV 文件或 JSON 等基于字符串的数据时,才使用动态 Realm。

要使用可变模式打开动态域,请使用 DynamicRealm:

RealmConfiguration config = new RealmConfiguration.Builder()
.allowWritesOnUiThread(true)
.allowQueriesOnUiThread(true)
.name("java.dynamic.realm")
.build();
DynamicRealm dynamicRealm = DynamicRealm.getInstance(config);
// all objects in a DynamicRealm are DynamicRealmObjects
AtomicReference<DynamicRealmObject> frog = new AtomicReference<>();
dynamicRealm.executeTransaction(transactionDynamicRealm -> {
// add type Frog to the schema with name and age fields
dynamicRealm.getSchema()
.create("Frog")
.addField("name", String.class)
.addField("age", int.class);
frog.set(transactionDynamicRealm.createObject("Frog"));
frog.get().set("name", "Wirt Jr.");
frog.get().set("age", 42);
});
// access all fields in a DynamicRealm using strings
String name = frog.get().getString("name");
int age = frog.get().getInt("age");
// because an underlying schema still exists,
// accessing a field that does not exist throws an exception
try {
frog.get().getString("doesn't exist");
} catch (IllegalArgumentException e) {
Log.e("EXAMPLE", "That field doesn't exist.");
}
// Queries still work normally
RealmResults<DynamicRealmObject> frogs = dynamicRealm.where("Frog")
.equalTo("name", "Wirt Jr.")
.findAll();
val config = RealmConfiguration.Builder()
.allowWritesOnUiThread(true)
.allowQueriesOnUiThread(true)
.name("kt.dynamic.realm")
.build()
val dynamicRealm = DynamicRealm.getInstance(config)
// all objects in a DynamicRealm are DynamicRealmObjects
var frog: DynamicRealmObject? = null
dynamicRealm.executeTransaction { transactionDynamicRealm: DynamicRealm ->
// add type Frog to the schema with name and age fields
dynamicRealm.schema
.create("Frog")
.addField("name", String::class.java)
.addField("age", Integer::class.java)
frog = transactionDynamicRealm.createObject("Frog")
frog?.set("name", "Wirt Jr.")
frog?.set("age", 42)
}
// access all fields in a DynamicRealm using strings
val name = frog?.getString("name")
val age = frog?.getInt("age")
// because an underlying schema still exists,
// accessing a field that does not exist throws an exception
try {
frog?.getString("doesn't exist")
} catch (e: IllegalArgumentException) {
Log.e("EXAMPLE", "That field doesn't exist.")
}
// Queries still work normally
val frogs = dynamicRealm.where("Frog")
.equalTo("name", "Wirt Jr.")
.findAll()

请务必记住在使用 Realm 实例完成后调用close()方法以释放资源。 忽视关闭 Realm 可能会导致OutOfMemoryError

realm.close();
realm.close()

Realm 模块是 Realm 对象模型的集合。在打开 Realm 时指定一个或多个模块,用于控制 Realm 应在模式中包含哪些类。如果您不指定模块,则 Realm 将使用默认模块,其中包括应用程序中定义的所有 Realm 对象。

注意

所有包含 Realm 的库必须通过模块显示和使用它们的模式。这样可以防止库生成默认的 RealmModule,从而避免该模块与任何包含该库的应用程序所使用的默认 RealmModule 发生冲突。所有使用该库的应用程序通过该模块访问库类。

// A library must create a module and set library = true. This will prevent the default
// module from being created.
// allClasses = true can be used instead of listing all classes in the library.
@RealmModule(library = true, allClasses = true)
public class MyLibraryModule {}
// ...
// Library projects are therefore required to explicitly set their own module.
SyncConfiguration libraryConfig = new SyncConfiguration.Builder(app.currentUser(), LIBRARY_PARTITION)
.modules(new MyLibraryModule())
.build();
// Apps can add the library RealmModule to their own schema.
SyncConfiguration config = new SyncConfiguration.Builder(app.currentUser(), PARTITION)
.modules(Realm.getDefaultModule(), new MyLibraryModule())
.build();
// A library must create a module and set library = true. This will prevent the default
// module from being created.
// allClasses = true can be used instead of listing all classes in the library.
@RealmModule(library = true, allClasses = true)
class MyLibraryModule
// ...
// Library projects are therefore required to explicitly set their own module.
val libraryConfig =
SyncConfiguration.Builder(app.currentUser(), LIBRARY_PARTITION)
.modules(MyLibraryModule())
.build()
// Apps can add the library RealmModule to their own schema.
val config =
SyncConfiguration.Builder(app.currentUser(), PARTITION)
.modules(Realm.getDefaultModule(), MyLibraryModule())
.build()

后退

Realm 文件