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

Android中HttpURLConnection触发NetworkOnMainThreadException原因咨询

为什么Android里会触发NetworkOnMainThreadException?

兄弟,这个异常其实是Android系统给咱们新手的一个「规范提醒」,咱们来一步步掰扯清楚:

异常产生的核心原因

Android的**主线程(UI线程)**是专门用来处理界面渲染、用户交互(比如点击按钮、滑动屏幕)的,它要求必须时刻保持响应速度——如果主线程被阻塞超过5秒,系统就会弹出「应用无响应(ANR)」的提示,这体验就太差了。

而网络请求是典型的耗时操作:你发请求到服务器,服务器处理、返回数据,期间可能因为网络差、服务器负载高等待好几秒。如果把网络请求直接放在onCreate这种主线程的方法里,主线程就会被彻底卡住,没法处理任何UI相关的操作。Android系统为了避免这种糟糕的用户体验,从API 11(Android 3.0)开始,就强制禁止在主线程中执行网络操作,一旦发现就抛出NetworkOnMainThreadException。

为啥IntelliJ里的代码能正常运行?

你在IntelliJ里写的是普通Java桌面程序,桌面程序的主线程没有Android这么严格的限制——就算主线程被网络请求卡住,顶多界面假死,但系统不会主动抛出异常阻止你。但Android是移动系统,对流畅性要求更高,所以有了这个强制规范。

怎么解决这个问题?

咱们需要把网络请求放到子线程里执行,等请求完成后再回到主线程更新UI。给你几个适合新手的方案:

方案1:用AsyncTask(快速改造你的现有代码)

AsyncTask是Android提供的轻量级异步任务工具,专门用来处理「后台耗时操作+主线程更新UI」的场景,直接改造你的MainActivity代码:

package android.adelsaadeddin.app3;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.os.AsyncTask;
import android.widget.TextView;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;

public class MainActivity extends AppCompatActivity {
    private TextView textView;

    @Override
    protected void onCreate (Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        textView = (TextView) findViewById(R.id.text);
        
        // 启动异步任务
        new NetworkTask().execute();
    }

    // 异步任务类:Params, Progress, Result
    private class NetworkTask extends AsyncTask<Void, Void, String> {

        @Override
        protected String doInBackground(Void... voids) {
            // 这里是子线程,执行网络请求
            HttpURLConnection urlConnection = null;
            try {
                URL url = new URL("http://codeforces.com/api/user.rating?handle=Adel_SaadEddin");
                urlConnection = (HttpURLConnection) url.openConnection();
                InputStream in = urlConnection.getInputStream();
                InputStreamReader isw = new InputStreamReader(in);
                StringBuilder stringBuilder = new StringBuilder();
                int data = isw.read();
                while (data != -1) {
                    char current = (char) data;
                    data = isw.read();
                    stringBuilder.append(current);
                }
                return stringBuilder.toString();
            } catch (Exception ex) {
                return "Error";
            } finally {
                if (urlConnection != null) {
                    urlConnection.disconnect();
                }
            }
        }

        @Override
        protected void onPostExecute(String result) {
            // 这里回到主线程,更新UI
            textView.setText(result);
        }
    }
}

方案2:用Kotlin协程(更现代的方式)

如果以后你开始用Kotlin开发,协程是更简洁的异步处理方式,代码会更清爽,不用写嵌套的任务类。

额外注意事项

你的代码里用了http://明文协议,在Android 9(API 28)及以上版本,默认是禁止明文网络请求的,会导致请求失败。解决办法有两个:

  • 把URL改成https://codeforces.com/api/user.rating?handle=Adel_SaadEddin(推荐,更安全)
  • 或者在AndroidManifest.xml的<application>标签里添加android:usesCleartextTraffic="true"

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 03:53:13