And*_*zie 5 user-interface android synchronization sync android-syncadapter
我正在开发一个Android应用程序,它与服务器执行后台同步(使用SyncAdapter和身份验证等).
启动前台应用程序(使用UI)时,可能正在进行后台同步,或者可选择通过UI按钮启动后台同步.
我想要一种"插入"正在进行的后台同步(无论是由系统启动,还是定期同步设置或UI)的方法,并显示它在前台活动中的进度.
ContentResolver文档(http://developer.android.com/reference/android/content/ContentResolver.html)提到了一个神秘的"SyncObserver",它没有链接到javadoc,也没有记录(我能找到).
还有一些其他页面提到它(http://www.chinaup.org/docs/migrating/m5-0.9/changes/android.content.ContentResolver.html)但我无法找到更多相关信息.
有人实施过这种野兽吗?
如果没有,是否有人有关于跟踪前台活动中后台同步进度的示例代码或建议?
谢谢你的回答.
由于后台同步的异步特性,您的应用程序(活动)可以通过已经进行的后台同步启动,您可以使用存储在首选项中的状态进行检测.
我所做的是实现一个SyncObserver类,它实现SyncStatusObserver接口并在suspend/resume上创建/销毁.
syncObserverHandle = ContentResolver.addStatusChangeListener( ContentResolver.SYNC_OBSERVER_TYPE_ACTIVE, new SyncObserver() );
Run Code Online (Sandbox Code Playgroud)
这会通知任何与同步(待处理,已启动等)相关的事件,并且我还会检查状态
ContentResolver.isSyncActive();
Run Code Online (Sandbox Code Playgroud)
用于此的Android API非常基本,您必须尊重关于在UI线程上做什么以及什么不做的规则,但是如果有人想看到我的实现只是发布一个问题并指出我并且我将回答乐趣.
我遇到了同样的问题,最终通过 1) 来自 SyncAdapter 的广播和 2) 使用 SharedPreferences 来指示状态的组合来实现它。
在 SyncAdapter 中,类似这样:
public static final String START_SYNC = "com.whatever.sync.start";
public static final String STOP_SYNC = "com.whatever.sync.stop";
public static final String SYNC_PROGRESS = "syncProgress";
public void onPerformSync(Account account, Bundle extras, String authority,
ContentProviderClient provider, SyncResult syncResult) {
// Add an integer to the shared settings to indicate the status
SharedPreferences settings = mContext.getSharedPreferences(Constants.PREFS, 0);
SharedPreferences.Editor editor = settings.edit();
editor.putInt(SyncAdapter.SYNC_PROGRESS, 0);
editor.commit();
Intent intent = new Intent();
intent.setAction(START_SYNC);
mContext.sendBroadcast(intent);
//... do some stuff, setting SYNC_PROGRESS to other values and
// sending more broadcasts as the state changes
// When we are done, remove the "in progress" setting and store some
// other data
editor.putString(SyncAdapter.LAST_UPDATED, new Date().toString());
editor.remove(SyncAdapter.SYNC_PROGRESS);
editor.commit();
Intent stopIntent = new Intent();
stopIntent.setAction(STOP_SYNC);
mContext.sendBroadcast(stopIntent);
}
Run Code Online (Sandbox Code Playgroud)
在该活动中,我们在恢复时执行两件事:1)检查当前是否正在进行同步的共享首选项,2)注册以侦听接收器的广播。
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// .. do some UI stuff
mReceiver = new SyncReceiver(this);
}
@Override
public void onResume() {
super.onResume();
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction(SyncAdapter.START_SYNC);
intentFilter.addAction(SyncAdapter.STOP_SYNC);
registerReceiver(mReceiver, intentFilter);
showProgress();
}
public void showProgress() {
SharedPreferences settings = getSharedPreferences(Constants.PREFS, 0);
if (settings.contains(SyncAdapter.SYNC_PROGRESS)) {
// ... set the UI to show that a sync is in progress
} else {
// ... set the UI to show that a sync is NOT in progress
}
}
private class SyncReceiver extends BroadcastReceiver {
private MyActivity mActivity;
public SyncReceiver(MyActivity activity) {
mActivity = activity;
}
@Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals(SyncAdapter.START_SYNC)) {
Log.i("@string/app_name", "Started sync");
mActivity.showProgress();
}
else if (intent.getAction().equals(SyncAdapter.STOP_SYNC)) {
Log.i("@string/app_name", "Started sync");
mActivity.showProgress();
}
}
}
Run Code Online (Sandbox Code Playgroud)
这似乎对我有用。我必须承认,我有一种感觉,由于广播的异步性质,这存在一些潜在的问题。任何有关改进我的方法的意见将不胜感激!
| 归档时间: |
|
| 查看次数: |
2276 次 |
| 最近记录: |