Difference between initLoader and restartLoader in LoaderManager

后端 未结 6 630
春和景丽
春和景丽 2020-12-22 16:17

I\'m completely lost regarding the differences between the initLoader and the restartLoader functions of the LoaderManager:

6条回答
  •  盖世英雄少女心
    2020-12-22 17:05

    I recently hit a problem with multiple loader managers and screen orientation changes and would like to say that after a lot of trial-and-error, the following pattern works for me in both Activities and Fragments:

    onCreate: call initLoader(s)
              set a one-shot flag
    onResume: call restartLoader (or later, as applicable) if the one-shot is not set.
              unset the one-shot in either case.
    

    (in other words, set some flag so that initLoader is always run once & that restartLoader is run on the 2nd & subsequent passes through onResume)

    Also, remember to assign different ids for each of your loaders within an Activity (which can be a bit of an issue with fragments within that activity if you're not careful with your numbering)


    I tried using initLoader only .... didn't seem to work effectively.

    Tried initLoader on onCreate with null args (docs say this is ok) & restartLoader (with valid args) in onResume ....docs are wrong & initLoader throws a nullpointer exception.

    Tried restartLoader only ... works for a while but blows on 5th or 6th screen re-orientation.

    Tried initLoader in onResume; again works for a while & then blows. (specifically the "Called doRetain when not started:"... error)

    Tried the following : (excerpt from a cover class that has the loader id passed into the constructor)

    /**
     * start or restart the loader (why bother with 2 separate functions ?) (now I know why)
     * 
     * @param manager
     * @param args
     * @deprecated use {@link #restart(LoaderManager, Bundle)} in onResume (as appropriate) and {@link #initialise(LoaderManager, Bundle)} in onCreate 
     */
    @Deprecated 
    public void start(LoaderManager manager, Bundle args) {
        if (manager.getLoader(this.id) == null) {
            manager.initLoader(this.id, args, this);
        } else {
            manager.restartLoader(this.id, args, this);
        }
    }
    

    (which I found somewhere in Stack-Overflow)

    Again, this worked for a while but still threw the occasional glitch.


    From what I can figure out while debugging, I think that there is something to do with save/restore instance state that requires that initLoader(/s) are run in the onCreate part of the lifecycle if they are to survive a spin of the cycle. ( I may be wrong.)

    in the case of Managers that cannot be started until the results come back from another manager or task (ie. cannot be initialised in onCreate), I only use initLoader. (I may not be correct in this but it seems to work. These secondary loaders are not part of the immediate instance-state so using initLoader may actually be correct in this case)

    lifecycle


    Looking at the diagrams and docs, I would have thought that initLoader should go in onCreate & restartLoader in onRestart for Activities but that leaves Fragments using some different pattern and I've not had time to investigate if this is actually stable. Can anyone else comment on if they have success with this pattern for activities?

提交回复
热议问题