Interacting with realms in an Android application uses the following high-level series of steps:
Create a configuration for the realm you want to open.
Open the realm using the config.
Cierra el realm para liberar recursos cuando hayas terminado.
El Realm por defecto
Puede guardar cualquier RealmConfiguration o SyncConfiguration como predeterminada para su aplicación utilizando el método setDefaultConfiguration():
RealmConfiguration config = new RealmConfiguration.Builder() .name("default-realm") .allowQueriesOnUiThread(true) .allowWritesOnUiThread(true) .compactOnLaunch() .inMemory() .build(); // set this config as the default realm Realm.setDefaultConfiguration(config);
val config = RealmConfiguration.Builder() .name("default-realm") .allowQueriesOnUiThread(true) .allowWritesOnUiThread(true) .compactOnLaunch() .inMemory() .build() // set this config as the default realm Realm.setDefaultConfiguration(config)
Luego puede usar getDefaultConfiguration() para acceder a esa configuración, o getDefaultInstance() para abrir un reino con esa configuración:
Realm realm = Realm.getDefaultInstance(); Log.v("EXAMPLE","Successfully opened the default realm at: " + realm.getPath());
val realm = Realm.getDefaultInstance() Log.v("EXAMPLE","Successfully opened the default realm at: ${realm.path}")
Dominios locales
Los dominios locales almacenan datos solo en el dispositivo cliente. Puedes personalizar la configuración de un dominio local con RealmConfiguration.
Configuración de Realm local
To configure settings for a realm, create a RealmConfiguration with a RealmConfiguration.Builder. The following example configures a local realm with:
the file name "alternate-realm"
Lecturas sincrónicas permitidas explícitamente en el hilo de UI
Escrituras sincrónicas permitidas explícitamente en el hilo de UI
automatic compaction when launching the realm to save file space
RealmConfiguration config = new RealmConfiguration.Builder() .name("alternate-realm") .allowQueriesOnUiThread(true) .allowWritesOnUiThread(true) .compactOnLaunch() .build(); Realm realm = Realm.getInstance(config); Log.v("EXAMPLE", "Successfully opened a realm at: " + realm.getPath());
val config = RealmConfiguration.Builder() .name("alternate-realm") .allowQueriesOnUiThread(true) .allowWritesOnUiThread(true) .compactOnLaunch() .build() val realm = Realm.getInstance(config) Log.v("EXAMPLE", "Successfully opened a realm at: ${realm.path}")
Importante
Synchronous Reads and Writes on the UI Thread
By default, you can only read or write to a realm in your application's UI thread using asynchronous transactions. That is, you can only use Realm methods whose name ends with the word Async in the main thread of your Android application unless you explicitly allow the use of synchronous methods.
Esta restricción existe en beneficio de los usuarios de tu aplicación: realizar operaciones de lectura y escritura en el hilo de la Interfaz de Usuario puede generar interacciones lentas o no respondidas en la Interfaz de Usuario, por lo que generalmente es mejor gestionar estas operaciones de manera asíncrona o en un hilo en segundo plano. Sin embargo, si tu aplicación requiere el uso de lecturas o escrituras de realm síncronas en el hilo de la IU, puedes permitir explícitamente el uso de métodos síncronos con las siguientes opciones SyncConfiguration:
SyncConfiguration config = new SyncConfiguration.Builder(app.currentUser(), PARTITION) .allowQueriesOnUiThread(true) .allowWritesOnUiThread(true) .build(); Realm.getInstanceAsync(config, new Realm.Callback() { public void onSuccess(Realm realm) { Log.v( "EXAMPLE", "Successfully opened a realm with reads and writes allowed on the UI thread." ); } });
val config = SyncConfiguration.Builder(app.currentUser(), PARTITION) .allowQueriesOnUiThread(true) .allowWritesOnUiThread(true) .build() Realm.getInstanceAsync(config, object : Realm.Callback() { override fun onSuccess(realm: Realm) { Log.v("EXAMPLE", "Successfully opened a realm with reads and writes allowed on the UI thread.") } })
Abrir un Realm local
Para abrir un realm, crea una RealmConfiguration con RealmConfiguration.Builder y pasar el RealmConfiguration resultante a getInstance() o getInstanceAsync():
RealmConfiguration config = new RealmConfiguration.Builder() .allowQueriesOnUiThread(true) .allowWritesOnUiThread(true) .build(); Realm realm; try { realm = Realm.getInstance(config); Log.v("EXAMPLE", "Successfully opened a realm at: " + realm.getPath()); } catch (RealmFileException ex) { Log.v("EXAMPLE", "Error opening the realm."); Log.v("EXAMPLE", ex.toString()); }
val config = RealmConfiguration.Builder() .allowQueriesOnUiThread(true) .allowWritesOnUiThread(true) .build() var realm: Realm try { realm = Realm.getInstance(config) Log.v("EXAMPLE", "Successfully opened a realm at: ${realm.path}") } catch(ex: RealmFileException) { Log.v("EXAMPLE", "Error opening the realm.") Log.v("EXAMPLE", ex.toString()) }
Read-Only Realms
It's sometimes useful to ship a prepared realm file with your app that contains shared data that does not frequently change. You can use the readOnly() method when configuring your realm to make it read-only. This can prevent accidental writes to the realm and causes the realm to throw an IllegalStateException if a write occurs.
Advertencia
Los archivos de Realm de solo lectura son escribibles
Los reinos de solo lectura se aplican solo como de solo lectura durante el proceso. El propio archivo Realm aún es editable.
RealmConfiguration config = new RealmConfiguration.Builder() .assetFile("bundled.realm") .readOnly() .modules(new BundledRealmModule()) .build();
val config = RealmConfiguration.Builder() .assetFile("readonly.realm") .readOnly() .modules(BundledRealmModule()) .build()
Dominios en memoria
Puedes crear un dominio que se ejecute completamente en memoria sin escribirse en un archivo. Cuando la memoria de un dispositivo Android es baja, los dominios en memoria pueden intercambiarse. Se transfieren temporalmente de la memoria principal al espacio en disco. El SDK elimina todos los archivos creados por un dominio en memoria cuando:
the realm closes
todas las referencias a ese realm quedan fuera de alcance
Para crear un realm en memoria, utiliza inMemory() al configurar tu realm:
RealmConfiguration config = new RealmConfiguration.Builder() .inMemory() .name("java.transient.realm") .build(); Realm realm = Realm.getInstance(config);
val config = RealmConfiguration.Builder() .inMemory() .name("kt.transient.realm") .build() val realm = Realm.getInstance(config)
Dynamic Realms
Los dominios convencionales definen un esquema mediante RealmObject subclases o la RealmModel interfaz. Un DynamicRealm utiliza cadenas para definir un esquema en tiempo de ejecución. Al abrir un dominio dinámico, se utiliza la misma configuración que un dominio convencional, pero los dominios dinámicos ignoran todos los esquemas, migraciones y versiones de esquema configurados.
Los dominios dinámicos ofrecen flexibilidad a costa de la seguridad de tipos y el rendimiento. Por lo tanto, úselos solo cuando sea necesaria, como durante migraciones, restablecimientos manuales de clientes y al trabajar con datos basados en cadenas, como archivos CSV o JSON.
Para abrir un Dynamic Realm con un esquema mutable, utiliza DynamicRealm:
RealmConfiguration config = new RealmConfiguration.Builder() .allowWritesOnUiThread(true) .allowQueriesOnUiThread(true) .name("java.dynamic.realm") .build(); DynamicRealm dynamicRealm = DynamicRealm.getInstance(config); // all objects in a DynamicRealm are DynamicRealmObjects AtomicReference<DynamicRealmObject> frog = new AtomicReference<>(); dynamicRealm.executeTransaction(transactionDynamicRealm -> { // add type Frog to the schema with name and age fields dynamicRealm.getSchema() .create("Frog") .addField("name", String.class) .addField("age", int.class); frog.set(transactionDynamicRealm.createObject("Frog")); frog.get().set("name", "Wirt Jr."); frog.get().set("age", 42); }); // access all fields in a DynamicRealm using strings String name = frog.get().getString("name"); int age = frog.get().getInt("age"); // because an underlying schema still exists, // accessing a field that does not exist throws an exception try { frog.get().getString("doesn't exist"); } catch (IllegalArgumentException e) { Log.e("EXAMPLE", "That field doesn't exist."); } // Queries still work normally RealmResults<DynamicRealmObject> frogs = dynamicRealm.where("Frog") .equalTo("name", "Wirt Jr.") .findAll();
val config = RealmConfiguration.Builder() .allowWritesOnUiThread(true) .allowQueriesOnUiThread(true) .name("kt.dynamic.realm") .build() val dynamicRealm = DynamicRealm.getInstance(config) // all objects in a DynamicRealm are DynamicRealmObjects var frog: DynamicRealmObject? = null dynamicRealm.executeTransaction { transactionDynamicRealm: DynamicRealm -> // add type Frog to the schema with name and age fields dynamicRealm.schema .create("Frog") .addField("name", String::class.java) .addField("age", Integer::class.java) frog = transactionDynamicRealm.createObject("Frog") frog?.set("name", "Wirt Jr.") frog?.set("age", 42) } // access all fields in a DynamicRealm using strings val name = frog?.getString("name") val age = frog?.getInt("age") // because an underlying schema still exists, // accessing a field that does not exist throws an exception try { frog?.getString("doesn't exist") } catch (e: IllegalArgumentException) { Log.e("EXAMPLE", "That field doesn't exist.") } // Queries still work normally val frogs = dynamicRealm.where("Frog") .equalTo("name", "Wirt Jr.") .findAll()
Close a Realm
Es importante recordar llamar al método close() al terminar con una instancia de reino para liberar recursos. No cerrar los reinos puede generar un error.OutOfMemoryError
realm.close();
realm.close()
Configure Which Classes to Include in Your Realm Schema
Realm modules are collections of Realm object models. Specify a module or modules when opening a realm to control which classes Realm should include in your schema. If you do not specify a module, Realm uses the default module, which includes all Realm objects defined in your application.
Nota
Libraries that include Realm must expose and use their schema through a module. Doing so prevents the library from generating the default RealmModule, which would conflict with the default RealmModule used by any app that includes the library. Apps using the library access library classes through the module.
// A library must create a module and set library = true. This will prevent the default // module from being created. // allClasses = true can be used instead of listing all classes in the library. public class MyLibraryModule {} // ... // Library projects are therefore required to explicitly set their own module. SyncConfiguration libraryConfig = new SyncConfiguration.Builder(app.currentUser(), LIBRARY_PARTITION) .modules(new MyLibraryModule()) .build(); // Apps can add the library RealmModule to their own schema. SyncConfiguration config = new SyncConfiguration.Builder(app.currentUser(), PARTITION) .modules(Realm.getDefaultModule(), new MyLibraryModule()) .build();
// A library must create a module and set library = true. This will prevent the default // module from being created. // allClasses = true can be used instead of listing all classes in the library. class MyLibraryModule // ... // Library projects are therefore required to explicitly set their own module. val libraryConfig = SyncConfiguration.Builder(app.currentUser(), LIBRARY_PARTITION) .modules(MyLibraryModule()) .build() // Apps can add the library RealmModule to their own schema. val config = SyncConfiguration.Builder(app.currentUser(), PARTITION) .modules(Realm.getDefaultModule(), MyLibraryModule()) .build()