一个小技巧避免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);
}
}
}