我假设您使用 AsyncTask 来加载光标只是为了解释,但如果您使用 Loader、ThreadPool 或其他任何东西,它的工作原理是一样的。
从服务中,只要新数据发生更改,我就会发送LocalBroadcast。活动可能存在或不存在,因此广播是让它知道有新数据的好方法。所以从你会做的服务:
// that's an example, let's say your SyncAdapter updated the album with this ID
// but you could create a simply "mybroadcast", up to you.
Intent i = new Intent("albumId_" + albumId);
LocalBroadcastManager.getInstance(this).sendBroadcast(i);
然后从具有光标的活动/片段中,您将像这样收听此广播:
public void onResume(){
// the filter matches the broadcast
IntentFilter filter = new IntentFilter("albumId_" + albumId);
LocalBroadcastManager.getInstance(this).registerReceiver(myReceiver, filter);
}
public void onPause(){
LocalBroadcastManager.getInstance(this).unregisterReceiver(myReceiver);
}
// and of course you have to create a BroadcastReceiver
private BroadcastReceiver myReceiver = new BroadcastReceiver(){
@Override
public void onReceive(Context context, Intent intent){
// here you know that your data have changed, so it's time to reload it
reloadData = new ReloadData().execute(); // you should cancel this task onPause()
}
};
正如我所说,下一部分取决于您用于加载光标的线程方法,对于这个示例,我将在 AsyncTask 中展示,因为它非常受欢迎(但我真的相信您和world 应该使用 Loaders 模式)。
private class ReloadData extends AsyncTask<Void, Void, Cursor> {
protected Cursor doInBackground(Void... void) {
// here you query your data base and return the new cursor
... query ...
return cursor;
}
protected void onPostExecute(Cursor result) {
// you said you're using a subclass of CursorAdater
// so you have the method changeCursor, that changes the cursor and closes the old one
myAdapter.changeCursor(result);
}
}
我之前测试和使用过的上述方法,我知道它有效。有一种方法可以使其与标志 FLAG_REGISTER_CONTENT_OBSERVER 一起使用并覆盖 onContentChanged() 以重新执行查询并交换光标,但我从未测试过它。会是这样的:
使用构造函数CursorAdapter(Context context, Cursor c, int flags) 传递标志FLAG_REGISTER_CONTENT_OBSERVER 并覆盖onContentChanged() 来初始化您的适配器。在 onContentChanged 中,您将像上面一样执行 AsyncTask。这样您就不必使用LocalBroadcastManager,因为数据库会发出警报。该方法不是我的主要答案的原因是因为我从未测试过它。
请注意,autoRequery 已被弃用,不鼓励使用,因为它在 UI 线程中执行数据加载。
编辑:
我刚刚注意到内容观察器是 API 11 的东西。您有两种选择:1 改用支持库:https://developer.android.com/reference/android/support/v4/widget/CursorAdapter.html 或广播选项。