8

我已经按照 SDK 中的 SimpleSyncAdapter 示例项目的方式实现了 SyncAdapter、AccountManager 和私有 ContentProvider。这一切都运作良好。

现在,当从设置了特定标志的远程服务器下载新行时,我想向用户显示一条消息。当同步完成时,我需要来自 SyncAdapter 的回调,以便我可以执行查询并显示来自活动的消息。我在 StackOverflow 上看到了一些讨论这个问题的问题,但没有一个很好的答案。

如何从 Android SyncAdapter 监听进度?说 SyncStatusObserver 没用。用户 mobibob 建议使用 ResultReceiver 从同步线程响应 UI。

如何知道同步何时完成?建议在您的 SyncService 中使用 Intent。

如何向 Android SyncManager 发出同步完成信号?建议使用 SyncResult。maxpower47 链接的示例代码使用 SyncResult 类报告异常,但不实际报告同步是否成功完成。

我只是不知道哪个是最好的选择,而且我还没有看到任何使用这些解决方案的示例项目。

4

3 回答 3

2

我知道这是一个老问题,但我自己也在问同样的事情。我发现作为一个很好的解决方案,特别是因为我正在处理本地数据,是使用 ContentResolver 中的以下方法:

registerContentObserver(Uri uri, boolean notifyForDescendents, ContentObserver observer)

这注册了一个观察者类,当给定内容 URI 标识的数据发生变化时,该类会获得回调。但这只有在您的 ContentProvider 发送通知时才会发生。因此,例如,如果您想在上面的 ContentObserver 上获得通过 ContentProvider 对数据库进行的所有更新的通知,您的 ContentProvider 应该实现类似于以下的更新:

@Override
public int update(Uri uri, ContentValues contentValues, String s, String[] strings) {
    // code goes here
    this.getContext().getContentResolver().notifyChange(uri, null);
    return 0;
}

在执行 registerContentObserver 时使用 notifyForDescendents 非常有用。

于 2014-04-19T14:13:45.233 回答
1

这是一个老问题,但我在过去几天做了一些研究,关于 syncAdapter 处理网络请求和通知 UI 的例子并不多。

首先,您应该将 Loaders 与 contentProvider 一起使用,以使您的生活更轻松。您不再需要注册内容解析器,Loader 会为您完成。因此,这意味着您的 UI 会收到有关进入内容提供程序的任何内容的通知。

如果什么都没有改变呢?一切都是最新的,或者您遇到了网络错误。

  1. 您可以像 Google I/O 应用程序那样监听您的 syncAdapter 的状态,在 BaseActivity 中搜索mSyncStatusObserver
  2. 我查看了默认的 android 电子邮件应用程序,他们使用带有回调的Singleton
  3. 您可以 BroadcastIntents 或使用 eventBus(例如方形 Otto)来通知您的 UI 任何行为。

我更喜欢最后一个,因为它可以让您更详细地了解同步适配器中发生的事件。

于 2015-01-16T11:41:31.587 回答
-2

我们遇到了类似的情况,并为 SyncAdapter 编写了一个静态 Listener 接口。侦听器是活动并在数据可用时执行必要的操作(更新 UI)。当系统在自动同步期间调用同步适配器时,这也有效,其中此侦听器将为空,并且同步进程将处理自己的事务。

class SyncAdapter extends AbstractThreadedSyncAdapter {

    protected static Listener uiListener = null;
    public interface Listener {
        public void onSync();
    }
    public static void setListener(Listener l) {
        uiListener = l;
    }
    public static void clearListener() {
        uiListener = null;
    }
    protected void broadcastSync() {
        if (uiListener != null)
            uiListener.onSync();
    }
    public void onPerformSync(Account account, Bundle extras, String authority,
                          ContentProviderClient provider, SyncResult syncResult) {

         // call broadcastSync();
    }

然后在Activity中,实现SyncAdapter.Listener接口。

于 2016-05-21T17:16:32.890 回答