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
}

Конечно, это работает легко, только если ваш адаптер синхронизации настроен на однопоточность. Для многопоточных адаптеров синхронизации вы должны предпринять дополнительные шаги, чтобы убедиться, что вы получаете статус всех текущих синхронизаций.

В любом случае это хороший способ получить живые результаты от адаптера синхронизации, чтобы представить их в вашем пользовательском интерфейсе.

Другие вопросы по тегам