同期のクイックスタート - Java SDK
Tip
このガイドでは Device Sync を使用します
このガイドは、アプリ バックエンドと通信する Android アプリケーションを使い始めるのに役立ちます。 このアプリは、 Sync 、Realm Functions、ユーザー管理などの機能を提供します。 アプリケーションでローカル データベース機能のみが必要な場合は、「クイック スタート(ローカルのみ) 」ガイドを確認してください。
このページには、Atlas App Services をすばやくアプリに統合するための情報が含まれています。 始める前に、以下のものがあることを確認してください。
Realm の初期化
アプリで Realm を使用する前に、Realm ライブラリを初期化する必要があります。 アプリケーションは、アプリケーションを実行するたびに Realm を 1 回だけ初期化する必要があります。
Realm ライブラリを初期化するには、 Realm.init()
静的関数に Android context
を指定します。 初期化用のアクティビティ、フラグメント、またはアプリケーションcontext
を指定すると、動作に違いはありません。 Realm ライブラリは、onCreate()
アプリケーション サブクラス の メソッドで初期化できます。 アプリケーションを実行するたびに、Realm を 1 回だけ初期化するようにします。
Realm.init(this); // context, usually an Activity or Application
Realm.init(this) // context, usually an Activity or Application
Tip
Android マニフェストでのアプリケーション サブクラスの登録
独自のApplication
サブクラスを作成する場合は、カスタム アプリケーション ロジックを実行するためにアプリケーションのAndroidManifest.xml
にそれを追加する必要があります。 マニフェストのアプリケーション定義のandroid.name
プロパティを設定して、ユーザーがアプリケーションを起動したときに Android が他のクラスよりも先にApplication
サブクラスをインスタンス化するようにします。
<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 にアクセスします。 アプリ ID は、App Services UI で確認できます。
app = new App(new AppConfiguration.Builder(appID) .build());
val appID : String = YOUR_APP_ID; app = App(AppConfiguration.Builder(appID) .build())
注意
Android Studio エラー
Android Studio がRealm
、 App
、またはAppConfiguration
型を認識しない場合は、 Gradle ビルド構成に問題がある可能性があります。 この問題を修正するには、以下の手順を行います。
次を使用してプロジェクトをクリーンアップします:
Build > Clean Project
更新された
build.gradle
ファイルに基づいてBuild > Rebuild Project
を使用してプロジェクトを再構築します。「 Java SDK のインストール」ガイドを再度開き、依存関係が正しくインストールされたことを確認します。
オブジェクトモデルを定義する
アプリケーションのデータモデルは、Realm 内に保存され、App Services と同期されるデータの構造を定義します。 アプリケーションのデータモデルは、次の 2 つの方法で定義できます。
App Services のスキーマ経由。
このクイック スタートでは、モバイル アプリケーションのコードで クラスを使用してスキーマを定義する後者のアプローチを使用します。 この方法でアプリのオブジェクトモデルを定義するには、開発モード を有効にする必要があります。
開発モードを有効にしたら、次のクラス定義をアプリケーション コードに追加します。
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 { private ObjectId _id = new ObjectId(); private String name = "Task"; 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() { var _id: ObjectId = ObjectId() var name: String = _name 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 UI で匿名認証を有効にした場合、ユーザーは識別情報を提供せずにアプリにすぐにログインできます。
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 は、ユーザーを認証、登録、リンクするための多くの追加の方法を提供します。
Realm を開く
同期を有効にしてユーザーを認証したら、同期されたRealmを開くことができます。 SyncConfiguration
を使用して、タイムアウト、同期読み取りと UI スレッドでの書込み (write) など、アプリケーションが 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)
オブジェクトの作成、読み取り、更新、削除
Realm を開くと、書込みトランザクション ( write transaction ) ブロックでその Realm 内の オブジェクト を変更できます。
重要
UI スレッドでの同期読み取りと書込み
デフォルトでは、非同期トランザクションを使用して、アプリケーションの UI スレッド内の Realm の読み取りまたは書き込みのみが可能です。 つまり、同期メソッドの使用を明示的に許可しない限り、Android アプリケーションのメイン スレッドでは、名前がAsync
という単語で終わるRealm
メソッドのみを使用できます。
この制限はアプリケーション ユーザーのメリットのために存在します。UI スレッドで読み取りおよび書込み操作を実行すると、UI のインタラクションが応答しなくなったり低速になったりする可能性があるため、通常、これらの操作は非同期またはバックグラウンド スレッドで取り扱うことをお勧めします。 ただし、アプリケーションで同期 Realm の読み取りまたは UI スレッドでの書込みを使用する必要がある場合は、次のSyncConfiguration
オプションを使用して同期メソッドの使用を明示的に許可できます。
SyncConfiguration config = new SyncConfiguration.Builder(app.currentUser(), PARTITION) .allowQueriesOnUiThread(true) .allowWritesOnUiThread(true) .build(); Realm.getInstanceAsync(config, new Realm.Callback() { 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) }
Realm 内のすべてのアイテムのライブコレクションを取得できます。
// 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 }
最後に、書込みトランザクション ブロックで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
をアタッチすると、Realm、コレクション、またはオブジェクトの変更を監視できます。
// all tasks in the realm RealmResults<Task> tasks = uiThreadRealm.where(Task.class).findAllAsync(); tasks.addChangeListener(new OrderedRealmCollectionChangeListener<RealmResults<Task>>() { 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 を Realm アプリ ID に置き換えて、完全な例を実行します。 このプロジェクトを新しい Android Studio プロジェクトで実行している場合は、このファイルをコピーして、アプリケーションのMainActivity
に貼り付けることができます。次の操作だけを忘れずに。
プロジェクトに一致するようにパッケージ宣言を変更します
アプリ ID プレースホルダーをアプリのアプリ ID に置き換え
Java を使用している場合は、
Task
とTaskStatus
のimport
ステートメントを更新
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 { private ObjectId _id = new ObjectId(); private String name = "Task"; 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; } }
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; 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>>() { 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)); } } }); } 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; } 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(); } } }
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() { var _id: ObjectId = ObjectId() var name: String = _name 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.