我使用 LoaderManager 和 CursorLoader 以异步方式将数据从 ContentProvider 加载到GUI。一切正常。但我想知道一旦ContentProvider的内容发生变化,如何重新启动加载程序?就我研究的那样,CursorLoader应该自动执行,但在我的情况下它不会!那么,我应该注册内容观察者并重新启动LoaderManager吗?
注意: ContentProvider已正确实施。例如,如果插入了新项目,我将使用主URI和新插入项目的URI调用ContentProvider.notifyChange(...)。对于ContentObservers,这可以正常工作。
public class MyFragment implements LoaderManager.LoaderCallbacks<Cursor> {
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_sample, container, false);
getLoaderManager().initLoader(1, null, this);
return view;
}
@Override
public Loader<Cursor> onCreateLoader(int id, Bundle args) {
if (isDetached())
return null;
Uri queryUri = MyContentProvider.CONTENT_URI;
String[] projection = this.getProjection();
String selection = null;
String[] selectionArgs = null;
String sortOrder = null;
return new CursorLoader(getActivity(), queryUri, projection, selection, selectionArgs, sortOrder);
}
@Override
public void onLoadFinished(Loader<Cursor> loader, Cursor data) {
// ToDo: display the content (in this case it's not a ListView but a Google Map with markers)
// Remark: I'm using the data/cursor only, but I'm not holding the loader!
}
@Override
public void onLoaderReset(Loader<Cursor> loader) {
// ToDo: clear/remove all markers from the map
}
}
答案 0 :(得分:0)
检查是否在返回之前在游标中设置了通知uri。
@Override
public Cursor query(Uri uri, String[] projection, String selection,
String[] selectionArgs, String sortOrder) {
int match = mUriMatcher.match(uri);
SQLiteDatabase db = mDatabaseHelper.getReadableDatabase();
ContentResolver contentResolver = getContext().getContentResolver();
Cursor cursor;
switch (match) {
case ROUTE_POSITIONS:
cursor = db.query(DatabaseContract.PositionEntry.TABLE_NAME, projection, selection, selectionArgs, null, null, sortOrder);
cursor.setNotificationUri(contentResolver, DatabaseContract.PositionEntry.CONTENT_URI);
break;
// do more cases ....
default:
throw new UnsupportedOperationException("Unknow uri: " + uri);
}
return cursor;
}
在您的活动中,您可以定义异步任务以在地图中加载数据
private class LoadMarkers extends AsyncTask<Cursor, MarkerOptions, String>{
@Override
protected void onPreExecute() {
super.onPreExecute();
mMap.clear();
}
@Override
protected String doInBackground(Cursor... params) {
Cursor data = params[0];
LatLng latLng = null;
while (data.moveToNext()) {
double latitude = data.getDouble(data.getColumnIndex(DatabaseContract.PositionEntry.COLUMN_NAME_LATITUDE));
double longitude = data.getDouble(data.getColumnIndex(DatabaseContract.PositionEntry.COLUMN_NAME_LONGITUDE));
String date = data.getString(data.getColumnIndex(DatabaseContract.PositionEntry.COLUMN_NAME_UPDATETIME));
latLng = new LatLng(latitude, longitude);
MarkerOptions markerOptions = new MarkerOptions().title(date).position(latLng);
publishProgress(markerOptions);
Log.d(TAG, "Loading...");
}
int count = data .getCount();
return count + " points";
}
@Override
protected void onProgressUpdate(MarkerOptions... values) {
super.onProgressUpdate(values);
MarkerOptions markerOptions = values[0];
mMap.addMarker(markerOptions);
}
@Override
protected void onPostExecute(String result) {
super.onPostExecute(result);
mTextView.setText(result);
}
}
并在新查询准备就绪时执行
@Override
public void onLoadFinished(android.support.v4.content.Loader<Cursor> loader, Cursor data) {
Log.d(TAG, "data loaded: " + data.getCount() + " points");
new LoadMarkers().execute(data);
}