Docs Menu
Docs Home
/ /
Atlas Device SDK
/ /

バックグラウンドで 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(@NonNull Context context, @NonNull WorkerParameters workerParams) {
super(context, workerParams);
}
@SuppressLint("RestrictedApi")
@NonNull
@Override
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() {
@Override
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>
@SuppressLint("RestrictedApi")
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"
}
}

バックグラウンド同期を定期的に実行するワーカーを作成するには、次の手順に従います。

  1. ワーカーに必要な条件を指定する制約のセットを作成します。

  2. ワーカーが実行する頻度を指定します。

  3. 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
)

戻る

ネットワーク接続の確認