Docs Menu
Docs Home
/ /
Sincronizar datos

Sincronizar un dominio en segundo plano - SDK de Java

Si necesita sincronizar datos cuando su aplicación no se está ejecutando, puede sincronizar reinos en un proceso en segundo plano.

Para comenzar con la sincronización en segundo plano, debe agregar las siguientes dependencias a su aplicación de Android:

  • androidx.work:tiempo de ejecución del trabajo, para poner en cola trabajos

  • androidx.concurrent:concurrent-futures, para devolver los resultados del trabajo de un trabajador en segundo plano

La sincronización en segundo plano requiere dos cosas:

  • lógica de sincronización

  • un trabajo programado que ejecuta periódicamente esa lógica.

Primero, escribe la lógica personalizada que sincroniza tu dominio. Considera esta lógica como una conexión independiente con tu backend. Por lo tanto, necesitarás:

  • inicializar el SDK de Realm

  • autenticar a un usuario para abrir el reino

Puede utilizar las credenciales almacenadas en caché de un usuario si el usuario utilizó la aplicación recientemente.

Abra el reino, luego use SyncSession.downloadAllServerChanges() y SyncSession.uploadAllLocalChanges() para sincronizar completamente el reino con el backend.

Puedes ejecutar esta lógica como un proceso en segundo plano usando una subclase de ListenableWorker. Coloca tu lógica de sincronización en el startWork() método de su trabajador:

import android.annotation.SuppressLint;
import android.content.Context;
import android.util.Log;
import androidx.annotation.NonNull;
import androidx.concurrent.futures.ResolvableFuture;
import androidx.work.ListenableWorker;
import androidx.work.WorkerParameters;
import com.google.common.util.concurrent.ListenableFuture;
import java.util.concurrent.TimeUnit;
import io.realm.Realm;
import io.realm.mongodb.App;
import io.realm.mongodb.AppConfiguration;
import io.realm.mongodb.Credentials;
import io.realm.mongodb.User;
import io.realm.mongodb.sync.SyncConfiguration;
public class RealmBackgroundWorker extends ListenableWorker {
static final String UNIQUE_WORK_NAME = "RealmBackgroundWorker";
private ResolvableFuture<Result> future;
public RealmBackgroundWorker(@NonNull Context context, @NonNull WorkerParameters workerParams) {
super(context, workerParams);
}
@SuppressLint("RestrictedApi")
@NonNull
@Override
public ListenableFuture<Result> startWork() {
future = ResolvableFuture.create();
Realm.init(this.getApplicationContext());
String appID = YOUR_APP_ID; // replace this with your App ID
App app = new App(new AppConfiguration.Builder(appID).build());
Credentials credentials = Credentials.anonymous();
app.loginAsync(credentials, it -> {
if (it.isSuccess()) {
Log.v("EXAMPLE", "Successfully authenticated.");
User user = app.currentUser();
SyncConfiguration config = new SyncConfiguration.Builder(user, "PARTITION")
.build();
Realm.getInstanceAsync(config, new Realm.Callback() {
@Override
public void onSuccess(Realm realm) {
Log.v("EXAMPLE", "Successfully opened a realm for background synchronization.");
try {
app.getSync().getSession(config).downloadAllServerChanges();
app.getSync().getSession(config).uploadAllLocalChanges();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
} else {
Log.e("EXAMPLE", "Failed login: " + it.getError().getErrorMessage());
}
});
return future;
}
}
import android.annotation.SuppressLint
import android.content.Context
import android.util.Log
import androidx.concurrent.futures.ResolvableFuture
import androidx.work.ListenableWorker
import androidx.work.WorkerParameters
import com.google.common.util.concurrent.ListenableFuture
import io.realm.Realm
import io.realm.mongodb.App
import io.realm.mongodb.AppConfiguration
import io.realm.mongodb.Credentials
import io.realm.mongodb.User
import io.realm.mongodb.sync.SyncConfiguration
import java.util.concurrent.TimeUnit
class RealmBackgroundWorker(context: Context, workerParams: WorkerParameters) :
ListenableWorker(context, workerParams) {
private lateinit var future: ResolvableFuture<Result>
@SuppressLint("RestrictedApi")
override fun startWork(): ListenableFuture<Result> {
future = ResolvableFuture.create()
Realm.init(this.applicationContext)
val appID = YOUR_APP_ID // replace this with your App ID
val app = App(AppConfiguration.Builder(appID).build())
val credentials = Credentials.anonymous()
app.loginAsync(credentials) { it: App.Result<User?> ->
if (it.isSuccess) {
Log.v("EXAMPLE", "Successfully authenticated.")
val user = app.currentUser()
val config = SyncConfiguration.Builder(user, "PARTITION")
.build()
Realm.getInstanceAsync(config, object : Realm.Callback() {
override fun onSuccess(realm: Realm) {
Log.v("EXAMPLE", "Successfully opened a realm for background synchronization.")
try {
app.sync.getSession(config).downloadAllServerChanges()
app.sync.getSession(config).uploadAllLocalChanges()
} catch (e: InterruptedException) {
e.printStackTrace()
}
}
})
} else {
Log.e("EXAMPLE", "Failed login: " + it.error.errorMessage)
}
}
return future
}
companion object {
const val UNIQUE_WORK_NAME = "RealmBackgroundWorker"
}
}

Para crear un trabajador que realice periódicamente una sincronización en segundo plano:

  1. Crea un conjunto de restricciones que especifique las condiciones necesarias para tu trabajador.

  2. Especifique con qué frecuencia debe ejecutarse su trabajador.

  3. Ponga en cola a su trabajador con el sistema operativo Android. Asígnele un identificador único para poder actualizar el trabajo en el futuro.

Puede crear el trabajo de sincronización en segundo plano dentro de una subclase de aplicación en su aplicación para garantizar que la lógica solo se ejecute una vez cada vez que se ejecuta su aplicación.

Dado que la sincronización de un reino utiliza datos, debes considerar descargar los cambios en segundo plano únicamente cuando el dispositivo no esté:

  • poca batería

  • utilizando una fuente de datos medida

Utilice restricciones para describir el entorno donde se ejecuta la sincronización en segundo plano.

El intervalo de repetición depende de la frecuencia con la que se actualizan los datos en el dominio y de la frecuencia con la que los usuarios abren la aplicación. Si el dominio se actualiza con frecuencia a lo largo del día, considere establecer un intervalo de repetición de 1a3 horas. Si el dominio solo se actualiza pocas veces al día, es recomendable establecer un intervalo de repetición mayor y sincronizar en segundo plano solo una o dos veces al día.

Constraints constraints = new Constraints.Builder()
.setRequiredNetworkType(NetworkType.UNMETERED)
.setRequiresBatteryNotLow(true)
.build();
PeriodicWorkRequest backgroundRealmSync =
new PeriodicWorkRequest
.Builder(RealmBackgroundWorker.class,
// 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.REPLACE,
backgroundRealmSync);
val constraints: Constraints = Constraints.Builder()
.setRequiredNetworkType(NetworkType.UNMETERED)
.setRequiresBatteryNotLow(true)
.build()
val backgroundRealmSync: PeriodicWorkRequest = PeriodicWorkRequest.Builder(
RealmBackgroundWorker::class.java,
// 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.REPLACE,
backgroundRealmSync
)

Volver

Compruebe la conexión de red

En esta página