Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit cbade7f4 authored by Adam Powell's avatar Adam Powell
Browse files

Retain loaders through stopped config changes

Framework edition

Previously we would throw away any stopped LoaderManagers when we went
to retain instances to pass along as nonConfigurationInstances during
config changes or similar activity restarts. This causes loaders to do
more work than they need to when a calling activity starts a new
activity on top, a config change happens (e.g. screen rotation) and
then the top activity is finished, restarting the caller in a new
configuration. The loaders would go through onReset unnecessarily,
potentially throwing away data to be reloaded again after the config
change completes.

Instead of throwing away stopped LoaderManagers in this case, restart
them and retain them across the config change so they can resume where
they left off.

Bug 27176186

Change-Id: Ia52c6448d2ad41dcb25d493770d9ffae20a19d2a
parent 9a916e56
Loading
Loading
Loading
Loading
+8 −0
Original line number Diff line number Diff line
@@ -2098,7 +2098,15 @@ public class Activity extends ContextThemeWrapper
        Object activity = onRetainNonConfigurationInstance();
        HashMap<String, Object> children = onRetainNonConfigurationChildInstances();
        FragmentManagerNonConfig fragments = mFragments.retainNestedNonConfig();

        // We're already stopped but we've been asked to retain.
        // Our fragments are taken care of but we need to mark the loaders for retention.
        // In order to do this correctly we need to restart the loaders first before
        // handing them off to the next activity.
        mFragments.doLoaderStart();
        mFragments.doLoaderStop(true);
        ArrayMap<String, LoaderManager> loaders = mFragments.retainLoaderNonConfig();

        if (activity == null && children == null && fragments == null && loaders == null
                && mVoiceInteractor == null) {
            return null;
+9 −2
Original line number Diff line number Diff line
@@ -308,15 +308,22 @@ public abstract class FragmentHostCallback<E> extends FragmentContainer {
    ArrayMap<String, LoaderManager> retainLoaderNonConfig() {
        boolean retainLoaders = false;
        if (mAllLoaderManagers != null) {
            // prune out any loader managers that were already stopped and so
            // have nothing useful to retain.
            // Restart any loader managers that were already stopped so that they
            // will be ready to retain
            final int N = mAllLoaderManagers.size();
            LoaderManagerImpl loaders[] = new LoaderManagerImpl[N];
            for (int i=N-1; i>=0; i--) {
                loaders[i] = (LoaderManagerImpl) mAllLoaderManagers.valueAt(i);
            }
            final boolean doRetainLoaders = getRetainLoaders();
            for (int i=0; i<N; i++) {
                LoaderManagerImpl lm = loaders[i];
                if (!lm.mRetaining && doRetainLoaders) {
                    if (!lm.mStarted) {
                        lm.doStart();
                    }
                    lm.doRetain();
                }
                if (lm.mRetaining) {
                    retainLoaders = true;
                } else {
+1 −1
Original line number Diff line number Diff line
@@ -1114,7 +1114,7 @@ final class FragmentManagerImpl extends FragmentManager implements LayoutInflate
                            if (!f.mRetaining) {
                                f.performDestroy();
                            } else {
                                f.mState = Fragment.CREATED;
                                f.mState = Fragment.INITIALIZING;
                            }

                            f.mCalled = false;