使用ContentResolver v.s. SyncAdapter中的ContentProviderClient

时间:2016-09-13 17:52:09

标签: android android-syncadapter

我目前使用onPerformSync()中提供的ContentProviderClient作为我的SyncAdapter。有时我必须进行大型查询,其中一些会抛出TransactionTooLarge异常。 (注意:我的SyncService在与应用程序不同的进程中运行。)

如果我使用的是ContentResolver - 由getContext()访问.getContentResolver() - 是否存在抛出TransactionTooLarge异常的相同可能性? ContentResolver的查询方法似乎没有抛出RemoteExceptions(通过文档),并提供了更大的灵活性。这可能是我问题的潜在解决方案吗?

这很难测试,因为TransactionTooLarge异常很少且很难重新创建(我在Crashlytics日志中看到了大部分异常)。

如果不解决我的问题,我想避免浪费时间重写所有内容以使用ContentResolver。

TL; DR:在SyncAdapter中使用ContentResolver而不是ContentProvider客户端有什么好处吗?

编辑:以下是一些抛出异常的调用:

删除:

String selection = UploadQueueTable.COLUMN_TASK_TYPE + " = 1";
int result = provider.delete(UploadQueueContract.UPLOAD_DELETE_URI, selection, null);

查询1:

String projection[] = new String[]{UploadQueueTable.COLUMN_URI, UploadQueueTable.COLUMN_ID};
String sort = UploadQueueTable.COLUMN_URI + " LIMIT 100 OFFSET 0";
cursor = provider.query(UploadQueueContract.CONTENT_URI, projection, null, null, sort);

查询2:

projection = new String[]{UploadQueueTable.COLUMN_URI};
selection = UploadQueueTable.COLUMN_URI + " = ? AND " + UploadQueueTable.COLUMN_STATUS + " != ?";
selectionArgs = new String[]{uri, "C"};
sort = UploadQueueTable.COLUMN_URI + " LIMIT 1";

Cursor cursor = provider.query(UploadQueueContract.CONTENT_URI,
        projection,
        selection,
        selectionArgs,
        null);

查询3:

Cursor cursor = provider.query(
        UploadQueueContract.CONTENT_URI,
        new String[]{"count(*) AS count"},
        "(status='E' or status='Q') and task_type = 0",
        null,
        null);

仅举几例......

有趣的注意事项 - 这几乎完全出现在Android操作系统版本< = 5.1,尤其是LG手机上。

provider.delete()的

堆栈跟踪 - (从Crashlytics获得,可能无法提供完整的跟踪)

Non-fatal Exception: android.os.TransactionTooLargeException
   at android.os.BinderProxy.transactNative(Binder.java)
   at android.os.BinderProxy.transact(Binder.java:511)
   at android.content.ContentProviderProxy.delete(ContentProviderNative.java:542)
   at android.content.ContentProviderClient.delete(ContentProviderClient.java:260)
   at com.forever.forever.Utils.sync.SyncAdapter.databaseCleanupTask(SyncAdapter.java:239)
   at com.forever.forever.Utils.sync.SyncAdapter.onPerformSync(SyncAdapter.java:191)
   at android.content.AbstractThreadedSyncAdapter$SyncThread.run(AbstractThreadedSyncAdapter.java:259)

0 个答案:

没有答案