非同期 API - Java SDK
Java SDK では、ネットワークとディスクのリソースに同期と非同期の 2 つの方法でアクセスできます。 同期中、つまり「同期」では、リクエストが成功または失敗を返すまでブロック実行をリクエストします。非同期、または「async」では、リクエストにコールバックを割り当て、コードの実行を続行します。 リクエストが返すと、コールバックが実行され結果を処理します。 コールバックでは、リクエストが正常に実行されたかどうかを確認し、返された結果または返されたエラーにアクセスできます。
非同期呼び出し
SDK の非同期 API リクエストは、サフィックス「Async」で終了します。 非同期リクエストの動作方法は、使用している SDK のどの部分かに応じて異なります。
Realm.コールバック
同期の使用となしの両方で、Realm を開くための非同期呼び出しでは、 Realm .コールバック 型の最終パラメータが使用されます。 リクエストが完了した後に返された値を検索するには、これらの非同期メソッドの最後のパラメータとして渡されるコールバック オブジェクトに onSuccess()
メソッドを実装します。 リクエストの失敗を処理するためにonError()
メソッドも実装する必要がありますが、これは必須ではありません。
Realm.getInstanceAsync(config, new Realm.Callback() { public void onSuccess( Realm realm) { Log.v("EXAMPLE", "Successfully fetched realm instance."); } public void onError(Exception e) { Log.e("EXAMPLE", "Failed to get realm instance: " + e); } });
Realm.getInstanceAsync(config, object : Realm.Callback() { override fun onSuccess(realm: Realm) { Log.v("EXAMPLE", "Successfully fetched realm instance.") } fun onError(e: java.lang.Exception) { Log.e("EXAMPLE", "Failed to get realm instance: $e") } })
App.コールバック
関数やユーザー認証などの Atlas App Services をクエリする場合、非同期呼び出しはApp.Callback型の最終パラメーターを受け入れます。 このコールバックは、 App.Result型の単一のパラメータを受け入れる Lambda 関数で処理できます。 App.Callback
リクエストから返された値を検索するには:
コールバック関数に渡される
App.Result
のisSuccess()
メソッドを使用して、クエリが正常に完了したかどうかを判断します。クエリが成功した場合は、
get()
メソッドを使用してクエリの結果を取得します。 クエリが失敗した場合は、getError()
を使用して、クエリが失敗した原因となった例外を取得します。
String appID = YOUR_APP_ID; // replace this with your App ID App app = new App(new AppConfiguration.Builder(appID) .build()); Credentials anonymousCredentials = Credentials.anonymous(); AtomicReference<User> user = new AtomicReference<User>(); app.loginAsync(anonymousCredentials, it -> { if (it.isSuccess()) { Log.v("AUTH", "Successfully authenticated anonymously."); user.set(app.currentUser()); } else { Log.e("AUTH", it.getError().toString()); } });
val appID = YOUR_APP_ID // replace this with your App ID val app: App = App( AppConfiguration.Builder(appID) .build() ) val anonymousCredentials: Credentials = Credentials.anonymous() var user: User? app.loginAsync(anonymousCredentials) { if (it.isSuccess) { Log.v("AUTH", "Successfully authenticated anonymously.") user = app.currentUser() } else { Log.e("AUTH", it.error.toString()) } }
RealmAsyncTask
Realm でトランザクションを実行するための非同期呼び出しは、 RealmAsyncTaskのインスタンスを返します。 オプションで、非同期呼び出しに追加のパラメータを渡すことで、 RealmAsyncTask
のエラー ハンドラーまたは成功通知を指定できます。 さらに、トランザクションの完了を停止するには、 Cancel()メソッドを使用します。 RealmAsyncTask
に渡される Lambda 関数には、トランザクションに含める書込み操作が含まれています。
// transaction logic, success notification, error handler all via lambdas realm.executeTransactionAsync(transactionRealm -> { Item item = transactionRealm.createObject(Item.class); }, () -> { Log.v("EXAMPLE", "Successfully completed the transaction"); }, error -> { Log.e("EXAMPLE", "Failed the transaction: " + error); }); // using class instances for transaction, success, error realm.executeTransactionAsync(new Realm.Transaction() { public void execute(Realm transactionRealm) { Item item = transactionRealm.createObject(Item.class); } }, new Realm.Transaction.OnSuccess() { public void onSuccess() { Log.v("EXAMPLE", "Successfully completed the transaction"); } }, new Realm.Transaction.OnError() { public void onError(Throwable error) { Log.e("EXAMPLE", "Failed the transaction: " + error); } });
// using class instances for transaction, success, error realm.executeTransactionAsync(Realm.Transaction { transactionRealm -> val item: Item = transactionRealm.createObject<Item>() }, Realm.Transaction.OnSuccess { Log.v("EXAMPLE", "Successfully completed the transaction") }, Realm.Transaction.OnError { error -> Log.e("EXAMPLE", "Failed the transaction: $error") }) // transaction logic, success notification, error handler all via lambdas realm.executeTransactionAsync( { transactionRealm -> val item = transactionRealm.createObject<Item>() }, { Log.v("EXAMPLE", "Successfully completed the transaction") }, { error -> Log.e("EXAMPLE", "Failed the transaction: $error") })
RealmResults
findAllAsync()を使用した Realm からの非同期読み取りでは、空のRealmResultsインスタンスがすぐに返されます。 SDK はバックグラウンド スレッドでクエリを実行し、クエリが完了するとRealmResults
インスタンスに結果を入力します。 addCheckLister()を使用してリスナーを登録し、クエリが完了したときに通知を受け取ることができます。
RealmResults<Item> items = realm.where(Item.class).findAllAsync(); // length of items is zero when initially returned items.addChangeListener(new RealmChangeListener<RealmResults<Item>>() { public void onChange(RealmResults<Item> items) { Log.v("EXAMPLE", "Completed the query."); // items results now contains all matched objects (more than zero) } });
val items = realm.where<Item>().findAllAsync() // length of items is zero when initially returned items.addChangeListener(RealmChangeListener { Log.v("EXAMPLE", "Completed the query.") // items results now contains all matched objects (more than zero) })
RealmResultTask
Atlas への非同期クエリは、 RealmResultTaskのインスタンスを返します。 RealmResultTask
インスタンスはRealmAsyncTask
と同様にキャンセルできます。 クエリによって返される値にアクセスするには、次のコマンドを使用します。
操作が完了するまでブロックするget()
getAsync()は、 App.Callbackインスタンスを介して結果を処理します
Document queryFilter = new Document("type", "perennial"); mongoCollection.findOne(queryFilter).getAsync(task -> { if (task.isSuccess()) { Plant result = task.get(); Log.v("EXAMPLE", "successfully found a document: " + result); } else { Log.e("EXAMPLE", "failed to find document with: ", task.getError()); } });
val queryFilter = Document("type", "perennial") mongoCollection.findOne(queryFilter) .getAsync { task -> if (task.isSuccess) { val result = task.get() Log.v("EXAMPLE", "successfully found a document: $result") } else { Log.e("EXAMPLE", "failed to find document with: ${task.error}") } }
コルーチン
SDKは、コールバックの代わりにコルーチンとフローを使用して非同期にリクエストするためのKotlin 拡張機能のセットを提供します。 これらの拡張機能を使用すると、トランザクション の実行、変更の監視、読み取り、書込み (write) ができます。
// open a realm asynchronously Realm.getInstanceAsync(config, object : Realm.Callback() { override fun onSuccess(realm: Realm) { Log.v("EXAMPLE", "Successfully fetched realm instance") CoroutineScope(Dispatchers.Main).launch { // asynchronous transaction realm.executeTransactionAwait(Dispatchers.IO) { transactionRealm: Realm -> if (isActive) { val item = transactionRealm.createObject<Item>() } } } // asynchronous query val items: Flow<RealmResults<Item>> = realm.where<Item>().findAllAsync().toFlow() } fun onError(e: Exception) { Log.e("EXAMPLE", "Failed to get realm instance: $e") } })