上一篇
安卓处理服务器json数据包
- 行业动态
- 2025-04-22
- 4864
网络请求与JSON数据获取
在安卓中处理服务器返回的JSON数据,首先需要通过网络请求获取数据,常用方式包括:
- OkHttp:轻量级HTTP客户端
- Retrofit:基于OkHttp的RESTful API封装库
- Volley:谷歌推出的网络请求库
示例代码(OkHttp):
OkHttpClient client = new OkHttpClient(); Request request = new Request.Builder() .url("https://api.example.com/data") .build(); client.newCall(request).enqueue(new Callback() { @Override public void onFailure(Call call, IOException e) { // 处理网络错误 } @Override public void onResponse(Call call, Response response) throws IOException { if (response.isSuccessful()) { String jsonData = response.body().string(); // 解析JSON数据 } } });
JSON解析方式对比
解析方式 | 适用场景 | 特点 |
---|---|---|
JSONObject | 简单键值对结构 | 原生API,无需额外依赖,适合动态结构 |
Gson | 复杂对象映射 | 支持泛型、注解,性能优秀,需添加依赖(com.google.code.gson) |
Moshi | 高性能需求 | 现代JSON解析库,支持Kotlin,扩展性强 |
FastJSON | 阿里系项目 | 国内生态支持好,但体积较大 |
Gson示例代码:
Gson gson = new Gson(); // 假设JSON返回:{"name":"张三","age":25} String json = "{"name":"张三","age":25}"; Person person = gson.fromJson(json, Person.class); // 定义数据类 public class Person { private String name; private int age; // getter/setter省略 }
异步处理与主线程安全
网络请求和JSON解析必须在子线程执行,更新UI需切换到主线程:
- 传统方式:
AsyncTask
(已过时) - 现代方式:
LiveData
、ViewModel
、Coroutine
Coroutine示例:
// 在ViewModel中 viewModelScope.launch { try { val response = withContext(Dispatchers.IO) { // 执行网络请求和JSON解析 } // 更新UI(自动切换到主线程) } catch (e: Exception) { // 处理异常 } }
常见问题与解决方案
问题描述 | 解决方案 |
---|---|
JSON解析失败 | 检查字段名大小写 使用 @SerializedName 注解映射不同命名规则 |
网络请求跨域问题 | 服务器端设置CORS头(Access-Control-Allow-Origin) |
数据量大导致OOM | 分页加载 使用 JsonReader 流式解析(Gson) |
SSL证书验证失败 | 配置证书信任白名单 调试时临时禁用SSL验证(不推荐生产环境使用) |
完整流程示例(Retrofit+Gson)
添加依赖:
implementation 'com.squareup.retrofit2:retrofit:2.9.0' implementation 'com.squareup.retrofit2:converter-gson:2.9.0'
定义接口:
public interface ApiService { @GET("users/{id}") Call<User> getUser(@Path("id") int id); }
创建Retrofit实例:
Retrofit retrofit = new Retrofit.Builder() .baseUrl("https://api.example.com/") .addConverterFactory(GsonConverterFactory.create()) .build();
ApiService apiService = retrofit.create(ApiService.class);
4. 发起请求:
```java
Call<User> call = apiService.getUser(123);
call.enqueue(new Callback<User>() {
@Override
public void onResponse(Call<User> call, Response<User> response) {
if (response.isSuccessful()) {
User user = response.body();
// 使用user对象
}
}
@Override
public void onFailure(Call<User> call, Throwable t) {
// 处理失败
}
});
相关问题与解答
问题1:如何缓存JSON数据到本地?
解答:
- 短期缓存:使用
SharedPreferences
存储简单JSON字符串 - 长期缓存:
- 将JSON转换为对象后存入Room数据库
- 使用
File
保存原始JSON文件(需处理序列化)
- 带过期机制:结合
Cache-Control
头或自定义时间戳字段
问题2:如何处理嵌套JSON结构?
解答:
- 对象嵌套:定义嵌套数据类
public class Order { private User user; private List<Item> items; // getter/setter }
- 数组嵌套:使用
List
或TypeToken
处理泛型Type listType = new TypeToken<List<Item>>() {}.getType(); List<Item> items = gson.fromJson(jsonArray, listType);
- 动态结构:使用
Map<String, Object>
接收未知