バックグラウンドで Realm を同期する - Java SDK
アプリが実行されていないときにデータを同期する必要がある場合は、バックグラウンド プロセスで Realm を同期できます。
前提条件
バックグラウンド同期を開始するには、次の依存関係を Android アプリケーションに追加する必要があります。
mongos.work:work-runtime 、ジョブを確保します
mongostats 、バックグラウンド ワーカーからジョブの結果を返す
例
バックグラウンド同期には、次の 2 つの条件が必要です。
同期ロジック
そのロジックを定期的に実行するスケジュールされたジョブ。
同期ロジック
まず、Realm を同期するカスタム ロジックを記述します。 このロジックをバックエンドへのスタンドアロン接続として扱います。 その結果、次の操作が必要になります。
Realm SDK を初期化する
Realm を開くためのユーザーの認証
ユーザーが最近アプリを使用した場合は、そのユーザーのキャッシュされた認証情報を使用できます。
Realm を開き、 SyncSession. DownloadAllServerChecks()を使用します およびSyncSession.uploadAllLocalchanges()を使用して、Realm をバックエンドと完全に同期します。
このロジックは listenableServer のサブクラスを使用して、バックグラウンド プロセスとして実行できます。 。同期ロジックをワーカーの startWork()
メソッドに配置します。
import android.annotation.SuppressLint; import android.content.Context; import android.util.Log; import androidx.annotation.NonNull; import androidx.concurrent.futures.ResolvableFuture; import androidx.work.ListenableWorker; import androidx.work.WorkerParameters; import com.google.common.util.concurrent.ListenableFuture; import java.util.concurrent.TimeUnit; import io.realm.Realm; 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; public class RealmBackgroundWorker extends ListenableWorker { static final String UNIQUE_WORK_NAME = "RealmBackgroundWorker"; private ResolvableFuture<Result> future; public RealmBackgroundWorker( Context context, WorkerParameters workerParams) { super(context, workerParams); } public ListenableFuture<Result> startWork() { future = ResolvableFuture.create(); Realm.init(this.getApplicationContext()); String appID = YOUR_APP_ID; // replace this with your App ID App app = new App(new AppConfiguration.Builder(appID).build()); Credentials credentials = Credentials.anonymous(); app.loginAsync(credentials, it -> { if (it.isSuccess()) { Log.v("EXAMPLE", "Successfully authenticated."); User user = app.currentUser(); SyncConfiguration config = new SyncConfiguration.Builder(user, "PARTITION") .build(); Realm.getInstanceAsync(config, new Realm.Callback() { public void onSuccess(Realm realm) { Log.v("EXAMPLE", "Successfully opened a realm for background synchronization."); try { app.getSync().getSession(config).downloadAllServerChanges(); app.getSync().getSession(config).uploadAllLocalChanges(); } catch (InterruptedException e) { e.printStackTrace(); } } }); } else { Log.e("EXAMPLE", "Failed login: " + it.getError().getErrorMessage()); } }); return future; } }
import android.annotation.SuppressLint import android.content.Context import android.util.Log import androidx.concurrent.futures.ResolvableFuture import androidx.work.ListenableWorker import androidx.work.WorkerParameters import com.google.common.util.concurrent.ListenableFuture import io.realm.Realm 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.TimeUnit class RealmBackgroundWorker(context: Context, workerParams: WorkerParameters) : ListenableWorker(context, workerParams) { private lateinit var future: ResolvableFuture<Result> override fun startWork(): ListenableFuture<Result> { future = ResolvableFuture.create() Realm.init(this.applicationContext) val appID = YOUR_APP_ID // replace this with your App ID val app = App(AppConfiguration.Builder(appID).build()) val credentials = Credentials.anonymous() app.loginAsync(credentials) { it: App.Result<User?> -> if (it.isSuccess) { Log.v("EXAMPLE", "Successfully authenticated.") val user = app.currentUser() val config = SyncConfiguration.Builder(user, "PARTITION") .build() Realm.getInstanceAsync(config, object : Realm.Callback() { override fun onSuccess(realm: Realm) { Log.v("EXAMPLE", "Successfully opened a realm for background synchronization.") try { app.sync.getSession(config).downloadAllServerChanges() app.sync.getSession(config).uploadAllLocalChanges() } catch (e: InterruptedException) { e.printStackTrace() } } }) } else { Log.e("EXAMPLE", "Failed login: " + it.error.errorMessage) } } return future } companion object { const val UNIQUE_WORK_NAME = "RealmBackgroundWorker" } }
ワーカー
バックグラウンド同期を定期的に実行するワーカーを作成するには、次の手順に従います。
ワーカーに必要な条件を指定する制約のセットを作成します。
ワーカーが実行する頻度を指定します。
Android OS でワーカーを使用します。 将来的にそのジョブをアップデートできるように、そのジョブに一意の識別子を割り当てます。
アプリ内のアプリケーション サブクラス内にバックグラウンド同期ジョブを作成すると、アプリケーションを実行するたびにロジックが 1 回のみ実行されることが保証されます。
Realm の同期ではデータが使用されるため、デバイスが でない場合は、バックグラウンドでの変更のみをダウンロードすることを検討してください。
低容量
測定データソースを使用する
使用 制約 バックグラウンド同期が実行される環境を説明します。
繰り返しの間隔は、Realm 内のデータが更新される頻度と、ユーザーがアプリケーションを開く頻度によって異なります。 Realm が 1 日を通して頻繁に更新される場合は、1 時間から 3 時間の繰り返しの間隔を設定することを検討してください。 Realm が毎日更新する回数が少ない場合は、繰り返しの間隔を長くして、バックグラウンド同期を 1 日 1 回または 2 回にすることをお勧めします。
Constraints constraints = new Constraints.Builder() .setRequiredNetworkType(NetworkType.UNMETERED) .setRequiresBatteryNotLow(true) .build(); PeriodicWorkRequest backgroundRealmSync = new PeriodicWorkRequest .Builder(RealmBackgroundWorker.class, // repeat every 12 hours 12, TimeUnit.HOURS, // execute job at any point during that 12 hour period 12, TimeUnit.HOURS) .setConstraints(constraints) .build(); // enqueue the work job, replacing it with the most recent version if we update it WorkManager.getInstance(this).enqueueUniquePeriodicWork( RealmBackgroundWorker.UNIQUE_WORK_NAME, ExistingPeriodicWorkPolicy.REPLACE, backgroundRealmSync);
val constraints: Constraints = Constraints.Builder() .setRequiredNetworkType(NetworkType.UNMETERED) .setRequiresBatteryNotLow(true) .build() val backgroundRealmSync: PeriodicWorkRequest = PeriodicWorkRequest.Builder( RealmBackgroundWorker::class.java, // repeat every 12 hours 12, TimeUnit.HOURS, // execute job at any point during that 12 hour period 12, TimeUnit.HOURS ) .setConstraints(constraints) .build() // enqueue the work job, replacing it with the most recent version if we update it WorkManager.getInstance(this).enqueueUniquePeriodicWork( RealmBackgroundWorker.UNIQUE_WORK_NAME, ExistingPeriodicWorkPolicy.REPLACE, backgroundRealmSync )