1. 使用HttpURLConnection发起GET请求并解析响应
HttpURLConnection GET 请求的核心链路
在 Android 中发起一次 GET 请求,本质上是把「权限声明 → 后台线程 → 建立连接 → 读取响应 → 更新 UI」串成一条完整链路。HttpURLConnection 本身是同步阻塞 API,因此必须放在工作线程中执行,否则会触发 NetworkOnMainThreadException。
关键实现代码
下面是一个完整可运行的 GET 请求方法,包含权限检查、线程切换、响应码判断和响应体读取:
// AndroidManifest.xml 中声明
// <uses-permission android:name="android.permission.INTERNET" />
public class HttpGetTask {
private static final String TAG = "HttpGetTask";
/**
* 在后台线程发起 GET 请求,通过回调返回结果
*/
public static void doGet(final String urlStr, final Callback callback) {
new Thread(new Runnable() {
@Override
public void run() {
HttpURLConnection conn = null;
try {
URL url = new URL(urlStr);
conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("GET");
conn.setConnectTimeout(5000);
conn.setReadTimeout(5000);
int responseCode = conn.getResponseCode();
Log.d(TAG, "响应码: " + responseCode);
if (responseCode == HttpURLConnection.HTTP_OK) {
// 读取响应体
InputStream is = conn.getInputStream();
BufferedReader reader = new BufferedReader(
new InputStreamReader(is, "UTF-8"));
StringBuilder sb = new StringBuilder();
String line;
while ((line = reader.readLine()) != null) {
sb.append(line).append("\n");
}
reader.close();
is.close();
final String body = sb.toString().trim();
callback.onSuccess(responseCode, body);
} else {
callback.onError(responseCode, "HTTP " + responseCode);
}
} catch (IOException e) {
Log.e(TAG, "请求失败", e);
callback.onError(-1, e.getMessage());
} finally {
if (conn != null) {
conn.disconnect();
}
}
}
}).start();
}
public interface Callback {
void onSuccess(int code, String body);
void onError(int code, String message);
}
}
在 Activity 中调用并更新 UI
public class MainActivity extends AppCompatActivity {
private TextView tvResult;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
tvResult = findViewById(R.id.tv_result);
HttpGetTask.doGet("https://httpbin.org/get", new HttpGetTask.Callback() {
@Override
public void onSuccess(final int code, final String body) {
runOnUiThread(new Runnable() {
@Override
public void run() {
tvResult.setText("响应码: " + code + "\n\n" + body);
}
});
}
@Override
public void onError(final int code, final String message) {
runOnUiThread(new Runnable() {
@Override
public void run() {
tvResult.setText("请求失败: " + message);
}
});
}
});
}
}
验证要点:运行后观察 Logcat 中打印的响应码是否为 200;TextView 是否显示 httpbin.org 返回的 JSON 内容。若出现
NetworkOnMainThreadException,说明请求仍在主线程执行;若出现 SecurityException,说明未声明 INTERNET 权限。
常见坑:Android 9.0(API 28)及以上默认禁止明文 HTTP 请求。如果测试地址是
http:// 开头,需要在 AndroidManifest.xml 的 <application> 标签中添加 android:usesCleartextTraffic="true",或改用 HTTPS 地址。
响应码与处理策略对照
| 响应码 | 含义 | 处理方式 |
|---|---|---|
| 200 | 请求成功 | 读取 InputStream,解析响应体 |
| 301 / 302 | 重定向 | HttpURLConnection 默认自动跟随,无需手动处理 |
| 400 | 请求参数错误 | 检查 URL 与请求头,提示用户 |
| 401 / 403 | 未授权 / 禁止访问 | 检查 Token 或权限配置 |
| 404 | 资源不存在 | 确认接口路径是否正确 |
| 500 | 服务端内部错误 | 提示用户稍后重试,记录日志 |