Android SyncAdapter: как получить уведомление о конкретной синхронизации произошло
У меня есть следующий сценарий.
Я использую SyncAdapter в своем приложении для загрузки данных с сервера.
Когда пользователь открывает приложение, я звоню requestSync()
чтобы убедиться, что последние данные доступны.
Когда пользователь запрашивает это, я звоню снова requestSync()
передавая пачку конкретных данных, которые я хочу скачать.
Проблема заключается в следующем:
Я могу использовать SyncStatusObserver
чтобы получить уведомление о статусе загрузки, но это не скажет мне, какая синхронизация завершена:
Например:
при запуске приложения я запускаю синхронизацию "Всего",
затем пользователь запрашивает обновление для определенной базы данных, поэтому я запускаю "Определенную синхронизацию базы данных foo",
SyncStatusObserver
скажет мне, что синхронизация ожидает / активна, но не скажет мне, является ли это синхронизация "Всего" или "Определенная синхронизация данных foo"
Как мне это сделать?
Является ли намерение вещания единственным способом?
1 ответ
SyncStatusObserver
Я не скажу вам об этом, но есть несколько способов сделать это, и это во многом зависит от вашей архитектуры.
Вот тот, который работает для нас:
Мы планируем позволить нашим SyncAdapter
вернуть другой IBinder
и вернуть этот, когда связывает наш SyncService
с конкретным действием. это IBinder
Объект предоставит информацию о текущем состоянии адаптера синхронизации. Это работает, потому что есть только один экземпляр службы синхронизации, а наша служба синхронизации содержит ровно один экземпляр адаптера синхронизации.
Вот быстрый пример:
В настоящее время onBind(Intent)
Метод нашего сервиса синхронизации выглядит так:
@Override
public IBinder onBind(Intent intent)
{
return sSyncAdapter.getSyncAdapterBinder();
}
куда sSyncAdapter
статический экземпляр нашего адаптера синхронизации
Мы планируем изменить это на что-то вроде этого:
public final static ACTION_SYNC_INFO = "com.example.SYNC_INFO";
@Override
public IBinder onBind(Intent intent)
{
if (ACTION_SYNC_INFO.equals(intent.getAction())
{
// sync info binder has been requested
return sSyncAdapter.getSyncInfoBinder();
}
// otherwise return the sync adapter binder
return sSyncAdapter.getSyncAdapterBinder();
}
В нашей деятельности мы связываем наш сервис синхронизации и устанавливаем действие SyncService.ACTION_SYNC_INFO
, Это говорит службе синхронизации, чтобы она возвращала привязку информации синхронизации вместо привязки адаптера синхронизации.
Связыватель будет иметь интерфейс, который может выглядеть следующим образом:
public interface SyncInfoBinder extends IBinder
{
public boolean isTotalSync();
}
Конечно, адаптер синхронизации все еще должен реализовать этот метод, который (в вашем случае) может выглядеть так:
private abstract class AbstractSyncInfoBinder extends Binder implements SyncInfoBinder
{
}
private final IBinder mSyncInfoBinder = new AbstractSyncInfoBinder()
{
@Override
public boolean isTotalSync()
{
// return some field that was set by your onPerformSync method
return mCurrentSyncIsTotalSync;
}
}
public IBinder getSyncInfoBinder()
{
return mSyncInfoBinder
}
Конечно, это работает легко, только если ваш адаптер синхронизации настроен на однопоточность. Для многопоточных адаптеров синхронизации вы должны предпринять дополнительные шаги, чтобы убедиться, что вы получаете статус всех текущих синхронизаций.
В любом случае это хороший способ получить живые результаты от адаптера синхронизации, чтобы представить их в вашем пользовательском интерфейсе.