-
Notifications
You must be signed in to change notification settings - Fork 3
Correr el SyncAdapter
Debes tratar de correr el SyncAdapter basado en un calendario o como resultado indirecto de algún evento. Por ejemplo, puedes realizar la sincronización en un momento particular del día, o cuando hayan cambios en los datos almacenados en el dispositivo. Debes evitar correr la sincronización por una acción directa del usuario porque haciendo esto no aprovechas todos los beneficios de una sincronización calendarizada.
Para realizar la sincronización tienes varias alternativas basadas en distintos eventos.
Cambiar los datos en respuesta a un mensaje desde el servidor indicando que los datos han cambiado. Esta opción te permite actualizar los datos sin utilizar mucha batería y mejora bastante el desempeño. No cubriremos en detalle ya que requiere utilizar Google Cloud Messaging (GCM), tema que da para un tutorial por si solo.
Para realizar esto debes registrar un observer para el content provider.
Cuando los datos en el content provider cambia, el content provider
framework llama al observer. En el observer se debe llamar a
requestSync()
para decirle al framework que corra el sync adapter.
También es muy importante que cuando se quiera hacer la sincronización
se debe llamar a ContentResolver.notifyChange(uri, null)
. Esto le avisa
a los observadores que se ha hecho un cambio y ellos toman las acciones
especificadas. En este caso se usa en el método ContentProvider.insert()
.
Para crear el observer debes extender la clase ContentObserver e
implementar el método onChange()
. Dentro de este método debes llamar a
requestSync()
para iniciar el SyncAdapter. Para registrar al observer
hay que pasar esta clase como argumento de registerContentObserver()
.
También debes pasar un content URI que indica los datos que quieres
observar. La clase observer quedaría como sigue:
public class TableObserver extends ContentObserver {
/**
* Crea un content observer
*
*/
public TableObserver(Handler handler) {
super(handler);
}
/*
* Define el metodo que es llamado cuando los datos en el content provider cambian.
* Este metodo es solo para que haya compatibilidad con plataformas mas viejas.
*/
@Override
public void onChange(boolean selfChange) {
onChange(selfChange, null);
}
/*
* Define el metodo que es llamado cuando los datos en el content provider cambian.
*/
@Override
public void onChange(boolean selfChange, Uri changeUri) {
if (mAccount != null) {
// Corre la sincronizacion
ContentResolver.requestSync(mAccount, StudentsContract.AUTHORITY, null);
}
}
}
Luego para registrar el observer tenemos que hacer lo siguiente:
// En activity.onCreate()
...
TableObserver observer = new TableObserver(null);
/*
* Registra el obsever para students
*/
mResolver.registerContentObserver(StudentsContract.STUDENTS_URI, true, observer);
...
La documentación de Google sugiere que se puede correr el SyncAdapter cada vez que haya un Network Message. Esto significa que la sincornización se realizará regularmente cuando haya conexión a internet. Por lo probado esto no funciona como la documentación indica. Lo único que asegura este método es que el SyncAdapter se corra en algún momento en un lapso de 24 horas.
Configurar esta forma de sincronizar es bastante sencillo, solo se debe llamar al método ContentResolver.setSyncAutomatically().
// En activity.onCreate()
...
mResolver.setSyncAutomatically(mAccount, StudentsContract.AUTHORITY , true);
...
Puedes configurar que el sync adapter se ejecute cada ciertos intervalos de tiempo, o a una hora específica, o ambos. Por ejemplo, puedes subir datos en una hora específica, cuando sabes que tu servidor está menos ocupado. Si ocupas esta estrategia debes procurar que cada dispositivo ejecute la sincronización a una hora ligeramente diferente, para no sobrecargar el servidor.
Una sincronización periódica tiene sentido si el usuario no necesita actualización instantanea pero si necesita que los datos se actualicen regularmente. Un ejemplo podría ser una aplicación de noticias. Sería bueno que la ejecución se realice cuando se han publicado las noticias de la mañana, por lo que una sincronización un poco después de eso podría ser de utilidad.
Para utilizar esta opción debes usar el método addPeriodicSync()
. Esto
hace que se ejecute la sincronización luego de que un tiempo determinado
a pasado. Este tiempo puede variar en algunos segundos para que el
framework pueda optimizar las veces que se utiliza el internet al
coordinarlo con otros sync adpaters.
Para correr el sync adapter a ciertas horas específicas diariamente
debes usar AlarmManager
, tema que no se revisará en este tutorial. El
método addPeriodicSync()
y el setSyncAutomatically()
pueden ir juntos
perfectamente.
Es una opción muy poco recomendada, debido a que hace un uso ineficiente
de la calenderización del framework. Si se quiere utilizar, se debe usar
el método requestSync()
frente a la acción específica del usuario. Es
importante acá entregar como parámetros unos flags que indiquen que se
quiere realizar una sincronización manual. Con estos se le dice al
framework que olvide su filosofía y haga la sincronización de inmediato.
Se debe usar de la siguiente manera:
Bundle settings = new Bundle();
// Fuerza sincronizacion manual
settings.putBoolean(ContentResolver.SYNC_EXTRAS_MANUAL, true);
// Que se realice de inmediato. Si no se pone este se puede esperar varios segundos hasta que el framework decida ejecutar la sincronizacion.
settings.putBooleanContentResolver.SYNC_EXTRAS_EXPEDITED, true);
ContentResolver.requestSync(mAccount, AUTHORITY, settingsBundle);
Siguiente: Comentarios.