Android SyncAdapter 回调

发布于 2025-01-05 08:18:13 字数 863 浏览 2 评论 0原文

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

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

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

如何知道同步何时完成?建议在您的同步服务。

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

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

I have implemented a SyncAdapter, AccountManager and private ContentProvider along the lines of the SimpleSyncAdapter sample project in the SDK. It is all working well.

Now I want to show a message to the user when new rows have been downloaded from the remote server that have a specific flag set. I need a callback from the SyncAdapter when a Sync has finished so I can do the query and display the message from an activity. I have seen a few questions on StackOverflow discussing this but none with a good answer.

How does one listen for progress from Android SyncAdapter? says that the SyncStatusObserver is useless. User mobibob suggests using a ResultReceiver to respond back to the UI from the sync thread.

How to know when sync is finished? suggests using an Intent in your SyncService.

How to signal sync-complete to the Android SyncManager? suggests using the SyncResult. The example code linked to by maxpower47 uses the SyncResult class to report exceptions but not to actually report if a sync was successfully completed.

I just don't know which is the best option and I have not seen any example projects where any of these solutions are used.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

蓝海似她心 2025-01-12 08:18:13

我知道这是一个老问题,但我自己也在问同样的事情。
我发现一个很好的解决方案,特别是因为我正在像您一样处理本地数据,是使用 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 时使用 notificationForDescendents 可能非常有用。

I know this is an old question, but I was asking the same thing myself.
What I found out as a good solution, specially because I'm dealing with local data as you are, is to use the following method from ContentResolver:

registerContentObserver(Uri uri, boolean notifyForDescendents, ContentObserver observer)

This register an observer class that get callback when data identified by a given content URI changes. But that can only happens if your ContentProvider send the notification. So for example, if you want to get notified on the ContentObserver above for all updates done on your database through a ContentProvider, your ContentProvider should implement update similar to this:

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

Using notifyForDescendents when you do a registerContentObserver can be very useful.

往事风中埋 2025-01-12 08:18:13

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

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

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

  1. 您可以作为 Google I/O 监听您的syncAdapter 的状态
    应用程序确实如此,请在 BaseActivity
  2. 我查看了默认的 Android 电子邮件应用程序,他们使用 带有回调的单例
  3. 您可以使用 BroadcastIntents 或使用 eventBus(例如 Square Otto)来通知您的 UI 任何行为。

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

This is an old question but I did some research in the past days and there are not many exemples on syncAdapter handling network requests and notifying the UI.

First you should use Loaders with contentProvider to make your life easier. You don't need to register for content resolver anymore the Loader does it for you. So it means your UI gets notified for anything that goes into your content provider.

What if nothing changed ? everything was up to date or you had a network error.

  1. You can listen to the status of your syncAdapter as the Google I/O
    app does, search for mSyncStatusObserver in the BaseActivity
  2. I had a look at the default android email app and they use a Singleton with callBacks.
  3. You can BroadcastIntents or use an eventBus (square Otto for exemple) to notify your UI of any behaviour.

I like the last one better because it gives you more granularity on the events that happen in the syncAdapter.

长途伴 2025-01-12 08:18:13

我们遇到了类似的情况,并为 SyncAdapter 编写了一个静态监听器接口。侦听器是活动,当数据可用时执行必要的操作(更新 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接口。

We ran into a similar situation and wrote a static Listener interface to the SyncAdapter. The listener is the activity and performs necessary actions when the data is available (update UI). This also works when the sync-adapter is called by the system during autosync where this listener would be null and the sync process would mind its own business.

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();
    }

Then in the Activity, implement SyncAdapter.Listener interface.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文