首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Google IO 2010 Virgil Dobjanschi模式C示例

Google IO 2010 Virgil Dobjanschi模式C示例
EN

Stack Overflow用户
提问于 2015-06-19 19:21:02
回答 1查看 58关注 0票数 0

我已经尝试了Virgil Dobjanschi模式A和B,并得出结论,我想使用模式C,因为在这种情况下,我可以使用基于google的代码,如果我有不稳定的网络连接,这些代码会关心如何将可能的数据发送到设备上,等等。但我没有找到如何以正确的方式实现这一点。特别是当您考虑到数据库足够大,可以每次同步所有数据库时。

我做了这样的事情

当CursorLoader执行查询以显示BizInbox时,该查询返回游标并启动SyncAdapter,后者应获取数据并停止其活动

但我的问题是SyncAdatert的onPerformSync启动了一次又一次。当游标重新加载数据并启动onPerformSync时,它看起来就像是一个无尽的循环……正如我所希望的那样,SyncAdapter可以在没有任何队列的情况下并行执行。

我应该注意到REST后端正确地处理数据,第二个请求onPerformSync没有数据,因为它使用了If-Modified-REST报头。

这显然是我做错了什么,因为我的SyncAdapter没有做同步回退,没有结束的请求。

When I is if (!ContentResolver.isSyncActive(mConnectedAccount,Scheme.AUTHORITY)) { ContentResolver.requestSync( mConnectedAccount,//同步帐户Scheme.AUTHORITY,//内容授权b);// Extras } else { Log.d(TAG,"> runSyncAdaterForClaimBizInbox跳过正在启动的适配器,它已经处于活动状态“);}

我能够赢得这个问题,但问题仍然是如何执行这种同步,如果需要同步部分数据-不是所有的数据ContentResolver.isSyncActive(mConnectedAccount,Scheme.AUTHORITY) -这种方法不能给出信息,它是同步的数据部分,我没有一个队列,由于某些原因在这里。如何处理这个问题?

请帮我找出错误,或者可能有人有模式C的可编译代码来找出如何正确地实现这个模式。

提前谢谢。

代码如下:

公共类ContentProvider {

代码语言:javascript
复制
 @Override
 public Cursor query(final Uri uri, final String[] projection, final String selection, final String[] selectionArgs, final String sortOrder) {

     final SQLiteQueryBuilder qb = new SQLiteQueryBuilder();
     final String orderBy = prepareQuery(uri, sortOrder, qb);

     final SQLiteDatabase db = databaseHelper.getReadableDatabase();
     final Cursor cursor = qb.query(db, projection, selection, selectionArgs, null, null, orderBy);

     runSyncAdapterForQuery(uri);

     cursor.setNotificationUri(getContext().getContentResolver(), uri);

     return cursor;
 }

void runSyncAdapterForQuery(Uri uri) {
    switch (uriMatcher.match(uri)) {
        case BIZ_INBOX:
            runSyncAdaterForBizInbox(METHOD_GET);
            break;
    }
}

void runSyncAdaterForBizInbox(String method) {

    Bundle b = new Bundle();

    b.putBoolean(ContentResolver.SYNC_EXTRAS_MANUAL, true);
    b.putBoolean(ContentResolver.SYNC_EXTRAS_EXPEDITED, true);

    b.putString(METHOD_EXTRA, method);
    b.putInt(RESOURCE_TYPE_EXTRA, RESOURCE_TYPE_BIZ_INBOX);

    Account mConnectedAccount = new Account(BPalAccountGeneral.ACCOUNT_NAME, BPalAccountGeneral.ACCOUNT_TYPE);
   //if (!ContentResolver.isSyncActive(mConnectedAccount, Scheme.AUTHORITY)) { Do i need this ? Where is Sync Adapters queue ?
     ContentResolver.requestSync(
            mConnectedAccount, // Sync account
            Scheme.AUTHORITY, // Content authority
            b);               // Extras
   //}
}

}

代码语言:javascript
复制
SyncAdapter

@Override
public void onPerformSync(Account account, Bundle extras, String authority, ContentProviderClient provider, SyncResult syncResult) {


    String accessToken = "some_token";

    switch (resourceType) {
        case UNKNOWN_RESOURCE_TYPE:
            //do update all ...
            break;
        case RESOURCE_TYPE_BIZ_INBOX:
            if (method.equals(METHOD_GET)) {

                String url = "some_inbox_url"

                GetBizInboxRequest request = new GetBizInboxRequest();

                BizInboxDAO BizInboxDAO = new BizInboxDAO();
                String lastModified = BizInboxDAO.getLastModified(getContext().getContentResolver());

                RestMethodResult<RestListEntityContainer<BizInboxEntity>> restMethodResult =
                        request.getBizInboxItems(
                                url,
                                null,
                                lastModified,
                                accessToken);

                int statusCode = restMethodResult.getStatusCode();

                if (statusCode == MobileConstant.HTTP_OK) {
                    List<BizInboxEntity> serverBizInboxEntities = restMethodResult.getResource().getList();

                    for (BizInboxEntity entity : serverBizInboxEntities) {
                        BizInboxDAO.insertyData(getContext().getContentResolver(), entity);
                        syncResult.stats.numInserts++;
                    }

                    if(syncResult.stats.numInserts > 0) {
                        Log.d(TAG, "> onPerformSync  BizInboxDAO.sendNotification ");
                        BizInboxDAO.sendNotification(getContext().getContentResolver());
                    }
                } else {
                    syncResult.stats.numIoExceptions++;
                    syncResult.databaseError = true;
                }
            }
            break;
        default:
            break;
    }
}
EN

回答 1

Stack Overflow用户

发布于 2015-06-26 16:11:55

我使用上面的代码犯了一个大错误。

  1. 根据模式C,同步适配器应检查当前数据状态。我不应该直接从内容提供商调用请求同步。可以使用的方法在Android文档https://developer.android.com/training/sync-adapters/running-sync-adapter.html
  2. If I称为同步中进行了描述,如下所示//禁用同步回退和忽略同步首选项。在其他words...perform中同步!b.putBoolean(ContentResolver.SYNC_EXTRAS_MANUAL,true);b.putBoolean(ContentResolver.SYNC_EXTRAS_EXPEDITED,true);

Account mConnectedAccount =新帐号(AccountGeneral.ACCOUNT_NAME,AccountGeneral.ACCOUNT_TYPE);ContentResolver.requestSync( mConnectedAccount,//同步帐号Scheme.AUTHORITY,//内容授权b);//额外的

你应该记住我在评论中写的:

禁用同步退避和忽略同步首选项。在其他words...perform中立即同步!

这意味着如果请求失败,它不会尝试重复自己。这段代码并行地运行它的操作。例如,如果您运行此requestSync两个磁贴,您将有两个同步线程,正如我所发现的。

最后一个主要注意事项:当我从查询中运行requestSync时,它导致了一些无穷无尽的循环,因为在requestSync之后,我做了Cursot通知,调用了重新查询,然后再次运行requestSync,等等。

我找到了一个很好的示例应用程序,它使用了模式C-这是链接:https://github.com/taoliuh/v2ex

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/30936896

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档