Quellcode durchsuchen

Framework leak prevention

Aidan Follestad vor 10 Jahren
Ursprung
Commit
5a30e76574

+ 30 - 0
library/src/main/java/com/afollestad/materialdialogs/DialogBase.java

@@ -3,8 +3,11 @@ package com.afollestad.materialdialogs;
 import android.app.Dialog;
 import android.content.Context;
 import android.content.DialogInterface;
+import android.os.Message;
 import android.view.View;
 
+import java.lang.reflect.Field;
+
 /**
  * @author Aidan Follestad (afollestad)
  */
@@ -34,4 +37,31 @@ class DialogBase extends Dialog implements DialogInterface.OnShowListener {
         if (mShowListener != null)
             mShowListener.onShow(dialog);
     }
+
+    @Override
+    protected void onStop() {
+        super.onStop();
+        // Prevent framework leak
+        try {
+            Class superCls = getClass().getSuperclass();
+            Field cancelMsg = superCls.getDeclaredField("mCancelMessage");
+            scrubMessageField(cancelMsg);
+            Field dismissMsg = superCls.getDeclaredField("mDismissMessage");
+            scrubMessageField(dismissMsg);
+            Field showMsg = superCls.getDeclaredField("mShowMessage");
+            scrubMessageField(showMsg);
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+    }
+
+    private void scrubMessageField(Field field) throws Exception {
+        field.setAccessible(true);
+        Object val = field.get(this);
+        if (val != null) {
+            Message msg = (Message) val;
+            msg.recycle();
+            field.set(this, null);
+        }
+    }
 }

+ 8 - 6
library/src/main/java/com/afollestad/materialdialogs/DialogInit.java

@@ -312,7 +312,14 @@ class DialogInit {
         // Setup internal show listener
         dialog.setOnShowListenerInternal();
 
-        // Setup user listeners
+        // Other internal initialization
+        dialog.invalidateList();
+        dialog.setViewInternal(dialog.view);
+        dialog.checkIfListInitScroll();
+    }
+
+    public static void resetListeners(MaterialDialog dialog) {
+        MaterialDialog.Builder builder = dialog.getBuilder();
         if (builder.showListener != null)
             dialog.setOnShowListener(builder.showListener);
         if (builder.cancelListener != null)
@@ -321,11 +328,6 @@ class DialogInit {
             dialog.setOnDismissListener(builder.dismissListener);
         if (builder.keyListener != null)
             dialog.setOnKeyListener(builder.keyListener);
-
-        // Other internal initialization
-        dialog.invalidateList();
-        dialog.setViewInternal(dialog.view);
-        dialog.checkIfListInitScroll();
     }
 
     private static void setupProgressDialog(final MaterialDialog dialog) {

+ 2 - 0
library/src/main/java/com/afollestad/materialdialogs/MaterialDialog.java

@@ -1379,6 +1379,8 @@ public class MaterialDialog extends DialogBase implements
             if (input.getText().length() > 0)
                 input.setSelection(input.getText().length());
         }
+        // Set listeners initially or in case they were scrubbed when the dialog was dismissed previously
+        DialogInit.resetListeners(this);
         super.onShow(dialog);
     }