[Android] Fix a very annoying IllegalStateException involving duplicate fragments
Edward Wang
git at videolan.org
Sun Mar 3 23:15:51 CET 2013
vlc-ports/android | branch: master | Edward Wang <edward.c.wang at compdigitec.com> | Sat Mar 2 15:02:35 2013 -0500| [c2bcced631856b61d6c3075726c9f7aa0f14cd3e] | committer: Edward Wang
Fix a very annoying IllegalStateException involving duplicate fragments
> http://git.videolan.org/gitweb.cgi/vlc-ports/android.git/?a=commit;h=c2bcced631856b61d6c3075726c9f7aa0f14cd3e
---
.../src/org/videolan/vlc/gui/MainActivity.java | 8 +++-
.../src/org/videolan/vlc/gui/SidebarAdapter.java | 42 ++++++++++++++++++++
2 files changed, 49 insertions(+), 1 deletion(-)
diff --git a/vlc-android/src/org/videolan/vlc/gui/MainActivity.java b/vlc-android/src/org/videolan/vlc/gui/MainActivity.java
index 29088ad..d018fb0 100644
--- a/vlc-android/src/org/videolan/vlc/gui/MainActivity.java
+++ b/vlc-android/src/org/videolan/vlc/gui/MainActivity.java
@@ -382,11 +382,17 @@ public class MainActivity extends SherlockFragmentActivity {
{
Fragment fragment = mSidebarAdapter.fetchFragment(id);
- if (!fragment.isAdded())
+ // Prevent fragment from being added twice. (IllegalStateException)
+ // See http://stackoverflow.com/questions/13745787/fragment-already-added-support-lib
+ mSidebarAdapter.lockSemaphore();
+ if(!mSidebarAdapter.isFragmentAdded(id)) {
getSupportFragmentManager()
.beginTransaction()
.add(R.id.fragment_placeholder, fragment, id)
.commitAllowingStateLoss();
+ mSidebarAdapter.setFragmentAdded(id);
+ }
+ mSidebarAdapter.unlockSemaphore();
/* Start the thumbnailer */
if (id.equals("video"))
diff --git a/vlc-android/src/org/videolan/vlc/gui/SidebarAdapter.java b/vlc-android/src/org/videolan/vlc/gui/SidebarAdapter.java
index cf901aa..b616f3f 100644
--- a/vlc-android/src/org/videolan/vlc/gui/SidebarAdapter.java
+++ b/vlc-android/src/org/videolan/vlc/gui/SidebarAdapter.java
@@ -23,6 +23,7 @@ package org.videolan.vlc.gui;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
+import java.util.concurrent.Semaphore;
import org.videolan.vlc.R;
import org.videolan.vlc.Util;
@@ -62,6 +63,8 @@ public class SidebarAdapter extends BaseAdapter {
private LayoutInflater mInflater;
static final List<SidebarEntry> entries;
private HashMap<String, Fragment> mFragments;
+ private HashMap<String, Boolean> mFragmentAdded;
+ private Semaphore mSemaphore;
static {
SidebarEntry entries2[] = {
@@ -78,6 +81,8 @@ public class SidebarAdapter extends BaseAdapter {
public SidebarAdapter() {
mInflater = LayoutInflater.from(VLCApplication.getAppContext());
mFragments = new HashMap<String, Fragment>(entries.size());
+ mFragmentAdded = new HashMap<String, Boolean>(entries.size());
+ mSemaphore = new Semaphore(1, true);
}
@Override
@@ -132,6 +137,43 @@ public class SidebarAdapter extends BaseAdapter {
}
f.setRetainInstance(true);
mFragments.put(id, f);
+ mFragmentAdded.put(id, false);
return f;
}
+
+ /**
+ * Has the fragment already been added?
+ * Note: lock must be held prior to entering this function!
+ *
+ * @return true if already added
+ */
+ public boolean isFragmentAdded(String id) {
+ return mFragmentAdded.get(id);
+ }
+
+ /**
+ * Flags the fragment as added.
+ *
+ * @param id ID of the fragment
+ */
+ public void setFragmentAdded(String id) {
+ mFragmentAdded.put(id, true);
+ }
+
+ /**
+ * Locks the semaphore before manipulating the added flag, since only one
+ * add operation is permitted.
+ *
+ * Remember to unlockSemaphore() when done.
+ */
+ public void lockSemaphore() {
+ mSemaphore.acquireUninterruptibly();
+ }
+
+ /**
+ * Release the semaphore when done.
+ */
+ public void unlockSemaphore() {
+ mSemaphore.release();
+ }
}
More information about the Android
mailing list