OSDN Git Service

Fix OOM when switching between camera and camcorder.
authorWu-cheng Li <wuchengli@google.com>
Tue, 3 Apr 2012 11:08:35 +0000 (19:08 +0800)
committerWu-cheng Li <wuchengli@google.com>
Tue, 3 Apr 2012 12:13:48 +0000 (20:13 +0800)
- Camera activities extend AbstractGalleryActivity. So
  onDestroy is moved from Gallery to AbstractGalleryActivity.
- Use WeakReference for values in the WeakHashMap of
  SpinnerVisibilitySetter.

bug:5954389
Change-Id: Ib15f269bd4c54a4621bdff58e7ea16b44f8fb3e3

src/com/android/gallery3d/app/AbstractGalleryActivity.java
src/com/android/gallery3d/app/Gallery.java
src/com/android/gallery3d/util/SpinnerVisibilitySetter.java

index 9a1d3d3..899e9bf 100644 (file)
@@ -181,6 +181,17 @@ public class AbstractGalleryActivity extends Activity implements GalleryActivity
     }
 
     @Override
+    protected void onDestroy() {
+        super.onDestroy();
+        mGLRootView.lockRenderThread();
+        try {
+            getStateManager().destroy();
+        } finally {
+            mGLRootView.unlockRenderThread();
+        }
+    }
+
+    @Override
     protected void onActivityResult(int requestCode, int resultCode, Intent data) {
         mGLRootView.lockRenderThread();
         try {
index e3937bc..60eb069 100644 (file)
@@ -245,18 +245,6 @@ public final class Gallery extends AbstractGalleryActivity implements OnCancelLi
     }
 
     @Override
-    public void onDestroy() {
-        super.onDestroy();
-        GLRoot root = getGLRoot();
-        root.lockRenderThread();
-        try {
-            getStateManager().destroy();
-        } finally {
-            root.unlockRenderThread();
-        }
-    }
-
-    @Override
     protected void onResume() {
         Utils.assertTrue(getStateManager().getStateCount() > 0);
         super.onResume();
index 6ccc264..1e0534e 100644 (file)
@@ -21,6 +21,7 @@ import android.os.Handler;
 import android.os.Message;
 import android.os.SystemClock;
 
+import java.lang.ref.WeakReference;
 import java.util.WeakHashMap;
 
 /**
@@ -47,25 +48,29 @@ public class SpinnerVisibilitySetter {
             new WeakHashMap<Activity, SpinnerVisibilitySetter>();
 
     private long mSpinnerVisibilityStartTime = -1;
-    private Activity mActivity;
+    private WeakReference<Activity> mActivityRef;
 
     private Handler mHandler = new Handler() {
         @Override
         public void handleMessage(Message msg) {
+            Activity activity = mActivityRef.get();
+
             switch(msg.what) {
                 case MSG_SHOW_SPINNER:
                     removeMessages(MSG_SHOW_SPINNER);
+                    if (activity == null) break;
                     if (mSpinnerVisibilityStartTime >= 0) break;
                     mSpinnerVisibilityStartTime = SystemClock.elapsedRealtime();
-                    mActivity.setProgressBarIndeterminateVisibility(true);
+                    activity.setProgressBarIndeterminateVisibility(true);
                     break;
                 case MSG_HIDE_SPINNER:
                     removeMessages(MSG_HIDE_SPINNER);
+                    if (activity == null) break;
                     if (mSpinnerVisibilityStartTime < 0) break;
                     long t = SystemClock.elapsedRealtime() - mSpinnerVisibilityStartTime;
                     if (t >= MIN_SPINNER_DISPLAY_TIME) {
                         mSpinnerVisibilityStartTime = -1;
-                        mActivity.setProgressBarIndeterminateVisibility(false);
+                        activity.setProgressBarIndeterminateVisibility(false);
                     } else {
                         sendEmptyMessageDelayed(MSG_HIDE_SPINNER, MIN_SPINNER_DISPLAY_TIME - t);
                     }
@@ -91,7 +96,8 @@ public class SpinnerVisibilitySetter {
     }
 
     private SpinnerVisibilitySetter(Activity activity) {
-        mActivity = activity;
+        // Activity are keys. Value objects should not strongly refer to keys.
+        mActivityRef = new WeakReference<Activity>(activity);
     }
 
     public void setSpinnerVisibility(boolean visible) {