Docs 菜单
Docs 主页
/ /
Atlas Device SDKs

使用同步快速入门 - Java SDK

在此页面上

  • 初始化 Realm
  • 初始化 App Services
  • 定义对象模型
  • 验证用户身份
  • 打开 Realm
  • 创建、读取、更新和删除对象
  • 注意更改
  • 登出
  • 完整示例
  • 输出

提示

本指南使用 Device Sync

本指南帮助您开始使用与应用后端通信的 Android应用程序程序。 该应用程序提供 Sync 、 Realm函数和用户管理等功能。 如果您的应用程序只需要本地数据库功能,请查看快速入门(仅限本地)指南。

此页面包含快速将 Atlas App Services 集成到您的应用程序中的信息。 开始之前,请确保您已:

在应用程序中使用 Realm 之前,您必须初始化 Realm 库。 您的应用程序应该在每次运行时初始化 Realm 一次。

要初始化Realm库,请为Realm.init()静态函数提供一个 Android context 。 您可以提供活动、片段或应用程序context进行初始化,而行为不会有任何差异。 您可以在 应用程序子类onCreate() 方法中初始化Realm库 以确保每次应用程序运行时仅初始化Realm一次。

Realm.init(this); // context, usually an Activity or Application
Realm.init(this) // context, usually an Activity or Application

提示

在 Android 清单中注册您的应用程序子类

如果创建自己的Application子类,则必须将其添加到应用程序的AndroidManifest.xml中才能执行自定义应用程序逻辑。 设置清单应用程序定义的android.name属性,确保当用户启动您的应用程序时,Android 会先于任何其他类实例化您的Application子类。

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.mongodb.example">
<application
android:name=".MyApplicationSubclass"
...
/>
</manifest>

要使用身份验证和同步等 App Services 功能,请使用您的App ID 访问 App Services 应用。您可在 App Services 用户界面中找到您的 App ID

app = new App(new AppConfiguration.Builder(appID)
.build());
val appID : String = YOUR_APP_ID;
app = App(AppConfiguration.Builder(appID)
.build())

注意

Android Studio 错误?

如果 Android Studio 无法识别RealmAppAppConfiguration类型,则 Gradle 构建配置可能有问题。 要解决此问题,请执行以下操作:

  • 使用清理项目 Build > Clean Project

  • 使用Build > Rebuild Project根据更新的build.gradle文件重建项目

  • 重新访问“安装 Java SDK”指南,确保正确安装依赖项。

您的应用程序的Realm 数据模型定义了存储在 Realm 中以及与 App Services 之间同步的数据结构。您可以通过两种方式定义应用程序的 Realm 数据模型:

本快速入门使用后一种方法,即使用移动应用程序代码中的类来定义模式。 要以这种方式定义应用的对象模型,您需要启用开发模式。

启用开发模式后,将以下类定义添加到应用程序代码中:

