我正在使用Sync Adapter为我的应用执行同步。它设置了自动同步:
// Inform the system that this account supports sync
ContentResolver.setIsSyncable(account, AuthenticatorService.AUTHORITY, 1);
// Inform the system that this account is eligible for auto sync when the network is up
ContentResolver.setSyncAutomatically(account, AuthenticatorService.AUTHORITY, true);
如果我要求同步:
Bundle b = new Bundle();
// Disable sync backoff and ignore sync preferences. In other words...perform sync NOW!
b.putBoolean(ContentResolver.SYNC_EXTRAS_MANUAL, true);
b.putBoolean(ContentResolver.SYNC_EXTRAS_EXPEDITED, true);
ContentResolver.requestSync(AuthenticatorService.GetAccount(), AuthenticatorService.AUTHORITY, b);
运行良好 - 一旦网络启动,就会调用SyncAdapter.onPerformSync()。但是,有一个问题:如果网络已启动但未连接到Internet(例如,没有网络共享的热点),仍会调用onPerformSync()。
当然,由于无法访问服务器,因此同步代码失败。更糟糕的是,系统认为一切正常,除非我的数据发生变化,否则不再进行同步调用。
我的问题是:我可以将同步标记为不成功,以便系统稍后再尝试(例如在另一个CONNECTED事件或几秒钟内)或更好地告诉系统仅在真实互联网时执行同步连通性存在?
我可以自己监控网络状态并进行连接检查,但是这会违反同步适配器的全部目的,不是吗。我能想到的唯一解决方法是安排定期同步(使用ContentResolver.addPeriodicSync()),当我的同步代码成功时,将其关闭。但我对此也不是很满意(耗尽电池)。
编辑:关于我的问题的第一部分,this answer是我正在寻找的。它部分地解决了我的问题但是如果连续数量的“非工作”连接,当设备与真实连接相关联时,同步需要几十分钟(因为指数退避算法)。
答案 0 :(得分:1)
感谢csenga的建议,我找到了一个解决方案:使用GcmNetworkManager来安排同步。它看起来有点愚蠢,因为我必须声明另一个服务只是为了调用ContentResolver.requestSync(),如果出现问题,我必须重新安排我的任务,而不是设置SyncResult.stat标志(我'这里几乎复制了Sync Adapter的工作)但仍然比处理我自己的NETWORK_STATE_CHANGED_ACTION接收器更好。