説明のために、カーソルをロードするために 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 で示します (しかし、あなたと世界中のすべての開発者が使用する必要があると本当に信じています)。ローダー パターン)。
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 のものであることに気付きました。2 つのオプションがあります。1 代わりにサポート ライブラリを使用します: https://developer.android.com/reference/android/support/v4/widget/CursorAdapter.htmlまたはブロードキャスト オプション