SimpleCursorAdapter's old constructor deprecated.. really?
Asked Answered
W

5

9

Here it says that SimpleCursorAdapter's API level 1 constructor is deprecated and the use of LoaderManager and CursorLoader is recommended.

But delving into the LoaderManager and CursorLoader's use I found this example where inside an inner class that extends a ListFragment (an extension of Fragment itself I suppose) we create a CursorLoader. Everything seems ok, except for the fact that CursorLoader takes a Uri as an argument. So this implies that I need to create a ContentProvider to get access to my database.

I must confess it looks like an overkill to have to go through all of this just to create a simple ListView with items coming from a database. Specially if I have no intention of making my database data available to other apps, and the main purpose of a content provider is to do that.

So is it really worth it?

Especially in cases like mine where the content to be fetched is likely going to be small. I'm seriously considering doing it the old way, what do you say?

Windbroken answered 31/8, 2011 at 4:8 Comment(3)
Are you supporting API 11 or higher only?Selfcontradiction
No of course I am not, I was willing to use the compatibility library that gives previous releases support for Fragments and Loaders.Windbroken
whats the name of the sample you found(seems like something I want to do in my app)? The link is just explaining the samples in general..Essy
S
8

I wrote a simple CursorLoader that does not need a content provider:

import android.content.Context;
import android.database.Cursor;
import android.support.v4.content.AsyncTaskLoader;

/**
 * Used to write apps that run on platforms prior to Android 3.0. When running
 * on Android 3.0 or above, this implementation is still used; it does not try
 * to switch to the framework's implementation. See the framework SDK
 * documentation for a class overview.
 *
 * This was based on the CursorLoader class
 */
public abstract class SimpleCursorLoader extends AsyncTaskLoader<Cursor> {
    private Cursor mCursor;

    public SimpleCursorLoader(Context context) {
        super(context);
    }

    /* Runs on a worker thread */
    @Override
    public abstract Cursor loadInBackground();

    /* Runs on the UI thread */
    @Override
    public void deliverResult(Cursor cursor) {
        if (isReset()) {
            // An async query came in while the loader is stopped
            if (cursor != null) {
                cursor.close();
            }
            return;
        }
        Cursor oldCursor = mCursor;
        mCursor = cursor;

        if (isStarted()) {
            super.deliverResult(cursor);
        }

        if (oldCursor != null && oldCursor != cursor && !oldCursor.isClosed()) {
            oldCursor.close();
        }
    }

    /**
     * Starts an asynchronous load of the contacts list data. When the result is ready the callbacks
     * will be called on the UI thread. If a previous load has been completed and is still valid
     * the result may be passed to the callbacks immediately.
     * <p/>
     * Must be called from the UI thread
     */
    @Override
    protected void onStartLoading() {
        if (mCursor != null) {
            deliverResult(mCursor);
        }
        if (takeContentChanged() || mCursor == null) {
            forceLoad();
        }
    }

    /**
     * Must be called from the UI thread
     */
    @Override
    protected void onStopLoading() {
        // Attempt to cancel the current load task if possible.
        cancelLoad();
    }

    @Override
    public void onCanceled(Cursor cursor) {
        if (cursor != null && !cursor.isClosed()) {
            cursor.close();
        }
    }

    @Override
    protected void onReset() {
        super.onReset();

        // Ensure the loader is stopped
        onStopLoading();

        if (mCursor != null && !mCursor.isClosed()) {
            mCursor.close();
        }
        mCursor = null;
    }
}

It only needs the AsyncTaskLoader class. Either the one in Android 3.0 or higher, or the one that comes with the compatibility package.

Selfcontradiction answered 14/9, 2011 at 20:8 Comment(1)
Found a nice code sample for the SimpleCursorLoader - bitbucket.org/ssutee/418496_mobileapp/src/fc5ee705a2fd/demo/… - found it very useful !Alignment
M
4

Just use the constructor below it, the one that takes the flags. Don't use the FLAG_AUTO_REQUERY, just pass 0 for the flags.

Unless you really need to handle data changes to the underlying DB while the user is looking at the ListView then you don't need to worry about needing to requery.

If on the other hand you want the ListView to show changes to the DB while the user is looking at the list then follow Google's advice and use the CursorLoader.

EDIT:

Since the second constructor is only available in API 11 you may just want to extend CursorAdapter yourself. You pretty much just need to implement bindView and newView and you are done.

Micaelamicah answered 31/8, 2011 at 4:42 Comment(0)
D
1

Use simpleCursorAdapter deprecated constructor only. This kind of error appeared when I was developing my app but i used it and it worked perfectly with my app. Or try to use the constructor below deprecated one in android developers website which has an extra argument i.e the flag argument with it.

Dowel answered 31/8, 2011 at 5:28 Comment(1)
But notice that the second constructor was only introduced in api level 11. So I would have to add the compatibility library just to use it. Adding a static library also makes my apk bigger at the end, and if it's just for the sake of using that constructor I honestly don't see the point of it.Windbroken
V
1

I believe CursorLoader is currently intended for use with a ContentProvider.

If you wish to load directly from your database using the new framework; you can consider extending AsyncTaskLoader and returning it from onCreateLoader instead of using a CursorLoader.

If you are using the existing methods you have to be more careful of how long your query operation will take. If your query will take noticable amounts of time consider using an AsyncTask to load the cursor (and be aware of requery running in the UI thread).

Vulgar answered 31/8, 2011 at 5:31 Comment(0)
R
0

I know this thread is old, but you could just add a last parameter into the SimpleCursorAdapter object creation. Just add ", 0".

It's a flag that Android likes and the warning goes away.

Example:

SimpleCursorAdapter dataAdapter = new SimpleCursorAdapter(getApplicationContext(), R.layout.item_list_layout, cursor, fromDB(), toLayout(), 0);
Rep answered 11/6, 2014 at 23:49 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.