Android中HttpUrlConnection无法连接服务器问题求助
首先,你的代码和配置存在几个关键问题,导致两种请求都无法正常发送到服务器,我们逐个拆解解决:
1. 主线程执行网络请求(核心问题)
Android从API Level 11开始就严格禁止在**主线程(UI线程)**中执行网络操作,你的getRequest方法直接在onCreate里调用,会触发NetworkOnMainThreadException——这个异常的getMessage()可能为空,这也是你HTTPS请求返回空异常信息的原因之一,而且系统会直接阻断网络请求,所以服务器根本收不到请求。
解决方法:必须把网络请求放到子线程中执行,比如用基础的Thread实现:
@Override protected void onCreate(android.os.Bundle savedInstanceState) { super.onCreate(savedInstanceState); this.setContentView(R.layout.activity_main); // 开启子线程执行网络请求 new Thread(new Runnable() { @Override public void run() { java.lang.String retHTTP = getRequest("http://httpaddress.example.com", "hello world!"); java.lang.String retHTTPS = getRequest("https://httpsaddress.example.com", "hello world!"); // 如果需要更新UI,必须切换回主线程 runOnUiThread(new Runnable() { @Override public void run() { // 在这里处理返回结果,比如显示到TextView } }); } }).start(); }
2. HTTPS分支判断逻辑错误
你的代码里判断HTTPS的条件是:
if (cweb.companion.MainActivity.url.startsWith("https")) {
但你的MainActivity里根本没有定义名为url的静态变量!你应该使用方法参数传入的Url(建议改成小写url更符合Java命名规范),而不是一个未定义的变量。这个错误会导致判断条件永远为false,HTTPS请求会走else分支的HTTP连接逻辑,从而引发异常。
修正后的判断逻辑:
// 改用方法参数传入的Url进行判断 if (Url.startsWith("https")) {
3. Manifest与Gradle的包名不一致
看你的配置:
- Manifest的
package是cweb.companion - Gradle的
defaultConfig里的applicationId是my.application.com
Android实际运行时使用的包名是applicationId,这会导致Manifest中的android:usesCleartextTraffic="true"配置不生效,所以HTTP请求仍然被拦截,提示"Cleartext HTTP traffic to localhost not permitted"。
解决方法:统一两者的包名,比如把Gradle里的applicationId改成cweb.companion,或者把Manifest的package改成my.application.com,确保两者完全一致。
4. 调试优化建议(可选)
- 后续可以把HTTP和HTTPS的公共逻辑(设置请求方法、写入Post内容、读取响应等)提取成单独方法,减少冗余代码;
- 处理网络流时建议用try-with-resources语法,自动关闭流避免资源泄漏:
try (OutputStreamWriter wr = new OutputStreamWriter(connection.getOutputStream())) { wr.write(PostContent); wr.flush(); }
- 在catch块里添加
e.printStackTrace(),打印完整异常堆栈,比只取getMessage()更能帮你定位问题。
按照以上步骤修改后,你的网络请求应该就能正常发送到服务器了。
内容的提问来源于stack exchange,提问作者SammuelMiranda

