Sincronizar dados em segundo plano - Kotlin SDK
Se você precisar sincronizar dados quando seu aplicativo não estiver em execução, poderá sincronizar realms em um processo de background.
Pré-requisitos
Para começar a usar a sincronização em segundo plano, é necessário adicionar as seguintes dependências ao seu aplicativo Android:
androidx.work:work-runtime para enfileirar trabalhos
androidx.concurrent:concurrent-futures para retornar os resultados da tarefa de um trabalhador de background
Exemplo
A sincronização em segundo plano requer duas coisas:
Lógica de sincronização
Uma tarefa agendada que executa periodicamente a lógica de sincronização
Lógica de sincronização
Primeiro, escreva a lógica personalizada que sincroniza seu Realm. Trate essa lógica como uma conexão autônomo com seu backend. Como resultado, você precisará:
Obtenha a configuração de sincronização do Realm para seu aplicativo
Autentique um usuário para abrir o domínio. Você pode usar as credenciais em cache de um usuário para um usuário conectado cujo token de atualização não expirou.
Abra o Realm e use SyncSession.downloadAllServerChanges() e SyncSession.uploadAllLocalChanges() para sincronizar totalmente o Realm com o backend. Para mais informações, consulte Gerenciar Sessões de Sincronização.
Feche o Realm.
Você pode executar essa lógica como um processo de background usando uma subclasse de CoroutineWorker. Coloque sua lógica de sincronização no método doWork()
do seu trabalhador.
package com.mongodb.app.worker import android.annotation.SuppressLint import android.content.Context import androidx.concurrent.futures.ResolvableFuture import androidx.work.CoroutineWorker import androidx.work.WorkerParameters import com.mongodb.app.app import com.mongodb.app.data.RealmSyncRepository import io.realm.kotlin.Realm import io.realm.kotlin.mongodb.syncSession class RealmBackgroundWorker(context: Context, workerParams: WorkerParameters) : CoroutineWorker(context, workerParams) { private lateinit var future: ResolvableFuture<Result> override suspend fun doWork(): Result { future = ResolvableFuture.create() // Get the realm configuration for your app val syncRepository = RealmSyncRepository { session, error -> future.setException(error) } val config = syncRepository.getRealmConfiguration() // Check if user is logged-in if (app.currentUser?.loggedIn == true) { val realm = Realm.open(config) try { realm.syncSession.downloadAllServerChanges() realm.syncSession.uploadAllLocalChanges() } catch (e: InterruptedException) { e.printStackTrace() } finally { realm.close() } return future.get() } companion object { const val UNIQUE_WORK_NAME = "RealmBackgroundWorker" } }
Trabalhador
Para criar um operador que executa periodicamente a sincronização em segundo plano:
Criar um conjunto de Restrições que especificam as condições necessárias para o seu trabalhador. Como a sincronização de um Realm usa dados, você deve considerar apenas o download de alterações em segundo plano quando o dispositivo não estiver:
bateria fraca
Usando um conjunto de dados limitado
Especifique com que frequência seu funcionário deve executar. O intervalo repetido depende da frequência com que os dados são atualizados no domínio e com que frequência os usuários abrem seu aplicativo:
Se o Realm for atualizado com frequência ao longo do dia, considere definir um intervalo repetido de 1 a 3 horas.
Se o Realm atualizar apenas um pequeno número de vezes por dia, é melhor definir um intervalo de repetição menos frequente e apenas sincronizar em segundo plano uma ou duas vezes por dia.
Anexe seu operador com o sistema operacional Android. Atribua a ele um identificador exclusivo para que você possa atualizar a tarefa no futuro.
Dica
Você pode criar a tarefa de sincronização em segundo plano dentro de uma subclasse Application em seu aplicativo para garantir que a lógica seja executada somente uma vez a cada execução do aplicativo.
// Define any constraints for the background job val constraints: Constraints = Constraints.Builder() .setRequiredNetworkType(NetworkType.UNMETERED) .setRequiresBatteryNotLow(true) .build() // Define the frequency of the background job val backgroundRealmSync = PeriodicWorkRequestBuilder<RealmBackgroundWorker>( // Repeat every 12 hours 12, TimeUnit.HOURS, // Execute job at any point during that 12-hour period 12, TimeUnit.HOURS ) .setConstraints(constraints) .build() // Enqueue the work job, replacing it with the most recent // version if we update it WorkManager.getInstance(this).enqueueUniquePeriodicWork( RealmBackgroundWorker.UNIQUE_WORK_NAME, ExistingPeriodicWorkPolicy.UPDATE, backgroundRealmSync )