android – 在SyncAdapter中使用ContentResolver而不是ContentProviderClient

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

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

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

我读过using ContentProviderClient vs ContentResolver to access content provider,我想我明白了它的不同之处.我现在感到困惑的是为什么Android SDK中有如此强烈的建议在单个SyncAdapter中使用单个ContentProvider但你可以使用ContentResolver来绕过这个限制.

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

解决方法

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

这个事实很容易在AbstractThreadedSyncAdapter.SyncThread的源代码中看到 – 传递给onPerformSync()的ContentProviderClient是以标准方式获得的:

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

因此,引导线:您可以根据需要在SyncAdapter中使用ContentResolver – 只需调用getContext().getContentResolver()并访问任何导出的ContentProvider.

相关文章

Android性能优化——之控件的优化 前面讲了图像的优化,接下...
前言 上一篇已经讲了如何实现textView中粗字体效果,里面主要...
最近项目重构,涉及到了数据库和文件下载,发现GreenDao这个...
WebView加载页面的两种方式 一、加载网络页面 加载网络页面,...
给APP全局设置字体主要分为两个方面来介绍 一、给原生界面设...
前言 最近UI大牛出了一版新的效果图,按照IOS的效果做的,页...