Abrir e fechar um domínio - SDK Java
Nesta página
A interação com domínios em um aplicativo Android usa a seguinte série de etapas de alto nível:
Crie uma configuração para o domínio que você deseja abrir.
Abra o domínio usando a configuração.
Feche o domínio para liberar recursos quando terminar.
O Realm padrão
Você pode salvar qualquer RealmConfiguration ou SyncConfiguration como padrão para seu aplicativo utilizando o 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)
Em seguida, você pode usar getDefaultConfiguration() para acessar essa configuração ou getDefaultInstance() para abrir um realm com essa configuração:
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}")
Realms locais
Os domínios locais armazenam dados apenas no dispositivo cliente. Você pode personalizar as configurações de um domínio local com RealmConfiguration
.
Configuração de domínio local
Para definir as configurações de um domínio, crie um RealmConfiguration com um RealmConfiguration.Builder. O exemplo a seguir configura um domínio local com:
o nome do arquivo "alternate-realm"
leituras síncronas explicitamente permitidas na thread da interface do usuário
gravações síncronas explicitamente permitidas no thread da interface do usuário
compactação automática ao iniciar o realm para economizar espaço no arquivo
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
Leituras e gravações síncronas na thread da interface do usuário
Por padrão, você só pode ler ou escrever em um realm no thread da UI do aplicativo usando transações assíncronas. Ou seja, você só pode usar métodos Realm
cujo nome termina com a palavra Async
no thread principal do seu aplicativo Android, a menos que você permita explicitamente o uso de métodos síncronos.
Essa restrição existe para o benefício dos usuários do aplicativo: executar operações de leitura e escrita no thread da interface do usuário pode levar a interações de interface do usuário não responsivas ou lentas, portanto, geralmente é melhor lidar com essas operações de forma assíncrona ou em um thread de fundo. No entanto, se o seu aplicativo exigir o uso de leituras ou gravações síncronas de realm no thread da interface do usuário, você poderá permitir explicitamente o uso de métodos síncronos com as seguintes opções 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.") } })
Abra um Realm local
Para abrir um domínio, crie um RealmConfiguration com RealmConfiguration.Builder e passe o RealmConfiguration
resultante para getInstance() ou 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()) }
Realms somente leitura
Às vezes, é útil enviar um arquivo de domínio preparado com seu aplicativo que contém dados compartilhados que não mudam com frequência. Você pode usar o método readOnly() ao configurar seu domínio para torná-lo somente leitura. Isso pode evitar gravações acidentais no realm e faz com que o realm lance um IllegalStateException
se ocorrer uma gravação.
Aviso
Arquivos de Realm somente leitura são graváveis
As regiões somente leitura são impostas apenas como somente leitura no processo. O próprio arquivo de região ainda pode ser gravado.
RealmConfiguration config = new RealmConfiguration.Builder() .assetFile("bundled.realm") .readOnly() .modules(new BundledRealmModule()) .build();
val config = RealmConfiguration.Builder() .assetFile("readonly.realm") .readOnly() .modules(BundledRealmModule()) .build()
Realms na memória
Você pode criar um Realm que é executado inteiramente na memória sem ser escrito em um arquivo. Quando a memória fica baixa em um dispositivo Android, os realms na memória podem trocar temporariamente da memória principal para o espaço em disco. O SDK exclui todos os arquivos criados por um Realm na memória quando:
o realm fecha
todas as referências a esse realm estão fora do escopo
Para criar um realm na memória, use inMemory() ao configurar seu 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)
Domínios dinâmicos
Os domínios convencionais definem um esquema utilizando RealmObject
subclasses ou a interface do RealmModel
. Um DynamicRealm utiliza strings para definir um esquema no tempo de execução. A abertura de um domínio dinâmico utiliza a mesma configuração que um domínio convencional, mas os domínios dinâmicos ignoram todas as versões de esquema, migração e esquema configuradas.
Os domínios dinâmicos oferecem flexibilidade às custas da segurança e do desempenho do tipo. Como resultado, use somente domínios dinâmicos quando essa flexibilidade for necessária, como durante migrações, redefinições manuais de clientes e ao trabalhar com dados baseados em strings, como arquivos CSV ou JSON.
Para abrir um Realm dinâmico com um esquema mutável, use 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()
Fechar um Realm
É importante lembrar de chamar o método close () quando terminar com uma instância de realm para liberar recursos. Negligenciar o fechamento de realms pode levar a um OutOfMemoryError
.
realm.close();
realm.close()
Configure quais classes incluir em seu esquema de domínio
Os módulos do Realm são coleções de modelos de objeto do Realm. Especifique um módulo ou módulos ao abrir um domínio para controlar quais classes o Realm deve incluir em seu esquema. Se você não especificar um módulo, o Realm usará o módulo padrão, que inclui todos os objetos do Realm definidos em seu aplicativo.
Observação
As bibliotecas que incluem o Realm devem expor e usar seu esquema por meio de um módulo. Isso evita que a biblioteca gere o RealmModule
padrão, o que entraria em conflito com o RealmModule
padrão usado por qualquer aplicativo que inclua a biblioteca. Os aplicativos que usam a biblioteca acessam as classes da biblioteca por meio do módulo.
// 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()