Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Loaders and onLoaderReset Android

I implemented a Loader in my application for querying data from the database. I listen the changes that happen' by implementing LoaderCallbacks<Cursor> listener. The problem that I have is when using the onLoaderReset(Loader<Cursor> loader) method when my data change and I want to invalidate and free any data associated with the loader. In all the examples, in this method there is the following call:

mAdapter.swapCursor(null);

But the thing is I don't use the data from the cursor in adapter, I use it in some other way in my application.

(directly from the returned cursor in onLoadFinished(Loader<Cursor> loader, Cursor data), for example)

        @Override
        public void onLoadFinished(Loader<Cursor> loader, Cursor data) {

            if (data.moveToFirst()) {
                TOTAL_CARDS = data.getCount();
                mView.createCards(TOTAL_CARDS);
            } else {
                TOTAL_CARDS = 0;
                mView.createCards(TOTAL_CARDS);
            }


        }

What would be the corresponding thing to do here, that is similar with mAdapter.swapCursor. I don't have much experience with loaders, in fact I just started working with them, so if someone has a solution to this, I would appreciate it. Thx!

EDIT: For now, I am passing null to the loader and it works, like this:

@Override
public void onLoaderReset(Loader<Cursor> loader) {
        loader = null;
}

};

But is this the right solution?

like image 862
Sandra Avatar asked Oct 17 '12 14:10

Sandra


People also ask

What are loaders in Android?

Loaders are special purpose classes that manage loading and reloading updated data asynchronously in the background using AsyncTask. Introduced in Android 3.0, loaders have these characteristics: They are available to every Activity and Fragment. They provide asynchronous loading of data in the background.

What is loader manager Android?

This helps an application manage longer-running operations in conjunction with the Activity or Fragment lifecycle; the most common use of this is with a CursorLoader , however applications are free to write their own loaders for loading other types of data. While the LoaderManager API was introduced in Build.

What is a loader phone?

What is a Loader? Loader is a set of APIs, known as Loader APIs given by Android, to load data asynchronously in activity/fragment.

How can we use loaders to display and load data?

There is only one LoaderManager per activity or fragment, but a LoaderManager can manage multiple loaders. To get LoaderManager, call getSupportLoaderManager() from the activity or fragment. To start loading data from a loader, call either initLoader() or restartLoader() .


1 Answers

Doing

@Override
public void onLoaderReset(Loader<Cursor> loader) {
  loader = null;
}

is just as good as doing nothing. In your example code, you are merely nulling your method's local reference to its argument. However, this reference will always be removed after the return of the method call. (You might want to read Is Java "pass-by-reference" or "pass-by-value"? for a further discussion of the topic.)

The onLoaderReset(Loader) method gets called when your loader's callback (usually an Activity or Fragment instance) is asked to release all references to the Cursor which it has gained via onLoadFinished(Loader, Cursor) before. Basically this method asks you to clean up since the Loader will soon close the Cursor it provided to you before. After the cursor was closed, you will not longer be able to retrieve data by it. If the cursor would however still be in use (typically by a CursorAdapter as you mentioned) after it was closed, this would cause an exception to be thrown.

Similarly, onLoadFinished(Loader, Cursor) has an implicit contract asking that after the method returns any formerly provided Cursor objects must not longer be in use. Instead, you have to replace these references by the new cursor which is provided as a method argument. In contrast, onLoaderReset(Loader) asks you to fulfill the same contract, but without providing a replacement, i.e. you should remove all references to a formerly retrieved Cursor.

In your example, you do not let your Cursor escape the method scope but instead you are reading the data right away. Therefore, it is not necessary to remove any references to a Cursor object which was provided via onLoadFinished(Loader, Cursor) since there are none. An empty implementation of onLoaderReset(Loader) to fulfill the interface contract will therefore do the job for you.

like image 70
Rafael Winterhalter Avatar answered Oct 17 '22 00:10

Rafael Winterhalter