import io.realm.RealmObject;
import io.realm.annotations.PrimaryKey;
import io.realm.annotations.RealmClass;
import io.realm.annotations.Required;
import org.bson.types.ObjectId;
public class Task extends RealmObject {
@PrimaryKey
private ObjectId _id = new ObjectId();
private String name = "Task";
@Required
private String status = TaskStatus.Open.name();
public void setStatus(TaskStatus status) {
this.status = status.name();
}
public String getStatus() {
return this.status;
}
public ObjectId get_id() {
return _id;
}
public void set_id(ObjectId _id) {
this._id = _id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Task(String _name) {
this.name = _name;
}
public Task() {}
}
public enum TaskStatus {
Open("Open"),
InProgress("In Progress"),
Complete("Complete");
String displayName;
TaskStatus(String displayName) {
this.displayName = displayName;
}
}
enum class TaskStatus(val displayName: String) {
Open("Open"),
InProgress("In Progress"),
Complete("Complete"),
}
open class Task(_name: String = "Task", project: String = "My Project") : RealmObject() {
@PrimaryKey
var _id: ObjectId = ObjectId()
var name: String = _name
@Required
var status: String = TaskStatus.Open.name
var statusEnum: TaskStatus
get() {
// because status is actually a String and another client could assign an invalid value,
// default the status to "Open" if the status is unreadable
return try {
TaskStatus.valueOf(status)
} catch (e: IllegalArgumentException) {
TaskStatus.Open
}
}
set(value) { status = value.name }
}

在App Services用户界面中启用匿名身份验证后,用户无需提供任何身份信息即可立即日志您的应用:

Credentials credentials = Credentials.anonymous();
app.loginAsync(credentials, result -> {
if (result.isSuccess()) {
Log.v("QUICKSTART", "Successfully authenticated anonymously.");
User user = app.currentUser();
String partitionValue = "My Project";
SyncConfiguration config = new SyncConfiguration.Builder(
user,
partitionValue)
.build();
uiThreadRealm = Realm.getInstance(config);
addChangeListenerToRealm(uiThreadRealm);
FutureTask<String> task = new FutureTask(new BackgroundQuickStart(app.currentUser()), "test");
ExecutorService executorService = Executors.newFixedThreadPool(2);
executorService.execute(task);
} else {
Log.e("QUICKSTART", "Failed to log in. Error: " + result.getError());
}
});
val credentials: Credentials = Credentials.anonymous()
app.loginAsync(credentials) {
if (it.isSuccess) {
Log.v("QUICKSTART", "Successfully authenticated anonymously.")
val user: User? = app.currentUser()
val partitionValue: String = "My Project"
val config = SyncConfiguration.Builder(user, partitionValue)
.build()
uiThreadRealm = Realm.getInstance(config)
addChangeListenerToRealm(uiThreadRealm)
val task : FutureTask<String> = FutureTask(BackgroundQuickStart(app.currentUser()!!), "test")
val executorService: ExecutorService = Executors.newFixedThreadPool(2)
executorService.execute(task)
} else {
Log.e("QUICKSTART", "Failed to log in. Error: ${it.error}")
}
}

Realm 提供了许多其他方法来对用户进行身份验证、注册和链接。

启用 Sync并对用户进行身份验证后,您可以打开 Synced 。 使用SyncConfiguration控制应用程序如何与App Services同步数据的细节,包括超时、用户界面线程上的同步读取和写入等等。

String partitionValue = "My Project";
SyncConfiguration config = new SyncConfiguration.Builder(
user,
partitionValue)
.build();
Realm backgroundThreadRealm = Realm.getInstance(config);
val partitionValue: String = "My Project"
val config = SyncConfiguration.Builder(user, partitionValue)
.build()
val backgroundThreadRealm : Realm = Realm.getInstance(config)

打开域后,您可以在 写事务(write transaction) 区块中修改该域内的 对象

重要

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.")
}
})

要创建新的Task ,请实例化Task类的实例并将其添加到写入区块中的 Realm:

Task task = new Task("New Task");
backgroundThreadRealm.executeTransaction (transactionRealm -> {
transactionRealm.insert(task);
});
val task : Task = Task("New Task", partitionValue)
backgroundThreadRealm.executeTransaction { transactionRealm ->
transactionRealm.insert(task)
}

您可以检索域中所有项目的实时集合

// all tasks in the realm
RealmResults<Task> tasks = backgroundThreadRealm.where(Task.class).findAll();
// all tasks in the realm
val tasks : RealmResults<Task> = backgroundThreadRealm.where<Task>().findAll()

您还可以使用过滤过滤该集合

// you can also filter a collection
RealmResults<Task> tasksThatBeginWithN = tasks.where().beginsWith("name", "N").findAll();
RealmResults<Task> openTasks = tasks.where().equalTo("status", TaskStatus.Open.name()).findAll();
// you can also filter a collection
val tasksThatBeginWithN : List<Task> = tasks.where().beginsWith("name", "N").findAll()
val openTasks : List<Task> = tasks.where().equalTo("status", TaskStatus.Open.name).findAll()

要修改任务,请在写事务区块中更新其属性:

