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

检测网络连通性引发Android无响应(ANR)问题的解决办法

解决Android网络检测导致ANR的问题

问题根源

你的isConnectedToGoogle()方法在主线程中执行ping命令并调用ipProcess.waitFor(),这个方法会阻塞当前线程直到ping命令执行完成。当设备网络信号弱时,ping可能耗时超过5秒,触发Android的「Application Not Responding」(ANR)错误,也就是控制台提示的input dispatching time out。

解决方案

1. 给ping命令添加超时参数

直接修改ping命令,通过-W参数设置超时时间(单位:秒),限制阻塞时长。比如设置为2秒,超过则直接判定为无法连接:

public boolean isConnectedToGoogle() {
    Runtime runtime = Runtime.getRuntime();
    boolean reachGoogle = false;
    try {
        // -c 1: 发送1个ping包;-W 2: 超时2秒(注意是大写W)
        Process ipProcess = runtime.exec("/system/bin/ping -c 1 -W 2 8.8.8.8");
        int exitValue = ipProcess.waitFor();
        reachGoogle = exitValue == 0;
    } catch (IOException e) {
        reachGoogle = false;
    } catch (InterruptedException e) {
        reachGoogle = false;
        Thread.currentThread().interrupt(); // 恢复线程中断状态,避免后续逻辑异常
    }
    return reachGoogle;
}

2. 绝对不要在主线程执行网络检测

即使加了超时,主线程执行阻塞操作仍然存在风险。必须将网络检测逻辑放到后台线程执行,通过回调返回结果:

步骤1:定义回调接口

public interface NetworkCheckCallback {
    void onNetworkCheckResult(boolean isNetworkNull);
}

步骤2:修改CheckNetwork类,异步执行检测

public class CheckNetwork {
    // 原isConnectedToGoogle()方法(已加超时)
    public boolean isConnectedToGoogle() { /* ... */ }

    // 原isNetworkNull()方法
    public boolean isNetworkNull(Context context) { /* ... */ }

    // 新增异步检测方法
    public void checkNetworkAsync(Context context, NetworkCheckCallback callback) {
        // 用单线程线程池执行后台任务
        ExecutorService executor = Executors.newSingleThreadExecutor();
        executor.execute(() -> {
            boolean result = isNetworkNull(context);
            // 切换回主线程回调结果
            new Handler(Looper.getMainLooper()).post(() -> {
                callback.onNetworkCheckResult(result);
            });
            executor.shutdown();
        });
    }
}

步骤3:调用异步方法

CheckNetwork checkNetwork = new CheckNetwork();
checkNetwork.checkNetworkAsync(getApplicationContext(), isNetworkNull -> {
    if (isNetworkNull) {
        // 无网络逻辑
    } else {
        // 有网络逻辑
    }
});

3. 优先使用系统API检测网络连通性

Android从API 29(Android 10)开始提供了更可靠的网络验证API,无需自己实现ping,系统会自动验证网络是否能访问互联网:

public boolean isNetworkValid(Context context) {
    ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
    if (cm == null) return false;

    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
        Network activeNetwork = cm.getActiveNetwork();
        if (activeNetwork == null) return false;
        NetworkCapabilities capabilities = cm.getNetworkCapabilities(activeNetwork);
        // NET_CAPABILITY_VALIDATED表示系统已验证网络可访问互联网
        return capabilities != null 
                && capabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
                && capabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_VALIDATED);
    } else {
        // 适配旧版本:先检查网络连接,再异步执行ping
        NetworkInfo activeNetwork = cm.getActiveNetworkInfo();
        if (activeNetwork == null || !activeNetwork.isConnected()) return false;
        // 这里的isConnectedToGoogle()必须在后台线程调用
        return isConnectedToGoogle();
    }
}

关键注意事项

  • 任何阻塞性的网络操作(包括ping、HTTP请求)都不能在主线程执行,必须放到后台线程。
  • 优先使用系统提供的NetworkCapabilities.NET_CAPABILITY_VALIDATED,避免自己实现网络连通性检测,减少出错概率。
  • 如果必须使用ping,一定要添加超时参数,同时在后台线程执行。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.18 07:45:39