Docs Menu
Docs Home
/ /
Atlas Device SDK
/ /

Realm ファイルのバンドル - Java SDK

項目一覧

  • Overview
  • バンドル用の Realm ファイルの作成
  • 本番アプリケーションでの Realm ファイルのバンドル
  • バンドルされた Realm ファイルから Realm を開く

注意

同期された Realm のバンドル

SDK バージョン 10.9.0 では、同期された Realm をバンドルする機能が導入されました。 バージョン 10.9.0 より前は、ローカル Realm のみをバンドルできました。

Realm は Realm ファイルのバンドルをサポートしています。 Realm ファイルをバンドルする場合、データベースとそのすべてのデータをアプリケーションのダウンロードに含めます。

これにより、ユーザーは初期データセットを使用して初めてアプリケーションを起動できます。 同期済み Realm の場合、バンドルにより、ユーザーが初めてアプリケーションを開くときに長時間かかる初期ダウンロードを回避できます。 代わりに、ユーザーは、バンドル ファイルの生成以降に発生した同期された変更のみをダウンロードする必要があります。

重要

同期された Realm のバンドル

バックエンド アプリケーションで Flexible Syncを使用している場合、バンドルされている Realm ファイルを初めて開くときにクライアントがリセットされる可能性があります。 これは、クライアント最大オフライン時間が有効になっている場合に発生する可能性があります(クライアントの最大オフライン時間はデフォルトで有効になっています)。 ユーザーが最初に同期する前に、バンドルされた Realm ファイルがクライアントの最大オフライン時間設定で指定された日数を超えて生成された場合、ユーザーはクライアントをリセットします。

クライアントリセットを実行するアプリケーションは、アプリケーション バックエンドから Realm の完全な状態をダウンロードします。 これにより、Realm ファイルをバンドルする利点が得られません。 クライアントのリセットを防ぎ、Realm ファイルのバンドルの利点を維持するには、次の手順に従います。

  • 同期された Realm をバンドルするアプリケーションでは、クライアントの最大オフライン時間を使用しないでください。

  • アプリケーションがクライアントの最大オフライン時間を使用する場合は、アプリケーションのダウンロードに最近同期された Realm ファイルが常に含まれていることを確認してください。 アプリケーション バージョンごとに新しい ファイルを生成し、クライアントの最大オフライン時間数を超えてどのバージョンも最新の状態に維持します。

Realm ファイルを作成してアプリケーションにバンドルするには、次の手順に従います。

  1. バンドルするデータを含むRealm ファイルを作成します

  2. Realm ファイルは本番アプリケーションの/<app name>/src/main/assetsフォルダーにバンドルします。

  3. 本番アプリケーションで、バンドルされた アセット ファイル から Realm を開きます。 同期された Realm の場合は、パーティションキーを指定する必要があります。

注意

同じタイプの同期のみ

このメソッドは、別のパーティションベースの同期ユーザーのパーティションベースの同期構成、または別の Flexible Sync ユーザーの Flexible Sync 構成のコピーのみをサポートします。 このメソッドを使用して、 パーティションベースの同期 Realm と Flexible Sync レルムの間で、またはその逆に変換することはできません。

  1. アプリケーションのデータモデルを共有する一時的な Realm アプリを構築します。

  2. Realm を開き、バンドルするデータを追加します。 同期された Realm を使用する場合は、Realm が完全に同期するまで時間を待ちます。

  3. writeCopyTo()メソッドを使用して、Realm を新しいファイルにコピーします。

    String appID = YOUR_APP_ID; // replace this with your App ID
    App app = new App(appID);
    Credentials anonymousCredentials = Credentials.anonymous();
    app.loginAsync(anonymousCredentials, it -> {
    if (it.isSuccess()) {
    Log.v("EXAMPLE", "Successfully authenticated anonymously.");
    String PARTITION = "PARTITION_YOU_WANT_TO_BUNDLE";
    // you can only create realm copies on a background thread with a looper.
    // HandlerThread provides a Looper-equipped thread.
    HandlerThread handlerThread = new HandlerThread("CopyARealmHandler");
    handlerThread.start();
    Handler handler = new Handler(handlerThread.getLooper());
    handler.post(new Thread(new Runnable() { @Override public void run() {
    SyncConfiguration config = new SyncConfiguration.Builder(app.currentUser(), PARTITION)
    // wait for the realm to download all data from the backend before opening
    .waitForInitialRemoteData()
    .build();
    Realm realm = Realm.getInstance(config);
    Log.v("EXAMPLE", "Successfully opened a realm.");
    // write a copy of the realm you can manually copy to your production application assets
    File outputDir = activity.getApplicationContext().getCacheDir();
    File outputFile = new File(outputDir.getPath() + "/" + PARTITION + "_bundled.realm");
    // ensure all local changes have synced to the backend
    try {
    app.getSync().getSession(config).uploadAllLocalChanges(10000, TimeUnit.MILLISECONDS);
    } catch (InterruptedException e) {
    e.printStackTrace();
    }
    // cannot write to file if it already exists. Delete the file if already there
    outputFile.delete();
    realm.writeCopyTo(outputFile);
    // search for this log line to find the location of the realm copy
    Log.i("EXAMPLE", "Wrote copy of realm to " + outputFile.getAbsolutePath());
    // always close a realm when you're done using it
    realm.close();
    }}));
    } else {
    Log.e("EXAMPLE", "Failed to authenticate: " + it.getError().toString());
    }
    });
    val appID: String = YOUR_APP_ID // replace this with your App ID
    val app = App(appID)
    val anonymousCredentials = Credentials.anonymous()
    app.loginAsync(anonymousCredentials) { it: App.Result<User?> ->
    if (it.isSuccess) {
    Log.v("EXAMPLE", "Successfully authenticated anonymously.")
    val PARTITION = "PARTITION_YOU_WANT_TO_BUNDLE"
    // you can only create realm copies on a background thread with a looper.
    // HandlerThread provides a Looper-equipped thread.
    val handlerThread = HandlerThread("CopyARealmHandler")
    handlerThread.start()
    val handler = Handler(handlerThread.looper)
    handler.post(Thread {
    val config = SyncConfiguration.Builder(app.currentUser(), PARTITION)
    // wait for the realm to download all data from the backend before opening
    .waitForInitialRemoteData()
    .build()
    val realm : Realm = Realm.getInstance(config);
    Log.v("EXAMPLE", "Successfully opened a realm.")
    // write a copy of the realm you can manually copy to your production application assets
    val outputDir = activity!!.applicationContext.cacheDir
    val outputFile =
    File(outputDir.path + "/" + PARTITION + "_bundled.realm")
    // ensure all local changes have synced to the backend
    try {
    app.sync.getSession(config)
    .uploadAllLocalChanges(10000, TimeUnit.MILLISECONDS)
    } catch (e: InterruptedException) {
    e.printStackTrace()
    }
    // cannot write to file if it already exists. Delete the file if already there
    outputFile.delete()
    realm.writeCopyTo(outputFile)
    // search for this log line to find the location of the realm copy
    Log.i("EXAMPLE", "Wrote copy of realm to " + outputFile.absolutePath)
    // always close a realm when you're done using it
    realm.close()
    })
    } else {
    Log.e("EXAMPLE", "Failed to authenticate: ${it.error}")
    }
    }

    writeCopyTo() は、コピーする前に Realm を可能な限り最小のサイズに自動的に圧縮します。

    Tip

    同期された Realm とローカル専用 Realm の違い

    上記の例では、 SyncConfigurationを使用して同期された Realm を構成しています。 ローカル Realm のコピーを作成するには、代わりにRealmConfigurationを使用して Realm を構成します。

