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 then change to landscape
I change back to portrait
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?
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 );
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.
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.
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
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..
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);
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With