logo

Android网络通信实战:如何高效调用JSON接口并测试

作者:搬砖的石头2025.09.25 17:12浏览量:0

简介:本文详细讲解Android应用中调用JSON接口的核心步骤,包括网络权限配置、HTTP请求实现、JSON解析方法及接口测试策略,提供可复用的代码示例和最佳实践。

一、环境准备与基础配置

1. 网络权限声明

在AndroidManifest.xml中添加必要权限:

  1. <uses-permission android:name="android.permission.INTERNET" />
  2. <!-- 若使用HTTPS且需要自签名证书,需添加 -->
  3. <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />

对于Android 9.0(API 28)及以上版本,默认禁止明文HTTP请求,需在res/xml/network_security_config.xml中配置:

  1. <network-security-config>
  2. <base-config cleartextTrafficPermitted="true">
  3. <trust-anchors>
  4. <certificates src="system" />
  5. </trust-anchors>
  6. </base-config>
  7. </network-security-config>

并在AndroidManifest.xml中引用:

  1. <application
  2. android:networkSecurityConfig="@xml/network_security_config"
  3. ...>
  4. </application>

2. 依赖管理

推荐使用OkHttp + Retrofit组合实现网络请求:

  1. // build.gradle (Module)
  2. dependencies {
  3. implementation 'com.squareup.okhttp3:okhttp:4.10.0'
  4. implementation 'com.squareup.retrofit2:retrofit:2.9.0'
  5. implementation 'com.squareup.retrofit2:converter-gson:2.9.0'
  6. }

二、JSON接口调用实现

1. 基础HTTP请求实现

使用OkHttp实现GET请求:

  1. public class JsonApiClient {
  2. private static final String BASE_URL = "https://api.example.com/";
  3. public void fetchData(String endpoint, Callback callback) {
  4. OkHttpClient client = new OkHttpClient();
  5. Request request = new Request.Builder()
  6. .url(BASE_URL + endpoint)
  7. .build();
  8. client.newCall(request).enqueue(new Callback() {
  9. @Override
  10. public void onFailure(Call call, IOException e) {
  11. callback.onError(e.getMessage());
  12. }
  13. @Override
  14. public void onResponse(Call call, Response response) throws IOException {
  15. if (response.isSuccessful()) {
  16. String jsonData = response.body().string();
  17. callback.onSuccess(jsonData);
  18. } else {
  19. callback.onError("Server error: " + response.code());
  20. }
  21. }
  22. });
  23. }
  24. public interface Callback {
  25. void onSuccess(String jsonData);
  26. void onError(String errorMessage);
  27. }
  28. }

POST请求实现(带请求体):

  1. public void postData(String endpoint, String jsonBody, Callback callback) {
  2. MediaType JSON = MediaType.parse("application/json; charset=utf-8");
  3. RequestBody body = RequestBody.create(jsonBody, JSON);
  4. Request request = new Request.Builder()
  5. .url(BASE_URL + endpoint)
  6. .post(body)
  7. .build();
  8. // 其余部分与GET请求相同
  9. }

2. Retrofit高级实现

定义API接口:

  1. public interface ApiService {
  2. @GET("users/{id}")
  3. Call<User> getUser(@Path("id") int userId);
  4. @POST("users")
  5. Call<User> createUser(@Body User user);
  6. @FormUrlEncoded
  7. @POST("users/login")
  8. Call<LoginResponse> login(
  9. @Field("email") String email,
  10. @Field("password") String password
  11. );
  12. }

创建Retrofit实例:

  1. public class RetrofitClient {
  2. private static Retrofit retrofit = null;
  3. private static final String BASE_URL = "https://api.example.com/";
  4. public static Retrofit getClient() {
  5. if (retrofit == null) {
  6. retrofit = new Retrofit.Builder()
  7. .baseUrl(BASE_URL)
  8. .addConverterFactory(GsonConverterFactory.create())
  9. .client(new OkHttpClient.Builder().build())
  10. .build();
  11. }
  12. return retrofit;
  13. }
  14. }

