Android:重新启动内容已更改CursorLoader

时间:2015-07-18 10:16:54

标签: android android-contentprovider android-cursorloader contentobserver

我使用 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
    }
}

1 个答案:

答案 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);
}