Use arquivos do Realm - SDK Java
Nesta página
Um Realm é um conjunto de objetos relacionados que estão em conformidade com um esquema predefinido. Os domínios podem conter mais de um tipo de dados, desde que exista um esquema para cada tipo.
Cada Realm armazena dados em um arquivo de Realm separado que contém uma codificação binária de cada objeto no Realm. Você pode sincronizar automaticamente o Realm em vários dispositivos e configurar manipuladores de evento reativos que chamam uma função sempre que um objeto em um Realm for criado, modificado ou excluído.
O Realm de vida do domínio
Cada instância de Realm consome uma quantidade significativa de recursos. Abrir e fechar um Realm são operações caras, mas manter um Realm aberto também incorre em uma significativa sobrecarga de recursos. Para maximizar o desempenho do seu aplicação, você deve minimizar o número de domínios abertos a qualquer momento e limitar o número de operações de abertura e fechamento usadas.
No entanto, abrir um Realm nem sempre é consistentemente caro. Se o Realm já estiver aberto dentro do mesmo processo ou thread, abrir uma instância adicional exigirá menos recursos:
Se o domínio não for aberto dentro do mesmo processo, abrir o domínio sairá caro.
Se o realm já estiver aberto em uma thread diferente dentro do mesmo processo, abrir o realm será menos caro, mas ainda não é trivial.
Se o realm já estiver aberto na mesma thread dentro do mesmo processo, a abertura do realm exigirá recursos adicionais mínimos.
Quando você abre um Realm pela primeira vez, o Realm executa o mapeamento de memória e a validação de esquema necessários para ler e gravar dados no Realm. Instâncias adicionais desse Realm na mesma thread utilizam os mesmos recursos subjacentes. As instâncias desse Realm em threads separados usam alguns dos mesmos recursos subjacentes.
Quando todas as conexões com um Realm são fechadas em um thread, o Realm libera os recursos de thread usados para se conectar a esse Realm. Quando todas as conexões com um Realm são fechadas em um processo, o Realm libera todos os recursos usados para se conectar a esse Realm.
Como prática recomendada, recomendamos vincular o ciclo de vida da instância de domínio aos ciclos de vida das visualizações que observam o domínio. Por exemplo, considere um RecyclerView
que exibe dados do RealmResults
por um Fragment
. Você poderia:
Abra um único Realm que contenha os dados para essa visualização no método de ciclo de vida do
Fragment.onCreateView()
.Feche o mesmo Realm no método de ciclo de vida
Fragment.onDestroyView()
.
Observação
Se o seu Realm for especialmente grande, buscar uma instância de Realm no Fragment.onCreateView()
pode bloquear brevemente a renderização. Se abrir seu Realm no onCreateView()
causar problemas de desempenho, considere gerenciar o Realm a partir do Fragment.onStart()
e Fragment.onStop()
.
Se várias instâncias do Fragment
exigirem acesso ao mesmo conjunto de dados, você poderá gerenciar um único domínio no Activity
anexado:
Abra o Realm no método de ciclo de vida
Activity.onCreate()
.Feche o domínio no método de ciclo de vida
Activity.onDestroy()
.
Multiprocesso
Você não pode acessar domínios criptografados ou sincronizados simultaneamente a partir de diferentes processos. No entanto, os domínios locais funcionam normalmente nos processos, para que você possa ler, escrever e receber notificações de vários APIs.
Esquema de Realm
Um Realm Schema é uma lista de esquemas de objeto válidos que cada um define um tipo de objeto que um aplicativo pode persistir. Todos os objetos em um Realm devem estar em conformidade com o Realm Schema.
Por padrão, o SDK adiciona automaticamente todas as classes em seu projeto que derivam do RealmObject ao esquema do domínio.
Os aplicativos do cliente fornecem um Realm Schema quando abrem um Realm. Se um Realm já contiver dados, o Realm validará cada objeto existente para garantir que um esquema de objetos tenha sido fornecido para seu tipo e que atenda a todas as restrições especificadas no esquema.
Exemplo
Um Realm que contém dados básicos sobre livros em bibliotecas pode usar um esquema como o seguinte:
[ { "type": "Library", "properties": { "address": "string", "books": "Book[]" } }, { "type": "Book", "primaryKey": "isbn", "properties": { "isbn": "string", "title": "string", "author": "string", "numberOwned": { "type": "int?", "default": 0 }, "numberLoaned": { "type": "int?", "default": 0 } } } ]
Domínios sincronizados
Um aplicativo que usa o Atlas Device Sync pode abrir um Realm sincronizado.
Ao usar o Flexible Sync, você pode personalizar os dados que o aplicativo cliente sincroniza assinando queries. Essas queries o Atlas Search de dados em seu backend do aplicativo, e o domínio Flexible Sync sincroniza os dados que correspondem às queries. O aplicativo cliente só pode sincronizar dados em que o usuário tenha as permissões de leitura ou leitura e gravação apropriadas para acessar os dados.
Quando você usa a Sincronização baseada em partições, os domínios sincronizados representam partições de dados do Atlas. Cada domínio corresponde a um subconjunto dos dados na fonte de dados do seu aplicativo. Você pode personalizar o particionamento de dados usando a chave de partiçãodo seu aplicativo. Valores exclusivos da chave de partição, conhecidos como valores de partição, correspondem a domínios individuais.
Você pode personalizar as permissões para os dados que os domínios sincronizados podem ler e gravar de seu aplicativo ao configurar as Regras do Realm .
Para obter mais informações, consulte Configurar um Realm sincronizado - Java SDK.
Encontre seu arquivo Realm
O Realm armazena uma versão codificada binária de cada objeto e digita um Realm em um único arquivo .realm
.
O sistema de arquivos usado pelos emuladores Android não é acessível diretamente da máquina que executa o Realm Studio. Você deve baixar o arquivo do emulador antes de poder acessá-lo.
Primeiro, encontre o caminho do arquivo no emulador:
// Run this on the device to find the path on the emulator Realm realm = Realm.getDefaultInstance(); Log.i("Realm", realm.getPath());
Em seguida, baixe o arquivo usando ADB. Você pode fazer isso enquanto o aplicativo está em execução.
> adb pull <path>
Você também pode carregar o arquivo modificado novamente usando o ADB, mas somente quando o aplicativo não estiver em execução. Carregar um arquivo modificado enquanto o aplicativo está em execução pode corromper o arquivo.
> adb push <file> <path>
Dica
Veja também: Arquivos Realm Auxiliares
O Realm cria arquivos adicionais para cada Realm. Para saber mais sobre esses arquivos, consulte Realm Internals.
Tamanho do arquivo de Realm
O Realm geralmente ocupa menos espaço no disco do que um banco de banco de dados SQLite equivalente . No entanto, para fornecer a você uma visão consistente de seus dados, o Realm opera em várias versões de um Realm. Se muitas versões de um Realm forem abertas simultaneamente, o arquivo de Realm poderá exigir espaço adicional no disco.
Essas versões ocupam uma quantidade de espaço que depende da quantidade de alterações em cada transação. Muitas transações pequenas têm a mesma sobrecarga que um pequeno número de transações grandes.
O crescimento inesperado do tamanho do arquivo geralmente acontece por um dos três motivos:
Você abre um Realm em um thread em background e se esquece de fechá-lo novamente. Como resultado, o Realm retém uma referência à versão mais antiga dos dados na thread do background. Como o Realm atualiza automaticamente os domínios para a versão mais recente em threads com loopers, o thread da UI e outros threads do Looper não têm esse problema.
Você tem referências a muitas versões de objetos congelados. Objetos congelados preservam a versão de um Realm que existiu quando o objeto foi congelado pela primeira vez. Se você precisar congelar um grande número de objetos, considere usar Realm.copyFromRealm() em vez disso, para preservar apenas os dados necessários.
Você lê alguns dados de um Realm. Em seguida, bloqueie o thread com uma operação de longa duração. Enquanto isso, você escreve muitas vezes no Realm em outras threads. Isso faz com que o Realm crie muitas versões intermediárias. Você pode evitar isso por:
agrupamento das gravações
evitando deixar o Realm aberto e, de outra forma, bloquear a thread no background.
Limite o número máximo de versões ativas
Você pode definir maxNumberOfActiveVersions() ao criar seu RealmConfiguration
para lançar um IllegalStateException
se seu aplicativo abrir mais versões de um domínio do que o número permitido. As versões são criadas ao executar uma transação de escrita.
O Realm remove automaticamente as versões mais antigas dos dados quando eles não são mais usados pelo seu aplicação. No entanto, o Realm não libera o espaço usado por versões mais antigas de dados; em vez disso, esse espaço é usado para novas gravações no Realm.
Compactar um domínio
Você pode remover o espaço não utilizado compactando o arquivo de domínio:
Manualmente: chame compactRealm()
Automaticamente: especifique a opção do construtor compactaOnLaunch() ao abrir a primeira conexão com um Realm em sua aplicação Android
Importante
Compactar todos os aplicativos de produção
Todo aplicativo de produção deve implementar a compactação para reduzir periodicamente o tamanho do arquivo do realm.
Realms de backup e restauração
O Realm persiste domínios em disco usando arquivos em seu dispositivo Android. Para fazer backup de um domínio, encontre seu arquivo de domínio e copie-o para um local seguro. Você deve fechar todas as instâncias do domínio antes de copiá-lo.
Como alternativa, você também pode usar Realm.writeCopyTo() para gravar uma versão compactada de um Realm em um arquivo de destino.
Módulos
Os módulos de domínio descrevem o conjunto de Realm de domínio que podem ser armazenados em um Realm. Por padrão, o Realm cria automaticamente um módulo Realm que contém todos os objetos do Realm definidos em seu aplicação. Você pode definir um RealmModule para restringir um Realm a um subconjunto de classes definidas em um aplicação. Se você produzir uma biblioteca que usa Realm, poderá usar um módulo Realm para incluir explicitamente apenas os objetos Realm definidos em sua biblioteca em seu Realm. Isso permite que os aplicativos que incluem sua biblioteca também usem o Realm sem gerenciar conflitos de nome de objeto e migrações com os objetos Realm definidos pela biblioteca.