数据模型定义:

  1. public class User {
  2. @SerializedName("id")
  3. private int id;
  4. @SerializedName("name")
  5. private String name;
  6. @SerializedName("email")
  7. private String email;
  8. // 必须有无参构造函数
  9. public User() {}
  10. // Getter和Setter方法
  11. // ...
  12. }

三、JSON数据解析策略

1. 原生JSONObject解析

  1. try {
  2. JSONObject jsonObject = new JSONObject(jsonString);
  3. int id = jsonObject.getInt("id");
  4. String name = jsonObject.getString("name");
  5. JSONArray hobbiesArray = jsonObject.getJSONArray("hobbies");
  6. List<String> hobbies = new ArrayList<>();
  7. for (int i = 0; i < hobbiesArray.length(); i++) {
  8. hobbies.add(hobbiesArray.getString(i));
  9. }
  10. } catch (JSONException e) {
  11. e.printStackTrace();
  12. }

2. Gson库高级解析

基本对象解析:

  1. Gson gson = new Gson();
  2. User user = gson.fromJson(jsonString, User.class);

集合解析:

  1. Type listType = new TypeToken<ArrayList<User>>(){}.getType();
  2. List<User> users = gson.fromJson(jsonArrayString, listType);

复杂嵌套结构解析:

  1. public class ApiResponse<T> {
  2. @SerializedName("status")
  3. private String status;
  4. @SerializedName("code")
  5. private int code;
  6. @SerializedName("data")
  7. private T data;
  8. // Getter和Setter方法
  9. }
  10. // 使用示例
  11. ApiResponse<User> response = gson.fromJson(jsonString,
  12. new TypeToken<ApiResponse<User>>(){}.getType());

四、接口测试与调试

1. 单元测试实现

使用JUnit和Mockito测试:

  1. @RunWith(MockitoJUnitRunner.class)
  2. public class ApiServiceTest {
  3. @Mock
  4. private Retrofit retrofit;
  5. @Mock
  6. private ApiService apiService;
  7. @Mock
  8. private Call<User> call;
  9. @Test
  10. public void testGetUserSuccess() throws Exception {
  11. User testUser = new User(1, "Test User", "test@example.com");
  12. Response<User> response = Response.success(testUser);
  13. when(retrofit.create(ApiService.class)).thenReturn(apiService);
  14. when(apiService.getUser(1)).thenReturn(call);
  15. when(call.execute()).thenReturn(response);
  16. User result = apiService.getUser(1).execute().body();
  17. assertEquals("Test User", result.getName());
  18. }
  19. }

2. 集成测试策略

使用Postman生成测试代码:

  1. 在Postman中配置请求
  2. 点击”Code”按钮选择”Java - OkHttp”
  3. 将生成的代码转换为Android可用的形式

本地Mock服务器测试:

  1. public class MockWebServerTest {
  2. private MockWebServer server;
  3. @Before
  4. public void setUp() throws Exception {
  5. server = new MockWebServer();
  6. server.start(8080);
  7. }
  8. @Test
  9. public void testMockResponse() throws Exception {
  10. String mockJson = "{\"id\":1,\"name\":\"Mock User\"}";
  11. server.enqueue(new MockResponse()
  12. .setResponseCode(200)
  13. .setBody(mockJson));
  14. Retrofit retrofit = new Retrofit.Builder()
  15. .baseUrl(server.url("/"))
  16. .addConverterFactory(GsonConverterFactory.create())
  17. .build();
  18. ApiService service = retrofit.create(ApiService.class);
  19. User user = service.getUser(1).execute().body();
  20. assertEquals("Mock User", user.getName());
  21. }
  22. @After
  23. public void tearDown() throws Exception {
  24. server.shutdown();
  25. }
  26. }

3. 常见问题调试

