Question

I have a very plain CursorLoader that loads a Cursor. I store the cursor as a field in my activity. (So not in a CursorAdapter!)

    public static class BundlesLoader extends CursorLoader {
        public static final String[] PROJECTION = new String[]{
                BaseColumns._ID,
                TITLE,
                SUBTITLE,
                DESCRIPTION
        };

        public BundlesLoader(Context ctx) {
            super(
                    ctx,
                    URI_BUNDLES,
                    PROJECTION,
                    null,
                    null,
                    POSITION + " ASC"
            );
        }
    }

When I call ContentResolver.notifyChange(URI_BUNDLES, null), I would expect the CursorLoader to reload, but it doesn't. (See LoaderCallbacks below; I log the callbacks.)

To debug this issue, I registered a little ContentObserver, which does work, oddly:

      getContentResolver().registerContentObserver(LegislationProvider.URI_BUNDLES,
            false, new ContentObserver(new Handler()) {
        @Override
        public void onChange(boolean selfChange) {
            Log.e("hello", "bundles changed!!!!!");
        }

        @Override
        public void onChange(boolean selfChange, Uri uri) {
            onChange(selfChange);
        }
    });

So know I don't know how to debug from here. My CursorLoader initializes okay, my ContentObserver works, but for some reason the CursorLoader does not reload the Cursor when the underlying database changes. What can be wrong?


Here are my LoaderCallbacks:

    @Override
    public android.support.v4.content.Loader onCreateLoader(int id, Bundle bundle) {
        switch (id) {
            case LoaderIds.LOADER_BUNDLES:
                d("Creating new bundles loader");
                return new Model.Bundle.Loader(getApplicationContext());
            default:
                throw new IllegalArgumentException(
                        "Could not handle loader id " + id);
        }
    }

    @Override
    public void onLoadFinished(android.support.v4.content.Loader loader, Cursor cursor) {
        switch (loader.getId()) {
            case LoaderIds.LOADER_BUNDLES:
                d("onLoadFinished: Bundles loaded with "
                        + cursor.getCount() + " elements");
                mMasterFragment.setBundlesCursor(cursor);
                break;
            default:
                throw new IllegalArgumentException(
                        "Could not handle loader id " + loader.getId());
        }
    }

    @Override
    public void onLoaderReset(android.support.v4.content.Loader loader) {
        switch (loader.getId()) {
            case LoaderIds.LOADER_BUNDLES:
                d("onLoaderReset: Clearing collection adapter");
                mMasterFragment.setBundlesCursor(null);
                break;
            default:
                throw new IllegalArgumentException(
                        "Could not handle loader id " + loader.getId());
        }
    }
Was it helpful?

Solution

You do still need to call setNotificationUri(getContentResolver(), URI_BUNDLES) on the cursor even though you are using the CursorLoader. I don't know from your question if you are doing that or not.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top