在SyncAdapter中使用ContentResolver而不是ContentProviderClient

时间:2014-03-31 20:51:08

标签: android android-contentprovider android-contentresolver android-syncadapter

据我所知,在SyncService中定义的一个SyncAdapter仅限于接收一个要处理的ContentProvider权限。

但是,与此同时,它可以访问ContentResolver,它也允许在其他ContentProviders上运行查询。如果需要开发人员为SyncAdapter提供单一内容权限,我无法理解这个特定的设计概念,尽管如此,她仍然能够在她有权访问的任何ContentProvider上做任何她想做的事情。我的问题是:忽略onPerformSync的参数会产生什么后果:字符串权限和ContentProviderClient提供程序以及使用纯ContentResolver?

我的应用程序(实际上是它的SyncService)的想法很简单:查询日历服务器(在我的情况下为OwnCloud)不仅可以获取事件(与com.android.calendar同步),还可以获取 VTODOS ,然后在各种任务管理应用程序之间分配,我可以获得源代码和/或ContentProviderContract。我还想到了我自己的“Hub”ContentProvider,它具有基本的VTODO / Task结构,并且是与服务器相比唯一的一个。它应该能够与任务管理应用程序的不同内容提供商进行双向同步,然后与服务器同步。

我已阅读using ContentProviderClient vs ContentResolver to access content provider,我想我理解其中的差异。我现在很困惑为什么Android SDK中有如此强烈的建议在一个SyncAdapter中使用单个ContentProvider,但你可以使用ContentResolver来绕过这个限制。

我花了一整天的时间来解决这个问题并在此问题上搜索了数百个SO / Google资源(其中一些是多次)。我也看到了有关使用一个SyncAdapter来同步多个ContentProviders的问题,但没有一个答案与使用ContentResolver的建议相近。

1 个答案:

答案 0 :(得分:2)

ContentResolver的上下文中使用SyncAdapter的API时没有特别限制。恕我直言,框架将ContentProviderClientauthority传递给onPerformSync()的唯一原因是方便并且向开发人员提示SyncAdapter如何工作。

AbstractThreadedSyncAdapter.SyncThread的源代码中很容易看到这一事实 - 传递给ContentProviderClient的{​​{1}}是以标准方式获得的:

onPerformSync()

因此,引导线:您可以根据需要在 @Override public void run() { Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND); // Trace this sync instance. Note, conceptually this should be in // SyncStorageEngine.insertStartSyncEvent(), but the trace functions require unique // threads in order to track overlapping operations, so we'll do it here for now. Trace.traceBegin(Trace.TRACE_TAG_SYNC_MANAGER, mAuthority); SyncResult syncResult = new SyncResult(); ContentProviderClient provider = null; try { if (isCanceled()) { return; } provider = mContext.getContentResolver().acquireContentProviderClient(mAuthority); if (provider != null) { AbstractThreadedSyncAdapter.this.onPerformSync(mAccount, mExtras, mAuthority, provider, syncResult); } else { syncResult.databaseError = true; } } finally { Trace.traceEnd(Trace.TRACE_TAG_SYNC_MANAGER); if (provider != null) { provider.release(); } if (!isCanceled()) { mSyncContext.onFinished(syncResult); } // synchronize so that the assignment will be seen by other threads // that also synchronize accesses to mSyncThreads synchronized (mSyncThreadLock) { mSyncThreads.remove(mThreadsKey); } } } 中使用ContentResolver - 只需致电SyncAdapter并访问任何导出的getContext().getContentResolver()