网络请求失败排查:

  1. 检查网络权限是否正确配置
  2. 验证URL是否完整(包括协议头)
  3. 使用OkHttp的拦截器记录请求日志
    ```java
    HttpLoggingInterceptor logging = new HttpLoggingInterceptor();
    logging.setLevel(HttpLoggingInterceptor.Level.BODY);

OkHttpClient client = new OkHttpClient.Builder()
.addInterceptor(logging)
.build();

  1. ### JSON解析错误处理:
  2. ```java
  3. try {
  4. User user = gson.fromJson(jsonString, User.class);
  5. } catch (JsonSyntaxException e) {
  6. Log.e("JSON_PARSE", "Invalid JSON format: " + e.getMessage());
  7. // 具体字段解析错误处理
  8. if (e.getMessage().contains("name")) {
  9. // 处理name字段缺失的情况
  10. }
  11. }

五、最佳实践与性能优化

1. 连接池管理

  1. // 创建OkHttpClient时配置连接池
  2. OkHttpClient client = new OkHttpClient.Builder()
  3. .connectionPool(new ConnectionPool(5, 5, TimeUnit.MINUTES))
  4. .build();

2. 缓存策略实现

  1. int cacheSize = 10 * 1024 * 1024; // 10MB
  2. Cache cache = new Cache(context.getCacheDir(), cacheSize);
  3. OkHttpClient client = new OkHttpClient.Builder()
  4. .cache(cache)
  5. .addInterceptor(new CacheInterceptor())
  6. .build();
  7. // 自定义缓存拦截器
  8. public class CacheInterceptor implements Interceptor {
  9. @Override
  10. public Response intercept(Chain chain) throws IOException {
  11. Request request = chain.request();
  12. Response response = chain.proceed(request);
  13. // 自定义缓存控制逻辑
  14. return response.newBuilder()
  15. .removeHeader("Pragma")
  16. .header("Cache-Control", "public, max-age=60")
  17. .build();
  18. }
  19. }

3. 异步处理优化

使用RxJava实现响应式编程:

  1. public interface RxApiService {
  2. @GET("users/{id}")
  3. Single<User> getUser(@Path("id") int userId);
  4. }
  5. // 使用示例
  6. RxApiService service = RetrofitClient.getClient().create(RxApiService.class);
  7. service.getUser(1)
  8. .subscribeOn(Schedulers.io())
  9. .observeOn(AndroidSchedulers.mainThread())
  10. .subscribe(
  11. user -> updateUI(user),
  12. throwable -> showError(throwable.getMessage())
  13. );

4. 错误处理机制

定义统一的错误响应模型:

  1. public class ApiError {
  2. @SerializedName("code")
  3. private int code;
  4. @SerializedName("message")
  5. private String message;
  6. // Getter方法
  7. public int getCode() { return code; }
  8. public String getMessage() { return message; }
  9. }
  10. // 自定义Gson异常解析
  11. public class ApiErrorHandler implements Response<Object> {
  12. @Override
  13. public boolean isSuccessful() {
  14. return false;
  15. }
  16. @Override
  17. public Object body() {
  18. return null;
  19. }
  20. public ApiError getError(Response<Object> response) {
  21. try {
  22. String errorBody = response.errorBody().string();
  23. return new Gson().fromJson(errorBody, ApiError.class);
  24. } catch (IOException e) {
  25. return new ApiError(500, "Unknown error");
  26. }
  27. }
  28. }

六、安全考虑

1. HTTPS安全配置

证书固定(Certificate Pinning):

  1. public class CertificatePinnerInterceptor implements Interceptor {
  2. private static final String CERT_PIN = "sha256/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=";
  3. @Override
  4. public Response intercept(Chain chain) throws IOException {
  5. CertificatePinner pinner = new CertificatePinner.Builder()
  6. .add("example.com", CERT_PIN)
  7. .build();
  8. return chain.proceed(
  9. chain.request()
  10. .newBuilder()
  11. .build()
  12. )
  13. .newBuilder()
  14. .certificatePinner(pinner)
  15. .build();
  16. }
  17. }
  18. // 使用方式
  19. OkHttpClient client = new OkHttpClient.Builder()
  20. .addInterceptor(new CertificatePinnerInterceptor())
  21. .build();

2. 敏感数据保护

