Nota
Bundle Synchronized Realms
SDK version 10.9.0 introduced the ability to bundle synchronized realms. Before version 10.9.0, you could only bundle local realms.
Realm permite agrupar archivos de realm. Al agrupar un archivo de realm, se incluye una base de datos y todos sus datos en la descarga de la aplicación.
This allows users to start applications for the first time with a set of initial data. For synced realms, bundling can avoid a lengthy initial download the first time a user opens your application. Instead, users must only download the synced changes that occurred since you generated the bundled file.
Importante
Agrupación de reinos sincronizados
Si su aplicación backend utiliza Sincronización flexible: los usuarios podrían experimentar un reinicio del cliente la primera vez que abren el archivo de dominio incluido. Esto puede ocurrir cuando el tiempo máximo sin conexión del cliente está habilitado (esta opción está habilitada por defecto). Si el archivo de dominio incluido se generó más de los días especificados en la configuración de tiempo máximo sin conexión del cliente antes de que el usuario sincronice por primera vez, el cliente se reiniciará.
Las aplicaciones que reinician el cliente descargan el estado completo del dominio desde el backend de la aplicación. Esto anula las ventajas de agrupar un archivo de dominio. Para evitar reinicios del cliente y conservar las ventajas de agrupar archivos de dominio:
Evite utilizar un tiempo máximo sin conexión del cliente en aplicaciones que agrupan un reino sincronizado.
Si su aplicación utiliza un tiempo máximo de desconexión del cliente, asegúrese de que la descarga de la aplicación siempre incluya un archivo de dominio sincronizado recientemente. Genere un nuevo archivo con cada versión de la aplicación y asegúrese de que ninguna versión permanezca actualizada durante más días que el tiempo máximo de desconexión del cliente.
Overview
Para crear y agrupar un archivo de reino con su aplicación:
Crea un archivo de reino que contenga los datos que deseas agrupar.
Agrupe el archivo de reino en la
/<app name>/src/main/assetscarpeta de su aplicación de producción.In your production application, open the realm from the bundled asset file. For synced realms, you must supply the partition key.
Nota
Solo sincronización de mismo tipo
This method only supports copying a Partition-Based Sync configuration for another Partition-Based Sync user, or a Flexible Sync configuration for another Flexible Sync user. You cannot use this method to convert between a Partition-Based Sync realm and a Flexible Sync realm or vice-versa.
Crear un archivo de reino para agrupar
Build a temporary realm app that shares the data model of your application.
Open a realm and add the data you wish to bundle. If using a synchronized realm, allow time for the realm to fully sync.
Utiliza el método writeCopyTo() para copiar el realm a un nuevo archivo:
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() { 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()automatically compacts your realm to the smallest possible size before copying.Tip
Diferencias entre los dominios sincronizados y los dominios solo locales
The above example uses a
SyncConfigurationto configure a synchronized realm. To create a copy of a local realm, configure your realm withRealmConfigurationinstead.
Incluya un archivo Realm en su aplicación de producción
Ahora que tiene una copia del reino que contiene los datos iniciales, inclúyalo en su aplicación de producción.
Search your application logs to find the location of the realm file copy you just created.
Using the "Device File Explorer" widget in the bottom right of your Android Studio window, navigate to the file.
Haz clic derecho en el archivo y selecciona 'Guardar Como'. Navega a la carpeta
/<app name>/src/main/assetsde tu aplicación de producción. Guardar una copia del archivo realm allí.
Tip
Asset Folders
Si su aplicación aún no contiene una carpeta de activos, puede crear una haciendo clic derecho en la carpeta de aplicación de nivel superior (<app name>) en Android Studio y seleccionando
New > Folder > Assets Folder en el menú.
Open a Realm from a Bundled Realm File
Now that you have a copy of the realm included with your production application, you need to add code to use it. Use the assetFile() method when configuring your realm to open the realm from the bundled file:
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
Diferencias entre los dominios sincronizados y los dominios solo locales
The above example uses a SyncConfiguration to configure a synchronized realm. To create a copy of a local realm, configure your realm with RealmConfiguration instead.