Task otherTask = tasks.get(0);
// all modifications to a realm must happen inside of a write block
backgroundThreadRealm.executeTransaction( transactionRealm -> {
Task innerOtherTask = transactionRealm.where(Task.class).equalTo("_id", otherTask.get_id()).findFirst();
innerOtherTask.setStatus(TaskStatus.Complete);
});
val otherTask: Task = tasks[0]!!
// all modifications to a realm must happen inside of a write block
backgroundThreadRealm.executeTransaction { transactionRealm ->
val innerOtherTask : Task = transactionRealm.where<Task>().equalTo("_id", otherTask._id).findFirst()!!
innerOtherTask.status = TaskStatus.Complete.name
}

最后,您可以通过在写事务(write transaction)区块中调用deleteFromRealm()方法来删除除任务:

Task yetAnotherTask = tasks.get(0);
ObjectId yetAnotherTaskId = yetAnotherTask.get_id();
// all modifications to a realm must happen inside of a write block
backgroundThreadRealm.executeTransaction( transactionRealm -> {
Task innerYetAnotherTask = transactionRealm.where(Task.class).equalTo("_id", yetAnotherTaskId).findFirst();
innerYetAnotherTask.deleteFromRealm();
});
val yetAnotherTask: Task = tasks.get(0)!!
val yetAnotherTaskId: ObjectId = yetAnotherTask._id
// all modifications to a realm must happen inside of a write block
backgroundThreadRealm.executeTransaction { transactionRealm ->
val innerYetAnotherTask : Task = transactionRealm.where<Task>().equalTo("_id", yetAnotherTaskId).findFirst()!!
innerYetAnotherTask.deleteFromRealm()
}

您可以通过使用addChangeListener()方法附加自定义OrderedRealmCollectionChangeListener监视域、集合或对象的更改

// all tasks in the realm
RealmResults<Task> tasks = uiThreadRealm.where(Task.class).findAllAsync();
tasks.addChangeListener(new OrderedRealmCollectionChangeListener<RealmResults<Task>>() {
@Override
public void onChange(RealmResults<Task> collection, OrderedCollectionChangeSet changeSet) {
// process deletions in reverse order if maintaining parallel data structures so indices don't change as you iterate
OrderedCollectionChangeSet.Range[] deletions = changeSet.getDeletionRanges();
for (OrderedCollectionChangeSet.Range range : deletions) {
Log.v("QUICKSTART", "Deleted range: " + range.startIndex + " to " + (range.startIndex + range.length - 1));
}
OrderedCollectionChangeSet.Range[] insertions = changeSet.getInsertionRanges();
for (OrderedCollectionChangeSet.Range range : insertions) {
Log.v("QUICKSTART", "Inserted range: " + range.startIndex + " to " + (range.startIndex + range.length - 1)); }
OrderedCollectionChangeSet.Range[] modifications = changeSet.getChangeRanges();
for (OrderedCollectionChangeSet.Range range : modifications) {
Log.v("QUICKSTART", "Updated range: " + range.startIndex + " to " + (range.startIndex + range.length - 1)); }
}
});
// all tasks in the realm
val tasks : RealmResults<Task> = realm.where<Task>().findAllAsync()
tasks.addChangeListener(OrderedRealmCollectionChangeListener<RealmResults<Task>> { collection, changeSet ->
// process deletions in reverse order if maintaining parallel data structures so indices don't change as you iterate
val deletions = changeSet.deletionRanges
for (i in deletions.indices.reversed()) {
val range = deletions[i]
Log.v("QUICKSTART", "Deleted range: ${range.startIndex} to ${range.startIndex + range.length - 1}")
}
val insertions = changeSet.insertionRanges
for (range in insertions) {
Log.v("QUICKSTART", "Inserted range: ${range.startIndex} to ${range.startIndex + range.length - 1}")
}
val modifications = changeSet.changeRanges
for (range in modifications) {
Log.v("QUICKSTART", "Updated range: ${range.startIndex} to ${range.startIndex + range.length - 1}")
}
})

登录后即可注销:

app.currentUser().logOutAsync(result -> {
if (result.isSuccess()) {
Log.v("QUICKSTART", "Successfully logged out.");
} else {
Log.e("QUICKSTART", "Failed to log out, error: " + result.getError());
}
});
app.currentUser()?.logOutAsync() {
if (it.isSuccess) {
Log.v("QUICKSTART", "Successfully logged out.")
} else {
Log.e("QUICKSTART", "Failed to log out, error: ${it.error}")
}
}