请求头安全配置:

  1. public class AuthInterceptor implements Interceptor {
  2. @Override
  3. public Response intercept(Chain chain) throws IOException {
  4. Request original = chain.request();
  5. Request request = original.newBuilder()
  6. .header("Authorization", "Bearer " + getAuthToken())
  7. .header("Content-Type", "application/json")
  8. .method(original.method(), original.body())
  9. .build();
  10. return chain.proceed(request);
  11. }
  12. private String getAuthToken() {
  13. // 从安全存储中获取token
  14. return SharedPrefsHelper.getAuthToken();
  15. }
  16. }

七、完整示例实现

1. 基础GET请求实现

  1. public class UserRepository {
  2. private ApiService apiService;
  3. public UserRepository() {
  4. Retrofit retrofit = new Retrofit.Builder()
  5. .baseUrl("https://api.example.com/")
  6. .addConverterFactory(GsonConverterFactory.create())
  7. .client(new OkHttpClient.Builder().build())
  8. .build();
  9. apiService = retrofit.create(ApiService.class);
  10. }
  11. public void getUser(int userId, final UserCallback callback) {
  12. apiService.getUser(userId).enqueue(new Callback<User>() {
  13. @Override
  14. public void onResponse(Call<User> call, Response<User> response) {
  15. if (response.isSuccessful()) {
  16. callback.onSuccess(response.body());
  17. } else {
  18. ApiError error = parseError(response);
  19. callback.onFailure(error.getMessage());
  20. }
  21. }
  22. @Override
  23. public void onFailure(Call<User> call, Throwable t) {
  24. callback.onFailure("Network error: " + t.getMessage());
  25. }
  26. });
  27. }
  28. private ApiError parseError(Response<?> response) {
  29. try {
  30. String errorBody = response.errorBody().string();
  31. return new Gson().fromJson(errorBody, ApiError.class);
  32. } catch (IOException e) {
  33. return new ApiError(response.code(), "Unknown error");
  34. }
  35. }
  36. public interface UserCallback {
  37. void onSuccess(User user);
  38. void onFailure(String errorMessage);
  39. }
  40. }

2. 在Activity中使用

  1. public class UserActivity extends AppCompatActivity {
  2. private UserRepository userRepository;
  3. private TextView userNameTextView;
  4. @Override
  5. protected void onCreate(Bundle savedInstanceState) {
  6. super.onCreate(savedInstanceState);
  7. setContentView(R.layout.activity_user);
  8. userNameTextView = findViewById(R.id.user_name);
  9. userRepository = new UserRepository();
  10. loadUserData(1); // 加载ID为1的用户数据
  11. }
  12. private void loadUserData(int userId) {
  13. userRepository.getUser(userId, new UserRepository.UserCallback() {
  14. @Override
  15. public void onSuccess(User user) {
  16. userNameTextView.setText(user.getName());
  17. }
  18. @Override
  19. public void onFailure(String errorMessage) {
  20. Toast.makeText(UserActivity.this,
  21. "Error: " + errorMessage,
  22. Toast.LENGTH_SHORT).show();
  23. }
  24. });
  25. }
  26. }

八、总结与扩展

1. 关键点总结

  1. 权限配置:确保INTERNET权限和网络安全配置正确
  2. 网络库选择:OkHttp+Retrofit组合提供最佳开发体验
  3. JSON解析:Gson库处理复杂数据结构高效可靠
  4. 错误处理:实现统一的错误响应模型
  5. 性能优化:连接池、缓存和异步处理提升性能
  6. 安全防护:HTTPS和证书固定保障通信安全

2. 进阶方向

  1. 集成GraphQL客户端实现灵活数据查询
  2. 使用WebSocket实现实时数据通信
  3. 实现分页加载和增量更新机制
  4. 开发网络状态监控和自动重试机制
  5. 集成ProGuard进行代码混淆和API保护

通过系统掌握上述技术要点,开发者可以构建出稳定、高效且安全的Android网络通信模块,为应用提供可靠的数据交互能力。实际开发中应根据项目需求选择合适的技术组合,并持续关注网络库和安全协议的更新版本。

相关文章推荐

发表评论