我假设您使用 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 中展示,因为它非常流行(但我真的相信您和世界上的每个开发人员都应该使用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或广播选项。