[Android] MainActivity: fix and document onResumeFragments() behaviour

Edward Wang git at videolan.org
Sun Mar 3 23:15:52 CET 2013


vlc-ports/android | branch: master | Edward Wang <edward.c.wang at compdigitec.com> | Sun Mar  3 16:14:58 2013 -0500| [0aa11efe1e8b13291209ac5afd860980772def13] | committer: Edward Wang

MainActivity: fix and document onResumeFragments() behaviour

This should fix a lot of fragment and fragment lifecycle related bugs.

> http://git.videolan.org/gitweb.cgi/vlc-ports/android.git/?a=commit;h=0aa11efe1e8b13291209ac5afd860980772def13
---

 .../src/org/videolan/vlc/gui/MainActivity.java     |   44 ++++++++++++++++----
 .../src/org/videolan/vlc/gui/SidebarAdapter.java   |   19 +++++++++
 2 files changed, 54 insertions(+), 9 deletions(-)

diff --git a/vlc-android/src/org/videolan/vlc/gui/MainActivity.java b/vlc-android/src/org/videolan/vlc/gui/MainActivity.java
index b0e56b4..142249c 100644
--- a/vlc-android/src/org/videolan/vlc/gui/MainActivity.java
+++ b/vlc-android/src/org/videolan/vlc/gui/MainActivity.java
@@ -51,7 +51,6 @@ import android.os.Bundle;
 import android.os.Handler;
 import android.preference.PreferenceManager;
 import android.support.v4.app.Fragment;
-import android.support.v4.app.FragmentManager;
 import android.support.v4.app.FragmentTransaction;
 import android.util.Log;
 import android.view.Display;
@@ -311,13 +310,11 @@ public class MainActivity extends SherlockFragmentActivity {
             MediaLibrary.getInstance(this).loadMediaItems(this);
     }
 
-
-
     @Override
     protected void onResumeFragments() {
         super.onResumeFragments();
 
-        /* Restore last view */
+        // Figure out if currently-loaded fragment is a top-level fragment.
         Fragment current = getSupportFragmentManager()
                 .findFragmentById(R.id.fragment_placeholder);
         boolean found = false;
@@ -331,13 +328,42 @@ public class MainActivity extends SherlockFragmentActivity {
         } else {
             found = true;
         }
-        /* Don't call replace() on a non-sidebar fragment, since replace() will
-         * remove() the currently displayed fragment and replace it with a
-         * blank screen.
+
+        mSidebarAdapter.lockSemaphore();
+        /**
+         * Let's see if Android recreated anything for us in the bundle.
+         * Prevent duplicate creation of fragments, since mSidebarAdapter might
+         * have been purged (losing state) when this activity was killed.
+         */
+        for(int i = 0; i < SidebarAdapter.entries.size(); i++) {
+            String fragmentTag = SidebarAdapter.entries.get(i).id;
+            Fragment fragment = getSupportFragmentManager().findFragmentByTag(fragmentTag);
+            if(fragment != null) {
+                Log.d(TAG, "Restoring automatically recreated fragment \"" + fragmentTag + "\"");
+                mSidebarAdapter.restoreFragment(fragmentTag, fragment);
+            }
+        }
+        mSidebarAdapter.unlockSemaphore();
+
+        /**
+         * Restore the last view.
+         *
+         * Replace:
+         * - null fragments (freshly opened Activity)
+         * - Wrong fragment open AND currently displayed fragment is a top-level fragment
+         *
+         * Do not replace:
+         * - Non-sidebar fragments.
+         * It will try to remove() the currently displayed fragment
+         * (i.e. tracks) and replace it with a blank screen. (stuck menu bug)
          */
-        if(found) {
+        if(current == null || (!current.getTag().equals(mCurrentFragment) && found)) {
+            Log.d(TAG, "Reloading displayed fragment");
+            Fragment ff = getFragment(mCurrentFragment);
             FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
-            ft.replace(R.id.fragment_placeholder, getFragment(mCurrentFragment));
+            if(current != null)
+                ft.detach(current);
+            ft.attach(ff);
             ft.commit();
         }
     }
diff --git a/vlc-android/src/org/videolan/vlc/gui/SidebarAdapter.java b/vlc-android/src/org/videolan/vlc/gui/SidebarAdapter.java
index b616f3f..05ed1f9 100644
--- a/vlc-android/src/org/videolan/vlc/gui/SidebarAdapter.java
+++ b/vlc-android/src/org/videolan/vlc/gui/SidebarAdapter.java
@@ -33,6 +33,7 @@ import org.videolan.vlc.gui.video.VideoGridFragment;
 
 import android.graphics.drawable.Drawable;
 import android.support.v4.app.Fragment;
+import android.util.Log;
 import android.view.LayoutInflater;
 import android.view.View;
 import android.view.ViewGroup;
@@ -176,4 +177,22 @@ public class SidebarAdapter extends BaseAdapter {
     public void unlockSemaphore() {
         mSemaphore.release();
     }
+
+    /**
+     * When Android has automatically recreated a fragment from the bundle state,
+     * use this function to 'restore' the recreated fragment into this sidebar
+     * adapter to prevent it from trying to create the same fragment again.
+     *
+     * @param id ID of the fragment
+     * @param f The fragment itself
+     */
+    public void restoreFragment(String id, Fragment f) {
+        if(f == null) {
+            Log.e(TAG, "Can't set null fragment for " + id + "!");
+            return;
+        }
+        mFragments.put(id, f);
+        mFragmentAdded.put(id, true);
+        // if Android added it, it's been implicitly added already...
+    }
 }



More information about the Android mailing list