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

Android使用HttpURLConnection报NetworkOnMainThreadException如何解决

错误原因

android.os.NetworkOnMainThreadException 是Android系统的强制限制:主线程负责所有UI渲染和用户交互响应,耗时的网络操作会阻塞主线程导致界面卡顿甚至ANR,因此系统直接禁止在主线程发起网络请求。

具体实现方案(基于java.util.concurrent官方推荐方案)

步骤1:声明全局线程管理工具

在CarSearch类的成员变量位置添加如下代码,用来管理子线程和切换主线程:

// 单线程线程池,专门处理网络请求
private final ExecutorService networkExecutor = Executors.newSingleThreadExecutor();
// 绑定主线程Looper的Handler,用来将UI操作切回主线程执行
private final Handler mainHandler = new Handler(Looper.getMainLooper());

步骤2:修改点击事件中的网络请求逻辑

将你原来try-catch包裹的网络请求代码,全部放到线程池的子线程中执行,涉及UI更新的操作(比如content.setText、弹Toast)要通过mainHandler切回主线程:

insert.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View view) {
        String vehiclenameTXT = name.getText().toString();
        String numberplateTXT = plate.getText().toString();
        String mileageTXT = mileage.getText().toString();

        Toast.makeText(CarSearch.this, "1", Toast.LENGTH_SHORT).show();

        Boolean checkinsertdata = DB.insertvehicledata(vehiclenameTXT, numberplateTXT, mileageTXT);
        if(checkinsertdata)
        {
            Toast.makeText(CarSearch.this, "New Vehicle Added", Toast.LENGTH_SHORT).show();
        }
        else
        {
            Toast.makeText(CarSearch.this, "Cannot add the same vehicle details twice!", Toast.LENGTH_SHORT).show();
        }

        Toast.makeText(CarSearch.this, "2", Toast.LENGTH_SHORT).show();
        // 把网络请求放到子线程执行
        networkExecutor.execute(() -> {
            StringBuilder htmlContent = new StringBuilder();
            try {
                String addr = "https://cartaxcheck.co.uk/free-car-check/?vrm=LN11VUM";
                URL url = new URL(addr);
                HttpURLConnection con = (HttpURLConnection) url.openConnection();
                BufferedReader in = new BufferedReader(new InputStreamReader(con.getInputStream()));
                String inputLine;
                while ((inputLine = in.readLine()) != null) {
                    htmlContent.append(inputLine);
                }
                in.close();
                // 切回主线程更新UI
                mainHandler.post(() -> {
                    content.setText(htmlContent.toString());
                    Toast.makeText(CarSearch.this, "3", Toast.LENGTH_SHORT).show();
                });
            } catch (MalformedURLException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }
        });
    }
});

步骤3:避免内存泄漏

在CarSearch的onDestroy生命周期方法中关闭线程池,释放资源:

@Override
protected void onDestroy() {
    super.onDestroy();
    // 页面销毁时关闭线程池,避免内存泄漏
    if (!networkExecutor.isShutdown()) {
        networkExecutor.shutdown();
    }
}

注意事项

  • 所有UI相关操作禁止在子线程执行,必须通过mainHandler.post投递到主线程
  • 如果后续需要发起多个并行网络请求,可以将Executors.newSingleThreadExecutor()替换为Executors.newCachedThreadPool()
  • 直接爬取第三方站点HTML需遵守对方的使用条款和robots协议,避免合规风险

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.29 15:57:03