SyncAdapters.requestSync和Android SyncManager

时间:2015-07-01 19:20:54

标签: android android-syncadapter

我试图了解SyncAdapters的工作原理。当我们从广播接收器收到GCM通知时,我查看了代码。我们希望通过调用requestSync来强制SyncAdapter立即同步,因为GCM告诉我的应用程序有新的数据可供获取。

我从以下链接获得了以下代码:https://software.intel.com/en-us/articles/handling-offline-capability-and-data-sync-in-an-android-app-part-2

public class GcmBroadcastReceiver extends BroadcastReceiver {
    private static final String TAG = GcmBroadcastReceiver.class.getSimpleName();
    public GcmBroadcastReceiver() {
    }

    @Override
    public void onReceive(Context context, Intent intent) {
        GoogleCloudMessaging gcm = GoogleCloudMessaging.getInstance(context);
        if (GoogleCloudMessaging.MESSAGE_TYPE_MESSAGE.equals(gcm.getMessageType(intent)) &&
                intent.getExtras().containsKey("com.example.restaurant.SYNC_REQ")) {
            Log.d(TAG, "GCM sync notification! Requesting DB sync for server dbversion " + intent.getStringExtra("dbversion"));
            ContentResolver.requestSync(new Account("dummyaccount", "com.example.restaurant"),
                    RestaurantContentProvider.AUTHORITY, Bundle.EMPTY);
        }
    }
}

现在我从这里读到有关SyncAdapters的信息:http://naked-code.blogspot.com/2011/05/revenge-of-syncadapter-synchronizing.html)他们提到了:

  

SyncAdapter只是由同步管理器启动的服务,   而这又维护着一个SyncAdapters队列。

如果我的手机有几个与不同应用程序(Facebook,Twitter等)相关的不同SyncAdapter,并且它们都有需要同步的项目(例如,Facebook或Twitter上的新帖子),它看起来就像所有这些SyncAdapter将被放入队列,等待SyncManager提前同步所有这些SyncAdapter。

如果我的应用程序现在调用命令同步 - ContentResolver.requestSync(),这是否意味着所有其他应用程序(Facebook,Twitter等)也会同时进行同步?

我查看了requestSync方法的定义:

http://developer.android.com/reference/android/content/ContentResolver.html#requestSync(android.accounts.Account,java.lang.String,android.os.Bundle)

public static void requestSync(帐户帐户,字符串权限, 捆绑额外内容)

  

启动异步同步操作。如果你想   监视同步的进度,您可以注册一个SyncObserver。

public static void requestSync(SyncRequest request)

  

使用SyncManager注册同步。这些请求是使用构建的   SyncRequest.Builder。

requestSync是否正在调用SyncManager来同步其所有的syncAdapter?

2 个答案:

答案 0 :(得分:0)

如果您使用代码明确强制运行同步播放器,则所有帐户都将同步。

Bundle bundle = new Bundle();
bundle.putBoolean(ContentResolver.SYNC_EXTRAS_EXPEDITED, true);
//deprecated in API level 5
//bundle.putBoolean(ContentResolver.SYNC_EXTRAS_FORCE, true);
bundle.putBoolean(ContentResolver.SYNC_EXTRAS_MANUAL, true);
ContentResolver.requestSync(null, MyContentProvider.getAuthority(), bundle);

SyncAdapters会自动同步,但不会立即同步。换句话说,除非您强制执行,否则很难估计同步适配器运行的确切时间。 See developer docs on this

答案 1 :(得分:0)

对于初学者,请务必阅读guide for creating a SyncAdapterhow to run one

请注意,SyncAdapter同步数据ContentProvider的数据,由权限字符串标识。在许多与请求或取消SyncAdapter运行相关的ContentResolver方法中,例如requestSync(),您将看到一个用于权限的String参数。这标识了请求适用的ContentProvider。

你问:

  

如果我的应用程序现在调用命令进行同步 -   ContentResolver.requestSync(),这是否意味着所有其他应用程序   (Facebook,Twitter等)也同时进行同步?

没有。您的同步请求将包含ContentProvider的权限字符串,例如:" com.example.myprovider"。您使用您指定的计划选项(现在,定期,数据更改,网络消息)请求仅同步该特定提供商。

根据您请求同步时使用的选项,您的适配器可以与其他应用程序的适配器同时运行,这是可能的。但这不在您的控制之下,它只是系统批处理同步的结果,以最大限度地减少电池消耗和计量数据使用。如果另一个应用程序已请求每天一次定期,并且您立即(很快)请求您的适配器同步,则运行的适配器不会影响另一个适配器的每日一次的调度。

  

requestSync是否正在调用SyncManager来同步它的所有内容   syncAdapters?

不,只是你自己 - 你用权限参数指定的那个。我还没有通过实验验证它,但我非常怀疑系统会允许应用请求或取消其他应用拥有的ContentProviders的同步。想象一下,如果允许流氓应用程序控制其他应用程序适配器的运行,则会造成严重破坏。

关于帐户:我的理解是,帐户信息被提供给SyncAdapter,以允许它登录到正在同步的服务器。