初期データを含む Realm のコピーが用意できたら、それを本番アプリケーションにバンドルします。

  1. アプリケーション ログを検索して、作成した Realm ファイルのコピーの場所を見つけます。

  2. Android Studio ウィンドウの右下にある「Device ファイル エクスプローラー」ウィジェットを使用して、 ファイルに移動します。

  3. ファイルを右クリックし、[Save As(名前を付けて保存)] を選択します。 本番アプリケーションの/<app name>/src/main/assetsフォルダーに移動します。 Realm ファイルのコピーをそこに保存します。

Tip

アセット フォルダー

アプリケーションにアセット フォルダーがまだ含まれていない場合は、Android Studio で最上位のアプリケーション フォルダー( <app name> )を右クリックし、[] メニューで [ New > Folder > Assets Folderを選択します。

本番アプリケーションに含まれる Realm のコピーが作成できたら、それを使用するためのコードを追加する必要があります。 バンドルされた ファイルからRealmを開くようにRealmを構成するときは、 assetFile()メソッドを使用します。

String appID = YOUR_APP_ID; // replace this with your App ID
App app = new App(appID);
Credentials anonymousCredentials = Credentials.anonymous();
app.loginAsync(anonymousCredentials, it -> {
if (it.isSuccess()) {
Log.v("EXAMPLE", "Successfully authenticated anonymously.");
// asset file name should correspond to the name of the bundled file
SyncConfiguration config = new SyncConfiguration.Builder(
app.currentUser(),
"PARTITION_YOU_WANT_TO_BUNDLE")
.assetFile("example_bundled.realm")
.build();
Realm realm = Realm.getInstance(config);
Log.v("EXAMPLE", "Successfully opened bundled realm.");
// read and write to the bundled realm as normal
realm.executeTransactionAsync(transactionRealm -> {
Frog frog = new Frog(new ObjectId(),
"Asimov",
4,
"red eyed tree frog",
"Spike");
transactionRealm.insert(frog);
expectation.fulfill();
});
} else {
Log.e("EXAMPLE", "Failed to authenticate: " + it.getError().toString());
}
});
val appID: String = YOUR_APP_ID // replace this with your App ID
val app = App(appID)
val anonymousCredentials = Credentials.anonymous()
app.loginAsync(anonymousCredentials) { it: App.Result<User?> ->
if (it.isSuccess) {
Log.v("EXAMPLE", "Successfully authenticated anonymously.")
// asset file name should correspond to the name of the bundled file
val config = SyncConfiguration.Builder(
app.currentUser(),
"PARTITION_YOU_WANT_TO_BUNDLE")
.assetFile("example_bundled.realm")
.build()
val realm: Realm = Realm.getInstance(config)
Log.v("EXAMPLE", "Successfully opened bundled realm.")
// read and write to the bundled realm as normal
realm.executeTransactionAsync { transactionRealm: Realm ->
val frog = Frog(
ObjectId(),
"Asimov",
4,
"red eyed tree frog",
"Spike"
)
transactionRealm.insert(frog)
expectation.fulfill()
}
} else {
Log.e("EXAMPLE", "Failed to authenticate: ${it.error}")
}
}

Tip

同期された Realm とローカル専用 Realm の違い

上記の例では、 SyncConfigurationを使用して同期された Realm を構成しています。 ローカル Realm のコピーを作成するには、代わりにRealmConfigurationを使用して Realm を構成します。

戻る

Realm のオープンと閉じます