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

Android中规避StrictMode检查网络连接状态的方法

解决方案

你的问题根源是在主线程执行了耗时的网络请求,Android从API 11开始就禁止主线程处理网络操作,StrictMode只是临时绕过的违规手段,正确的做法是把网络操作移到后台线程,同时保证多类调用的便利性,下面是具体改造方案:

1. 替换过时的网络状态判断API

原代码里的NetworkInfo已被标记为过时,改用ConnectivityManager.NetworkCapabilities来判断网络连通性:

private static boolean isNetworkAvailable(Context context) {
    ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
    if (cm == null) return false;

    Network network = cm.getActiveNetwork();
    if (network == null) return false;

    NetworkCapabilities capabilities = cm.getNetworkCapabilities(network);
    return capabilities != null && (capabilities.hasTransport(NetworkCapabilities.TRANSPORT_WIFI) 
            || capabilities.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR)
            || capabilities.hasTransport(NetworkCapabilities.TRANSPORT_ETHERNET));
}

2. 将同步网络请求改为异步执行

网络请求属于耗时操作,不能在主线程同步返回结果,我们通过回调接口返回结果,同时用ExecutorService管理后台线程,封装成可复用的工具类:

第一步:定义回调接口

public interface ConnectionCheckCallback {
    void onConnectionChecked(boolean isConnected);
}

第二步:改造为异步工具类

public class NetworkUtils {
    // 单例线程池,复用线程避免频繁创建销毁
    private static final ExecutorService EXECUTOR = Executors.newSingleThreadExecutor();

    public static void checkConnectionAsync(Context context, ConnectionCheckCallback callback) {
        EXECUTOR.execute(() -> {
            boolean isConnected = false;
            try {
                if (isNetworkAvailable(context)) {
                    String checkUrl = databaseManagement.getSettingValue("urlCheckConnection", context);
                    URL url = new URL(checkUrl);
                    HttpURLConnection httpURLConnection = (HttpURLConnection) url.openConnection();
                    httpURLConnection.setConnectTimeout(3000);
                    httpURLConnection.setReadTimeout(3000);
                    // getResponseCode会自动触发连接,无需显式调用connect()
                    isConnected = httpURLConnection.getResponseCode() == HttpURLConnection.HTTP_OK;
                    
                    // 用try-with-resources自动关闭输入流,避免资源泄漏
                    try (InputStream ignored = httpURLConnection.getInputStream()) {
                        // 仅需关闭资源,无需读取内容
                    }
                    httpURLConnection.disconnect();
                }
            } catch (Exception e) {
                isConnected = false;
                wil.WriteFile("checkConnection - Exception: " + e.getMessage(), context);
            } finally {
                // 切回主线程回调结果,避免后台线程操作UI
                new Handler(Looper.getMainLooper()).post(() -> callback.onConnectionChecked(isConnected));
            }
        });
    }

    // 上面的isNetworkAvailable方法放在这里
    private static boolean isNetworkAvailable(Context context) {
        ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
        if (cm == null) return false;

        Network network = cm.getActiveNetwork();
        if (network == null) return false;

        NetworkCapabilities capabilities = cm.getNetworkCapabilities(network);
        return capabilities != null && (capabilities.hasTransport(NetworkCapabilities.TRANSPORT_WIFI) 
                || capabilities.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR)
                || capabilities.hasTransport(NetworkCapabilities.TRANSPORT_ETHERNET));
    }
}

3. 多类调用方式

任何需要检查网络的类,只需调用异步方法并传入回调:

NetworkUtils.checkConnectionAsync(context, new ConnectionCheckCallback() {
    @Override
    public void onConnectionChecked(boolean isConnected) {
        // 在这里处理检查结果,比如更新UI或执行业务逻辑
        if (isConnected) {
            // 网络可用,执行对应操作
        } else {
            // 网络不可用,提示用户或做降级处理
        }
    }
});

额外优化点

  • 避免重复请求:可在工具类中添加请求锁,同一时间只发起一次网络请求,结果复用给所有调用者
  • 权限声明:确保在AndroidManifest.xml中添加必要权限:
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    <uses-permission android:name="android.permission.INTERNET" />
    

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.03 10:40:36