You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android断网显示AlertDialog异常:联网后对话框未消失排查

问题:网络恢复后AlertDialog无法关闭

我想要检测设备是否联网,未联网时显示AlertDialog。关闭网络时对话框正常弹出,但重新开启网络后,对话框仍持续显示,请问问题出在哪?

我的代码

network_class.java

public class network_class {
    public static boolean isConnectedToInternet(Context context){
        ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
        NetworkInfo activeNetwork = cm.getActiveNetworkInfo();
        if (activeNetwork != null) {
            if (activeNetwork.getType() == ConnectivityManager.TYPE_WIFI) {
                return true;
            }
            else if(activeNetwork.getType() == ConnectivityManager.TYPE_MOBILE) {
                return true;
            }
        }
        return false;
    }
}

network_detector.java

public class network_detector extends BroadcastReceiver {

    @Override
    public void onReceive(Context context, Intent intent) {
        View alertdialog_1 = LayoutInflater.from(context).inflate(R.layout.network_dialog,null);
        AlertDialog.Builder dialog_1 = new AlertDialog.Builder(context);
        dialog_1.setView(alertdialog_1);

        AlertDialog dialog = dialog_1.create();
        dialog.getWindow().setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));

        dialog.setCancelable(false);
        if(network_class.isConnectedToInternet(context)){
            if(dialog.isShowing())
                dialog.cancel();
        }
        else
            dialog.show();
    }
}

MainActivity中使用接收器

network_detector detector = new network_detector();
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    //some irrelevant code here
}

@Override
protected void onStart() {
    IntentFilter intentFilter = new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION);
    registerReceiver(detector,intentFilter);
    super.onStart();
}

@Override
protected void onStop() {
    unregisterReceiver(detector);
    super.onStop();
}

补充说明

已在Manifest中配置权限:

<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.INTERNET" />

问题原因及解决办法

核心问题

每次onReceive触发时,你都重新创建了一个新的AlertDialog实例。当网络恢复时,你判断的是当前新创建的dialog是否显示(此时它还没show,所以条件不成立),而之前弹出的那个旧dialog根本没被引用到,自然无法关闭。

解决步骤

  1. 把AlertDialog的实例提升为BroadcastReceiver的成员变量,避免每次都创建新对象:
public class network_detector extends BroadcastReceiver {
    private AlertDialog dialog; // 成员变量存储对话框实例

    @Override
    public void onReceive(Context context, Intent intent) {
        // 仅在dialog未创建时初始化
        if (dialog == null) {
            View alertdialog_1 = LayoutInflater.from(context).inflate(R.layout.network_dialog,null);
            AlertDialog.Builder dialog_1 = new AlertDialog.Builder(context);
            dialog_1.setView(alertdialog_1);
            dialog = dialog_1.create();
            dialog.getWindow().setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
            dialog.setCancelable(false);
        }

        if(network_class.isConnectedToInternet(context)){
            if(dialog != null && dialog.isShowing()){
                dialog.dismiss();
                dialog = null; // 可选:释放资源,下次需要时重新创建
            }
        } else {
            if(dialog != null && !dialog.isShowing()){
                dialog.show();
            }
        }
    }
}
  1. 额外注意事项
    • 由于BroadcastReceiver的生命周期很短,建议不要持有Dialog的强引用太久,在dismiss后可以置空避免内存泄漏。
    • 从Android 7.0(API 24)开始,CONNECTIVITY_ACTION广播不再发送给静态注册的接收器,但你这里是动态注册,所以不受影响。
    • 更高版本的Android推荐使用ConnectivityManager.NetworkCallback替代广播监听网络状态,广播方式在部分场景下会有延迟或不准确的问题。

内容的提问来源于stack exchange,提问作者user21917572

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.21 20:43:12