将 appId 替换为您的 域 应用程序 ID,运行完整示例。如果您在新的 Android Studio 项目中运行此项目,则可以将此文件复制并粘贴到应用程序的MainActivity中,但请记住:

  • 更改包声明,使其与您的项目匹配

  • 将 应用程序 ID 占位符替换为您的应用的 应用程序 ID

  • 如果您使用的是 Java,请更新TaskTaskStatusimport语句

Task.java
import io.realm.RealmObject;
import io.realm.annotations.PrimaryKey;
import io.realm.annotations.RealmClass;
import io.realm.annotations.Required;
import org.bson.types.ObjectId;
public class Task extends RealmObject {
@PrimaryKey
private ObjectId _id = new ObjectId();
private String name = "Task";
@Required
private String status = TaskStatus.Open.name();
public void setStatus(TaskStatus status) {
this.status = status.name();
}
public String getStatus() {
return this.status;
}
public ObjectId get_id() {
return _id;
}
public void set_id(ObjectId _id) {
this._id = _id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Task(String _name) {
this.name = _name;
}
public Task() {}
}
TaskStatus.java
public enum TaskStatus {
Open("Open"),
InProgress("In Progress"),
Complete("Complete");
String displayName;
TaskStatus(String displayName) {
this.displayName = displayName;
}
}
MainActivity.java
import io.realm.OrderedCollectionChangeSet;
import org.bson.types.ObjectId;
import android.os.Bundle;
import androidx.appcompat.app.AppCompatActivity;
import android.util.Log;
import io.realm.OrderedRealmCollectionChangeListener;
import io.realm.Realm;
import io.realm.RealmResults;
import io.realm.mongodb.App;
import io.realm.mongodb.AppConfiguration;
import io.realm.mongodb.Credentials;
import io.realm.mongodb.User;
import io.realm.mongodb.sync.SyncConfiguration;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.FutureTask;
import com.mongodb.realm.examples.model.Task;
import com.mongodb.realm.examples.model.TaskStatus;
public class MainActivity extends AppCompatActivity {
Realm uiThreadRealm;
App app;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Realm.init(this); // context, usually an Activity or Application
app = new App(new AppConfiguration.Builder(appID)
.build());
Credentials credentials = Credentials.anonymous();
app.loginAsync(credentials, result -> {
if (result.isSuccess()) {
Log.v("QUICKSTART", "Successfully authenticated anonymously.");
User user = app.currentUser();
String partitionValue = "My Project";
SyncConfiguration config = new SyncConfiguration.Builder(
user,
partitionValue)
.build();
uiThreadRealm = Realm.getInstance(config);
addChangeListenerToRealm(uiThreadRealm);
FutureTask<String> task = new FutureTask(new BackgroundQuickStart(app.currentUser()), "test");
ExecutorService executorService = Executors.newFixedThreadPool(2);
executorService.execute(task);
} else {
Log.e("QUICKSTART", "Failed to log in. Error: " + result.getError());
}
});
}
private void addChangeListenerToRealm(Realm realm) {
// all tasks in the realm
RealmResults<Task> tasks = uiThreadRealm.where(Task.class).findAllAsync();
tasks.addChangeListener(new OrderedRealmCollectionChangeListener<RealmResults<Task>>() {
@Override
public void onChange(RealmResults<Task> collection, OrderedCollectionChangeSet changeSet) {
// process deletions in reverse order if maintaining parallel data structures so indices don't change as you iterate
OrderedCollectionChangeSet.Range[] deletions = changeSet.getDeletionRanges();
for (OrderedCollectionChangeSet.Range range : deletions) {
Log.v("QUICKSTART", "Deleted range: " + range.startIndex + " to " + (range.startIndex + range.length - 1));
}
OrderedCollectionChangeSet.Range[] insertions = changeSet.getInsertionRanges();
for (OrderedCollectionChangeSet.Range range : insertions) {
Log.v("QUICKSTART", "Inserted range: " + range.startIndex + " to " + (range.startIndex + range.length - 1)); }
OrderedCollectionChangeSet.Range[] modifications = changeSet.getChangeRanges();
for (OrderedCollectionChangeSet.Range range : modifications) {
Log.v("QUICKSTART", "Updated range: " + range.startIndex + " to " + (range.startIndex + range.length - 1)); }
}
});
}
@Override
protected void onDestroy() {
super.onDestroy();
// the ui thread realm uses asynchronous transactions, so we can only safely close the realm
// when the activity ends and we can safely assume that those transactions have completed
uiThreadRealm.close();
app.currentUser().logOutAsync(result -> {
if (result.isSuccess()) {
Log.v("QUICKSTART", "Successfully logged out.");
} else {
Log.e("QUICKSTART", "Failed to log out, error: " + result.getError());
}
});
}
public class BackgroundQuickStart implements Runnable {
User user;
public BackgroundQuickStart(User user) {
this.user = user;
}
@Override
public void run() {
String partitionValue = "My Project";
SyncConfiguration config = new SyncConfiguration.Builder(
user,
partitionValue)
.build();
Realm backgroundThreadRealm = Realm.getInstance(config);
Task task = new Task("New Task");
backgroundThreadRealm.executeTransaction (transactionRealm -> {
transactionRealm.insert(task);
});
// all tasks in the realm
RealmResults<Task> tasks = backgroundThreadRealm.where(Task.class).findAll();
// you can also filter a collection
RealmResults<Task> tasksThatBeginWithN = tasks.where().beginsWith("name", "N").findAll();
RealmResults<Task> openTasks = tasks.where().equalTo("status", TaskStatus.Open.name()).findAll();
Task otherTask = tasks.get(0);
// all modifications to a realm must happen inside of a write block
backgroundThreadRealm.executeTransaction( transactionRealm -> {
Task innerOtherTask = transactionRealm.where(Task.class).equalTo("_id", otherTask.get_id()).findFirst();
innerOtherTask.setStatus(TaskStatus.Complete);
});
Task yetAnotherTask = tasks.get(0);
ObjectId yetAnotherTaskId = yetAnotherTask.get_id();
// all modifications to a realm must happen inside of a write block
backgroundThreadRealm.executeTransaction( transactionRealm -> {
Task innerYetAnotherTask = transactionRealm.where(Task.class).equalTo("_id", yetAnotherTaskId).findFirst();
innerYetAnotherTask.deleteFromRealm();
});
// because this background thread uses synchronous realm transactions, at this point all
// transactions have completed and we can safely close the realm
backgroundThreadRealm.close();
}
}
}
MainActivity.kt
import org.bson.types.ObjectId
import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
import android.util.Log
import com.mongodb.realm.examples.YOUR_APP_ID
import io.realm.OrderedRealmCollectionChangeListener
import io.realm.Realm
import io.realm.RealmObject
import io.realm.RealmResults
import io.realm.annotations.PrimaryKey
import io.realm.annotations.Required
import io.realm.kotlin.where
import io.realm.mongodb.App
import io.realm.mongodb.AppConfiguration
import io.realm.mongodb.Credentials
import io.realm.mongodb.User
import io.realm.mongodb.sync.SyncConfiguration
import java.util.concurrent.ExecutorService
import java.util.concurrent.Executors
import java.util.concurrent.FutureTask
class MainActivity : AppCompatActivity() {
lateinit var uiThreadRealm: Realm
lateinit var app: App
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
Realm.init(this) // context, usually an Activity or Application
val appID : String = YOUR_APP_ID;
app = App(AppConfiguration.Builder(appID)
.build())
val credentials: Credentials = Credentials.anonymous()
app.loginAsync(credentials) {
if (it.isSuccess) {
Log.v("QUICKSTART", "Successfully authenticated anonymously.")
val user: User? = app.currentUser()
val partitionValue: String = "My Project"
val config = SyncConfiguration.Builder(user, partitionValue)
.build()
uiThreadRealm = Realm.getInstance(config)
addChangeListenerToRealm(uiThreadRealm)
val task : FutureTask<String> = FutureTask(BackgroundQuickStart(app.currentUser()!!), "test")
val executorService: ExecutorService = Executors.newFixedThreadPool(2)
executorService.execute(task)
} else {
Log.e("QUICKSTART", "Failed to log in. Error: ${it.error}")
}
}
}
fun addChangeListenerToRealm(realm : Realm) {
// all tasks in the realm
val tasks : RealmResults<Task> = realm.where<Task>().findAllAsync()
tasks.addChangeListener(OrderedRealmCollectionChangeListener<RealmResults<Task>> { collection, changeSet ->
// process deletions in reverse order if maintaining parallel data structures so indices don't change as you iterate
val deletions = changeSet.deletionRanges
for (i in deletions.indices.reversed()) {
val range = deletions[i]
Log.v("QUICKSTART", "Deleted range: ${range.startIndex} to ${range.startIndex + range.length - 1}")
}
val insertions = changeSet.insertionRanges
for (range in insertions) {
Log.v("QUICKSTART", "Inserted range: ${range.startIndex} to ${range.startIndex + range.length - 1}")
}
val modifications = changeSet.changeRanges
for (range in modifications) {
Log.v("QUICKSTART", "Updated range: ${range.startIndex} to ${range.startIndex + range.length - 1}")
}
})
}
override fun onDestroy() {
super.onDestroy()
// the ui thread realm uses asynchronous transactions, so we can only safely close the realm
// when the activity ends and we can safely assume that those transactions have completed
uiThreadRealm.close()
app.currentUser()?.logOutAsync() {
if (it.isSuccess) {
Log.v("QUICKSTART", "Successfully logged out.")
} else {
Log.e("QUICKSTART", "Failed to log out, error: ${it.error}")
}
}
}
class BackgroundQuickStart(val user: User) : Runnable {
override fun run() {
val partitionValue: String = "My Project"
val config = SyncConfiguration.Builder(user, partitionValue)
.build()
val backgroundThreadRealm : Realm = Realm.getInstance(config)
val task : Task = Task("New Task", partitionValue)
backgroundThreadRealm.executeTransaction { transactionRealm ->
transactionRealm.insert(task)
}
// all tasks in the realm
val tasks : RealmResults<Task> = backgroundThreadRealm.where<Task>().findAll()
// you can also filter a collection
val tasksThatBeginWithN : List<Task> = tasks.where().beginsWith("name", "N").findAll()
val openTasks : List<Task> = tasks.where().equalTo("status", TaskStatus.Open.name).findAll()
val otherTask: Task = tasks[0]!!
// all modifications to a realm must happen inside of a write block
backgroundThreadRealm.executeTransaction { transactionRealm ->
val innerOtherTask : Task = transactionRealm.where<Task>().equalTo("_id", otherTask._id).findFirst()!!
innerOtherTask.status = TaskStatus.Complete.name
}
val yetAnotherTask: Task = tasks.get(0)!!
val yetAnotherTaskId: ObjectId = yetAnotherTask._id
// all modifications to a realm must happen inside of a write block
backgroundThreadRealm.executeTransaction { transactionRealm ->
val innerYetAnotherTask : Task = transactionRealm.where<Task>().equalTo("_id", yetAnotherTaskId).findFirst()!!
innerYetAnotherTask.deleteFromRealm()
}
// because this background thread uses synchronous realm transactions, at this point all
// transactions have completed and we can safely close the realm
backgroundThreadRealm.close()
}
}
}
enum class TaskStatus(val displayName: String) {
Open("Open"),
InProgress("In Progress"),
Complete("Complete"),
}
open class Task(_name: String = "Task", project: String = "My Project") : RealmObject() {
@PrimaryKey
var _id: ObjectId = ObjectId()
var name: String = _name
@Required
var status: String = TaskStatus.Open.name
var statusEnum: TaskStatus
get() {
// because status is actually a String and another client could assign an invalid value,
// default the status to "Open" if the status is unreadable
return try {
TaskStatus.valueOf(status)
} catch (e: IllegalArgumentException) {
TaskStatus.Open
}
}
set(value) { status = value.name }
}

运行上述代码应产生类似以下内容的输出:

Successfully authenticated anonymously.
Updated range: 0 to 1
Deleted range: 0 to 1
Successfully logged out.

来年

欢迎使用 Atlas Device SDK 文档