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根本没被引用到,自然无法关闭。
解决步骤
- 把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(); } } } }
- 额外注意事项
- 由于BroadcastReceiver的生命周期很短,建议不要持有Dialog的强引用太久,在dismiss后可以置空避免内存泄漏。
- 从Android 7.0(API 24)开始,
CONNECTIVITY_ACTION广播不再发送给静态注册的接收器,但你这里是动态注册,所以不受影响。 - 更高版本的Android推荐使用
ConnectivityManager.NetworkCallback替代广播监听网络状态,广播方式在部分场景下会有延迟或不准确的问题。
内容的提问来源于stack exchange,提问作者user21917572
相关产品推荐
相关产品推荐

