核心概念
在开始之前,我们需要了解几个基本概念:

- HTTP/HTTPS 协议:Android 应用与服务器通信的基础,现在几乎所有的生产环境都使用 HTTPS,因为它通过 SSL/TLS 加密了数据,保证了数据传输的安全性。
- 请求方法:
GET:用于从服务器获取数据(查询)。POST:用于向服务器提交数据(创建、更新)。PUT/PATCH:用于更新服务器上的数据(较少用,通常用 POST 代替)。DELETE:用于删除服务器上的数据。
- 请求头:附加在请求上的信息,如
Content-Type(内容类型,application/json),Authorization(认证信息) 等。 - 请求体:POST 或 PUT 请求时发送给服务器的数据,通常是 JSON 格式。
- 响应:服务器返回的数据,包含状态码(如 200 成功, 404 未找到, 500 服务器错误)和响应体(通常是 JSON 数据)。
使用 HttpURLConnection (Java 原生)
这是 Android SDK 自带的方式,无需添加任何依赖,它功能强大,但 API 相对繁琐,适合简单的网络请求。
优点:
- 无需第三方库,减少应用体积。
- 是 Android 平台的标准 API。
缺点:
- API 较为底层,代码冗长。
- 处理 JSON 需要手动解析或引入额外的 JSON 库(如
org.json或 Gson)。 - 不支持异步操作,需要手动开启线程。
示例代码 (GET 请求)
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.util.Log;
import android.widget.TextView;
import androidx.appcompat.app.AppCompatActivity;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
public class MainActivity extends AppCompatActivity {
private static final String TAG = "NetworkDemo";
private TextView tvResult;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
tvResult = findViewById(R.id.tv_result);
// 网络请求不能在主线程(UI线程)进行,否则会抛出 NetworkOnMainThreadException
new Thread(new Runnable() {
@Override
public void run() {
try {
String response = performGetRequest("https://jsonplaceholder.typicode.com/posts/1");
// 更新UI必须在主线程
new Handler(Looper.getMainLooper()).post(new Runnable() {
@Override
public void run() {
tvResult.setText(response);
}
});
} catch (IOException e) {
e.printStackTrace();
}
}
}).start();
}
private String performGetRequest(String urlString) throws IOException {
URL url = new URL(urlString);
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod("GET");
connection.setConnectTimeout(5000); // 5秒连接超时
connection.setReadTimeout(10000); // 10秒读取超时
int responseCode = connection.getResponseCode();
Log.d(TAG, "Response Code: " + responseCode);
if (responseCode == HttpURLConnection.HTTP_OK) { // 200
InputStream inputStream = connection.getInputStream();
BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
StringBuilder response = new StringBuilder();
String line;
while ((line = reader.readLine()) != null) {
response.append(line);
}
reader.close();
inputStream.close();
return response.toString();
} else {
return "GET request failed. Response Code: " + responseCode;
}
}
}
使用 OkHttp (强烈推荐)
OkHttp 是目前 Android 开发中最流行的网络请求库,它高效、易用,并内置了对现代网络协议的支持。
优点:
- 高效:支持 HTTP/2,可以复用连接,减少延迟。
- 易用:提供简洁的 API,支持同步和异步请求。
- 强大:内置连接池、拦截器、GZIP 压缩等功能。
- 现代:是 Google 官方推荐的 Android 网络库。
缺点:
- 需要添加第三方依赖。
添加依赖
在 app/build.gradle 文件的 dependencies 代码块中添加:
// OkHttp
implementation("com.squareup.okhttp3:okhttp:4.12.0")
// 为了方便解析JSON,通常会搭配Gson或Moshi
implementation("com.google.code.gson:gson:2.10.1")
添加网络权限
在 app/src/main/AndroidManifest.xml 文件中添加:

