OnLoadFinished() called twice
Asked Answered
H

5

21

I'm trying to figure out if I'm doing something wrong with respect to Loaders. I'm using the support library, and I have a Fragment which in onCreate() calls initLoader() setting itself as the LoaderCallbacks, however on a rotation it is receiving the result twice in onLoadFinished(), once as a result of calling init (and it already having the data), and once as a result of FragmentActivity looping through all Loaders in onStart() and delivering the result since it already has the data.

If I only call init once (on first launch of the Fragment), it doesn't set itself as the callback for the Loader so it doesn't receive a call to onLoadFinished at all. It seems as though onLoadFinished should only be called once since some expensive things may be done in onLoadFinished() (such as clearing list adapters, etc.), so I'm just trying to figure out if this is a bug or if I am just calling init at the wrong time or something else.

Anyone have any insight to this issue?

Hf answered 6/2, 2013 at 0:59 Comment(2)
I'm not sure why this happens, but calling getLoaderManager().initLoader(0, null, this); in onResume() seems to be the solution for a lot of people (inc. me). See https://mcmap.net/q/583863/-android-loadercallbacks-onloadfinished-called-twice .Excitability
This is the best answer I have found on this: https://mcmap.net/q/553371/-should-we-really-call-getloadermanager-initloader-in-onactivitycreated-which-causes-onloadfinished-being-called-twicePeritonitis
Z
3

I had a similar problem and the cause was that I had initLoader and restartLoader in my code. Depending on user's action, my query could change, so I needed to restart my loader.

The solution was to use only restartLoader, even in onResume callback method replace initLoader with restartLoader.

Zeniazenith answered 28/5, 2015 at 5:55 Comment(0)
B
3

This is a rather old question, but for future readers I have an alternative solution. Basically what I ended up doing was restart the loader if it existed.

public void onActivityCreated(Bundle savedInstanceState) {
...
       if(getLoaderManager().getLoader(Constants.LOADER_ID) == null) {
            getLoaderManager().initLoader(Constants.LOADER_ID, null, this);
        } else {
            getLoaderManager().restartLoader(Constants.LOADER_ID, null, this);
        }

...
}

This solved my issue with that on screen rotate the loader was triggered twice. One thing too note is that this is only needed for me on Android < 6 that I tested. Android 6 seem to not have this issue at all.

Burley answered 29/11, 2015 at 21:41 Comment(1)
This solution may works, but has the same problem as Alex Lockwood mentioned earlier.Shoshone
T
2

I am experiencing same problem my self, with no good solution. It seems as bug in Android framework, here is similar thread in which proposed solution is to place initLoader() in onResume() - I have tried it and it works, on onLoadFinished() gets called only once: Android: LoaderCallbacks.OnLoadFinished called twice

Tenor answered 14/2, 2013 at 10:25 Comment(0)
C
2

See my post at Android: LoaderCallbacks.OnLoadFinished called twice

I had a similar problem when restarting Fragments in a ViewPager. My solution is to remove the Loader once I'm finished with it (at the end of onLoadFinished) by calling

getLoaderManager().destroyLoader(LOADER_ID);

Hope it helps!

Casefy answered 4/3, 2014 at 21:22 Comment(1)
This is a very bad solution... destroying the Loader will also destroy all of the data associated with it. One of the main benefits of Loaders is that data is retained across configuration changes (such as changes in orientation, etc.)... destroying this data means you will need to requery the data each time a configuration change occurs.Angwantibo
A
0

It is looks like framework Loader wrong implementation/bug. 1. look at what I got from Log.v(LOG_TAG, ...) messages from every important method/callback after screen rotation:

...: .initLoader() 100
...: onStartLoading()
...: onLoadFinished()
...: updateUi(); articles size=10
...: loadInBackground()
...: getInputStream() - HttpRequest
...: onLoadFinished()
...: updateUi(); articles size=10

2. As you can see everything after 'updateUi()' is no needed there.

Addict answered 10/5, 2020 at 15:42 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.