美文网首页
一个小技巧避免AlertDialog 窗体泄露

一个小技巧避免AlertDialog 窗体泄露

作者: 一航jason | 来源:发表于2023-11-16 14:36 被阅读0次

    一个小技巧避免AlertDialog 窗体泄露

    
    package acr.browser.lightning.utils;
    
    import android.content.Context;
    import android.util.Log;
    
    import androidx.activity.ComponentActivity;
    import androidx.annotation.NonNull;
    import androidx.appcompat.app.AlertDialog;
    import androidx.lifecycle.DefaultLifecycleObserver;
    import androidx.lifecycle.LifecycleOwner;
    
    import java.lang.ref.WeakReference;
    import java.util.ArrayList;
    import java.util.Iterator;
    import java.util.List;
    
    public class LeakAlertDialogBuilder extends AlertDialog.Builder implements DefaultLifecycleObserver {
    
        private static final String TAG = "my_alert_dialog_builder";
        private final List<WeakReference<AlertDialog>> weakReferenceList=new ArrayList<>();
    
        public LeakAlertDialogBuilder(@NonNull Context context) {
            super(context);
            init(context);
        }
    
        public LeakAlertDialogBuilder(@NonNull Context context, int themeResId) {
            super(context, themeResId);
            init(context);
        }
    
        private void init(Context context) {
            if (context instanceof ComponentActivity){
                ((ComponentActivity) context).getLifecycle().addObserver(this);
                Log.i(TAG, "init: register life cycle:"+context);
            }
        }
    
        @NonNull
        @Override
        public AlertDialog create() {
            AlertDialog alertDialog = super.create();
            weakReferenceList.add(new WeakReference<>(alertDialog));
            return alertDialog;
        }
    
        @Override
        public void onPause(@NonNull LifecycleOwner owner) {
            DefaultLifecycleObserver.super.onPause(owner);
            releaseAlertDialog();
        }
    
        private void releaseAlertDialog() {
            Iterator<WeakReference<AlertDialog>> iterator = weakReferenceList.iterator();
            while (iterator.hasNext()){
                WeakReference<AlertDialog> item = iterator.next();
                AlertDialog alertDialog = item.get();
                if (alertDialog!=null){
                    if (alertDialog.isShowing()){
                        alertDialog.cancel();
                        Log.i(TAG, "onPause: cancel dialog:"+alertDialog);
                    }
                }else {
                    item.clear();
                    iterator.remove();
                    Log.i(TAG, "onPause: clear item:"+item);
                }
            }
        }
    
    }
    
    

    还可以做个类似的类,可以只替换import就能够使用。

    
    
    package acr.browser.lightning.utils;
    
    import android.content.Context;
    
    import androidx.annotation.NonNull;
    import androidx.annotation.Nullable;
    
    public class AlertDialog extends androidx.appcompat.app.AlertDialog {
        protected AlertDialog(@NonNull Context context) {
            super(context);
        }
    
        protected AlertDialog(@NonNull Context context, int themeResId) {
            super(context, themeResId);
        }
    
        protected AlertDialog(@NonNull Context context, boolean cancelable, @Nullable OnCancelListener cancelListener) {
            super(context, cancelable, cancelListener);
        }
    
        public static class Builder extends LeakAlertDialogBuilder {
    
            public Builder(@NonNull Context context) {
                super(context);
            }
    
            public Builder(@NonNull Context context, int themeResId) {
                super(context, themeResId);
            }
        }
    }
    
    

    相关文章

      网友评论

          本文标题:一个小技巧避免AlertDialog 窗体泄露

          本文链接:https://www.haomeiwen.com/subject/xvoewdtx.html