<uses-permission android:name="android.permission.INTERNET" />
示例代码 (异步 GET 请求)
import android.os.Bundle;
import android.util.Log;
import android.widget.TextView;
import androidx.appcompat.app.AppCompatActivity;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import java.io.IOException;
import java.lang.reflect.Type;
import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
public class OkHttpActivity extends AppCompatActivity {
private static final String TAG = "OkHttpDemo";
private TextView tvResult;
private OkHttpClient client;
private Gson gson;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
tvResult = findViewById(R.id.tv_result);
client = new OkHttpClient();
gson = new Gson();
// 异步GET请求
performGetRequest();
}
private void performGetRequest() {
String url = "https://jsonplaceholder.typicode.com/posts/1";
Request request = new Request.Builder()
.url(url)
.build();
client.newCall(request).enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
// 请求失败,在主线程更新UI
runOnUiThread(() -> tvResult.setText("请求失败: " + e.getMessage()));
}
@Override
public void onResponse(Call call, Response response) throws IOException {
if (response.isSuccessful()) {
String responseBody = response.body().string();
Log.d(TAG, "Response: " + responseBody);
// 解析JSON
Post post = gson.fromJson(responseBody, Post.class);
// 在主线程更新UI
runOnUiThread(() -> tvResult.setText(
"Title: " + post.title + "\n" +
"Body: " + post.body
));
} else {
runOnUiThread(() -> tvResult.setText("请求失败: Code " + response.code()));
}
}
});
}
// 定义一个数据模型类来匹配JSON结构
static class Post {
int userId;
int id;
String title;
String body;
}
}
示例代码 (异步 POST 请求)
// 在OkHttpActivity中添加此方法
private void performPostRequest() {
String url = "https://jsonplaceholder.typicode.com/posts";
// 创建要发送的JSON数据
Post newPost = new Post();
newPost.userId = 1;
newPost.title = "新标题";
newPost.body = "这是新发布的内容。";
String jsonBody = gson.toJson(newPost);
RequestBody body = RequestBody.create(jsonBody, MediaType.get("application/json; charset=utf-8"));
Request request = new Request.Builder()
.url(url)
.post(body)
.build();
client.newCall(request).enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
runOnUiThread(() -> tvResult.setText("POST请求失败: " + e.getMessage()));
}
@Override
public void onResponse(Call call, Response response) throws IOException {
if (response.isSuccessful()) {
String responseBody = response.body().string();
Log.d(TAG, "POST Response: " + responseBody);
runOnUiThread(() -> tvResult.setText("POST成功,服务器响应: \n" + responseBody));
} else {
runOnUiThread(() -> tvResult.setText("POST请求失败: Code " + response.code()));
}
}
});
}
使用 Retrofit (更高级的选择)
Retrofit 是一个类型安全的 HTTP 客户端,由 Square 公司(OkHttp 的开发者)打造,它将 REST API 转换为 Java 接口,极大地简化了网络请求的编写。
优点:
- 类型安全:通过接口定义 API,编译时检查错误。
- 代码简洁:使用注解(如
@GET,@POST,@Path)来描述请求,代码可读性极高。 - 集成性好:默认使用 OkHttp 作为底层实现,可以无缝集成 Gson、Moshi 等库进行序列化和反序列化。
- 支持 RxJava, Coroutines:可以轻松与响应式编程和协程结合,实现更优雅的异步处理。
缺点:
- 学习曲线比 OkHttp 稍陡。
- 需要添加多个依赖。
添加依赖
在 app/build.gradle 文件中添加:
// Retrofit
implementation("com.squareup.retrofit2:retrofit:2.9.0")
// Retrofit with Gson Converter
implementation("com.squareup.retrofit2:converter-gson:2.9.0")
// Coroutines Support (可选,但强烈推荐)
implementation("com.squareup.retrofit2:retrofit-coroutines-adapter:0.9.2") // 或使用其他适配器
定义 API 接口
创建一个接口,用 Retrofit 的注解来描述 API。
import retrofit2.Call;
import retrofit2.http.Body;
import retrofit2.http.GET;
import retrofit2.http.POST;
import retrofit2.http.Path;
public interface ApiService {
// GET https://jsonplaceholder.typicode.com/posts/1
@GET("posts/{id}")
Call<Post> getPost(@Path("id") int id);
// POST https://jsonplaceholder.typicode.com/posts
@POST("posts")
Call<Post> createPost(@Body Post post);
}
创建 Retrofit 实例
import retrofit2.Retrofit;
import retrofit2.converter.gson.GsonConverterFactory;
public class RetrofitClient {
private static Retrofit retrofit = null;
private static final String BASE_URL = "https://jsonplaceholder.typicode.com/";
public static Retrofit getClient() {
if (retrofit == null) {
retrofit = new Retrofit.Builder()
.baseUrl(BASE_URL)
.addConverterFactory(GsonConverterFactory.create())
.build();
}
return retrofit;
}
}
示例代码 (使用 Retrofit)
import android.os.Bundle;
import android.widget.TextView;
import androidx.appcompat.app.AppCompatActivity;
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;
public class RetrofitActivity extends AppCompatActivity {
private TextView tvResult;
private ApiService apiService;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
tvResult = findViewById(R.id.tv_result);
// 1. 创建 ApiService 实例
apiService = RetrofitClient.getClient().create(ApiService.class);
// 2. 调用 API 方法
getPostById(1);
}
private void getPostById(int id) {
Call<Post> call = apiService.getPost(id);
call.enqueue(new Callback<Post>() {
@Override
public void onResponse(Call<Post> call, Response<Post> response) {
if (response.isSuccessful() && response.body() != null) {
Post post = response.body();
tvResult.setText(
"Title: " + post.title + "\n" +
"Body: " + post.body
);
} else {
tvResult.setText("请求失败: Code " + response.code());
}
}
@Override
public void onFailure(Call<Post> call, Throwable t) {
tvResult.setText("请求失败: " + t.getMessage());
}
});
}
// POST 请求调用示例
private void createNewPost() {
Post newPost = new Post();
newPost.userId = 1;
newPost.title = "Retrofit 新标题";
newPost.body = "这是使用 Retrofit 创建的内容。";
Call<Post> call = apiService.createPost(newPost);
call.enqueue(new Callback<Post>() {
@Override
public void onResponse(Call<Post> call, Response<Post> response) {
if (response.isSuccessful()) {
tvResult.setText("POST 成功: " + response.body().title);
}
}
@Override
public void onFailure(Call<Post> call, Throwable t) {
tvResult.setText("POST 失败: " + t.getMessage());
}
});
}
}
最佳实践与注意事项
-
禁止在主线程进行网络请求
(图片来源网络,侵删)- Android 4.0 (API level 11) 之后,禁止在主线程(UI 线程)执行网络操作,否则会抛出
NetworkOnMainThreadException异常。 - 解决方案:使用
AsyncTask(已废弃)、Thread+Handler、ExecutorService,或者更现代的 Kotlin Coroutines 和 RxJava。
- Android 4.0 (API level 11) 之后,禁止在主线程(UI 线程)执行网络操作,否则会抛出
-
处理网络状态
- 在发起请求前,最好检查设备是否连接了网络。
- 可以使用
ConnectivityManager和NetworkCapabilities来检查网络连接状态。
-
使用 HTTPS
现代应用必须使用 HTTPS 来保护数据安全,防止中间人攻击。
-
数据解析
- 推荐使用
Gson、Moshi或Jackson等 JSON 库来解析数据,而不是手动拼接字符串,Retrofit 和 OkHttp 都可以很方便地集成它们。
- 推荐使用
-
异常处理
网络请求可能因为各种原因失败(无网络、服务器宕机、超时等),务必做好异常处理,并向用户友好的提示。
-
生命周期管理
- 当 Activity 或 Fragment 在网络请求返回之前被销毁时,应取消对应的网络请求,以避免内存泄漏和无效的 UI 更新,Retrofit 的
Call对象提供了cancel()方法。
- 当 Activity 或 Fragment 在网络请求返回之前被销毁时,应取消对应的网络请求,以避免内存泄漏和无效的 UI 更新,Retrofit 的
总结与选择
| 特性 | HttpURLConnection |
OkHttp | Retrofit |
|---|---|---|---|
| 易用性 | 低 (代码繁琐) | 中 (API 简洁) | 高 (接口驱动) |
| 功能 | 基础 | 强大 (连接池,拦截器) | 非常强大 (类型安全,易扩展) |
| 依赖 | 无 | 1 个 | 2-3 个 |
| 适用场景 | 简单、轻量级项目;不想引入第三方库时 | 绝大多数 Android 项目的首选 | 大型、复杂的 RESTful API 项目;追求代码优雅和类型安全 |
推荐路线:
- 初学者或简单项目:可以直接使用
HttpURLConnection了解原理,但更推荐直接上手 OkHttp。 - 标准开发:直接使用 OkHttp + Gson 是一个非常健壮和流行的组合。
- 专业开发/大型项目:强烈推荐 Retrofit,它能让你写出更规范、更易于维护和测试的代码,是现代 Android 开发的行业标准。
