Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Sometimes don't get onCreateLoader callback after calling initLoader

I have an activity that calls initLoader when it is created in order to load the data that the activity will display. Normally, this works fine. I have breakpoints set to see the order that everything happens. First I call initLoader, then I get the OnCreateLoader callback, then the OnLoadFinished callback, then everything is great.

However, I noticed that if I changed the orientation on my Android that I don't get the OnCreateLoader callback or the OnLoadFinished callback, resulting in no data displayed on the page. I still get my breakpoint on the initLoader call so I know that is happening, but I don't get an error and I can't find any documentation explaining why I wouldn't get a callback after calling initLoader.

Interestingly, I do get the callbacks if I return to the original orientation.

So, to summarize:

I start the activity in portrait orientation

  • I call initLoader
  • I get onCreateLoader and onLoadFinished callbacks

I then change to landscape

  • I call initLoader
  • no onCreateLoader or onLoadFinished callbacks

I change back to portrait

  • I call initLoader
  • I get onCreateLoader and onLoadFinished callbacks

Similarly, if I start the activity in landscape mode I get the callbacks. Then, if I switch to portrait, I don't. Then, if I switch back to landscape I get the callbacks again.

Does anyone have any idea what's going on?

like image 979
casimps1 Avatar asked Oct 18 '11 15:10

casimps1


6 Answers

I had something very similar thing happening with cursor adapters in fragments on orientation change. initloader was called in onCreateView (also tried onStart and onResume) but onCreatLoader as well as the other loader callback methods never were called. Also of note in my case the fragment was contained in a view pager.

So initially the activity and view pager and fragments were created and everything worked. On orientation change though the lists in my fragments would not get data. Changing orientation again and the data came back.

In my case the fix was changing this:

getActivity().getLoaderManager().initLoader( 0, null, this );

I changed it to this

getLoaderManager().initLoader( 0, null, this );
like image 65
startoftext Avatar answered Oct 09 '22 04:10

startoftext


I spent weeks on tracking this issue. It tired to put the previous fragment content to my new fragment. Finally fixed.

In my onCreate() method of which fragment implemented LoaderManager, I did this

  getLoaderManager().initLoader(0, null, this);
        if(!getLoaderManager().getLoader(0).isReset()) {
            getLoaderManager().restartLoader(0, null, this);
        }

It works when new loader was not actived properly.

like image 26
Xin Zhang Avatar answered Oct 09 '22 06:10

Xin Zhang


We've seen this same problem with Fragments in a ViewPager. It appears that the loaders are not properly activated again when a fragment is resumed. In fact, when the fragment is paused, our CursorLoader no longer gets ContentObserver callbacks as I would expect.

Our workaround has been to call restartLoader() which dumps the previous contents and reloads the data. This would have the same net affect as destroyLoader(); initLoader(), but it will be more efficient.

like image 23
jsmith Avatar answered Oct 09 '22 05:10

jsmith


You'll need to call initLoader in your onCreate

For a similar issue and more info have a look at LoaderCallbacks.onLoadFinished not called if orientation change happens during AsyncTaskLoader run

like image 31
gnorsilva Avatar answered Oct 09 '22 04:10

gnorsilva


I've been tracing this problem

Initial create (OnActivityCreated)

initLoader -> OnCreateLoader -> OnOnStartLoading -> OnLoadFinished

Orientation change - OnActivityCreated called again

initLoader - OnLoadFinished (Without loading any data!) - bug.

The only workaround I've found is to call destroyLoader() just before the init. This forces the proper Create/Start/Finished sequence to happen.

What appears to be happening is the initLoader code is written to assume the fragment isn't destroyed during an orientation change, which is of course not how the rest of android works..

like image 23
Tony Hoyle Avatar answered Oct 09 '22 06:10

Tony Hoyle


I had this problem recently, and would like to submit my solution.

I found it was simply enough to just do:

    Loader<Cursor> loader = getActivity().getLoaderManager().getLoader(LOADERID);

    if (loader == null) {
        getActivity().getLoaderManager().initLoader(LOADERID, null, this);
    } else {
        getActivity().getLoaderManager().restartLoader(LOADERID, null, this);
    }
like image 25
Chad Mx Avatar answered Oct 09 '22 06:10

Chad Mx