Использование ContentResolver вместо ContentProviderClient в SyncAdapter

Насколько я понимаю из документации, один SyncAdapter, определенный в SyncService, ограничен для получения только одного полномочия ContentProvider для работы.

Но в то же время у него есть доступ к ContentResolver, который позволяет запускать запросы и на других ContentProvider'ах. Я не понимаю эту конкретную концепцию дизайна, если разработчику требуется предоставить единый орган управления контентом для SyncAdapter, и, тем не менее, он может делать все, что захочет, с любым ContentProvider, к которому у него есть доступ. Мой вопрос: Каковы последствия игнорирования параметров onPerformSync: String Authority и ContentProviderClient provider и использования чистого ContentResolver?

Идея моего приложения (на самом деле его SyncService) проста: запросить сервер календаря (в моем случае OwnCloud), чтобы получить не только события (синхронизированные с com.android.calendar), но также VTODOS, которые затем распространяются между различными приложениями для управления задачами я могу получить исходный код и / или ContentProviderContract. Я также подумал о моем собственном ContentProvider «Hub», который имеет базовую структуру VTODO / Task и является единственным по сравнению с сервером. Он должен иметь возможность двусторонней синхронизации с разными поставщиками контента приложений для управления задачами, а затем он синхронизируется с сервером.

Я прочитал использование ContentProviderClient и ContentResolver для доступа к поставщику контента и Думаю, я понимаю разницу. Теперь я озадачен, почему SDK для Android так убедительно предлагает использовать один ContentProvider в одном SyncAdapter, и все же вам разрешено использовать ContentResolver, чтобы обойти это ограничение.

Я потратил весь день на выяснение этого и поискал сотни ресурсов SO / Google по этому поводу (некоторые из них несколько раз). Я также видел вопросы, касающиеся использования одного SyncAdapter для синхронизации нескольких ContentProvider, но ни один из ответов не был близок к тому, чтобы предлагать вместо этого использовать ContentResolver.


person SkarabePL    schedule 31.03.2014    source источник


Ответы (1)


Нет особых ограничений на API ContentResolver при использовании из контекста SyncAdapter. ИМХО, единственная причина, по которой фреймворк передает ContentProviderClient и authority onPerformSync(), - это удобство и своего рода подсказка разработчикам относительно того, как SyncAdapter предполагается работать.

Этот факт легко увидеть в исходном коде для AbstractThreadedSyncAdapter.SyncThread - ContentProviderClient, переданный в 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);
            }
        }
    }

Следовательно, строка bootom: вы можете использовать ContentResolver в своем SyncAdapter по своему усмотрению - просто вызовите getContext().getContentResolver() и получите доступ к любому экспортированному ContentProvider.

person Vasiliy    schedule 07.06.2015