Android开发中处理JSON数据时,JsonReader是原生提供的流式解析工具,相比一次性加载整个JSON对象的解析方式,它能有效降低内存占用,特别适合处理大体积JSON数据。本文将详细介绍JsonReader的使用方法。

JsonReader基本使用流程
使用JsonReader解析JSON通常需要以下步骤:首先获取JSON数据的输入流,然后创建JsonReader实例,接着根据JSON的结构逐层遍历读取数据,最后关闭资源。下面是基础的解析示例,假设我们有一个简单的JSON数据:
{
"name": "测试应用",
"version": 1.0,
"is_debug": true,
"tags": ["tools", "demo"]
}创建JsonReader实例
首先需要准备JSON数据的输入流,然后通过JsonReader构造函数创建实例,代码如下:
import android.util.JsonReader;
import java.io.IOException;
import java.io.StringReader;
public class JsonParseDemo {
public void parseJson() {
String jsonStr = "{\"name\":\"测试应用\",\"version\":1.0,\"is_debug\":true,\"tags\":[\"tools\",\"demo\"]}";
// 创建JsonReader实例,传入StringReader作为数据源
JsonReader reader = new JsonReader(new StringReader(jsonStr));
try {
// 开始解析流程
reader.beginObject();
while (reader.hasNext()) {
String fieldName = reader.nextName();
switch (fieldName) {
case "name":
String name = reader.nextString();
System.out.println("name: " + name);
break;
case "version":
double version = reader.nextDouble();
System.out.println("version: " + version);
break;
case "is_debug":
boolean isDebug = reader.nextBoolean();
System.out.println("is_debug: " + isDebug);
break;
case "tags":
// 处理数组类型字段
reader.beginArray();
while (reader.hasNext()) {
String tag = reader.nextString();
System.out.println("tag: " + tag);
}
reader.endArray();
break;
default:
// 忽略未知字段
reader.skipValue();
break;
}
}
reader.endObject();
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
reader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}核心方法说明
JsonReader提供了一系列方法用于读取不同结构的JSON数据,常用方法如下:
beginObject():开始解析一个JSON对象,对应JSON中的{endObject():结束当前JSON对象的解析,对应JSON中的}beginArray():开始解析一个JSON数组,对应JSON中的[endArray():结束当前JSON数组的解析,对应JSON中的]nextName():读取当前对象的下一个字段名nextString():读取下一个字符串类型的值nextDouble():读取下一个浮点类型的值nextBoolean():读取下一个布尔类型的值nextInt():读取下一个整型类型的值skipValue():跳过当前不需要处理的值hasNext():判断当前对象或数组是否还有下一个元素
处理复杂嵌套JSON结构
实际开发中的JSON往往存在多层嵌套,比如下面的JSON包含一个用户对象列表:
{
"code": 200,
"msg": "请求成功",
"data": {
"user_list": [
{
"user_id": 1,
"user_name": "张三",
"age": 25
},
{
"user_id": 2,
"user_name": "李四",
"age": 28
}
]
}
}针对这种嵌套结构,我们可以通过多层遍历的方式解析,代码如下:
import android.util.JsonReader;
import java.io.IOException;
import java.io.StringReader;
import java.util.ArrayList;
import java.util.List;
public class ComplexJsonParse {
static class User {
int userId;
String userName;
int age;
@Override
public String toString() {
return "User{userId=" + userId + ", userName='" + userName + "', age=" + age + "}";
}
}
public List<User> parseComplexJson() {
String jsonStr = "{\"code\":200,\"msg\":\"请求成功\",\"data\":{\"user_list\":[{\"user_id\":1,\"user_name\":\"张三\",\"age\":25},{\"user_id\":2,\"user_name\":\"李四\",\"age\":28}]}}";
List<User> userList = new ArrayList<>();
JsonReader reader = new JsonReader(new StringReader(jsonStr));
try {
reader.beginObject();
while (reader.hasNext()) {
String topField = reader.nextName();
if ("data".equals(topField)) {
reader.beginObject();
while (reader.hasNext()) {
String dataField = reader.nextName();
if ("user_list".equals(dataField)) {
reader.beginArray();
while (reader.hasNext()) {
User user = new User();
reader.beginObject();
while (reader.hasNext()) {
String userField = reader.nextName();
switch (userField) {
case "user_id":
user.userId = reader.nextInt();
break;
case "user_name":
user.userName = reader.nextString();
break;
case "age":
user.age = reader.nextInt();
break;
default:
reader.skipValue();
break;
}
}
reader.endObject();
userList.add(user);
}
reader.endArray();
} else {
reader.skipValue();
}
}
reader.endObject();
} else {
reader.skipValue();
}
}
reader.endObject();
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
reader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
return userList;
}
}注意事项
使用JsonReader时需要注意以下几点,避免出现解析异常:
- 解析顺序必须和JSON的结构完全匹配,先调用
beginObject再读取对象内字段,数组必须先调用beginArray再遍历元素。 - 读取值的类型必须和JSON中字段的实际类型匹配,比如字符串类型不能调用
nextInt读取,否则会抛出MalformedJsonException。 - 每次
beginObject、beginArray都必须有对应的endObject、endArray收尾,否则会导致解析状态异常。 - 解析完成后务必调用
close方法关闭JsonReader,释放相关资源,建议使用try-finally结构保证资源正确释放。 - 如果JSON数据来源是网络流或文件流,需要先将流转换为
Reader对象再传入JsonReader构造函数,不要直接处理二进制流。
适用场景对比
为了帮助开发者选择合适的解析方式,下面对比JsonReader和常用第三方解析库的适用场景:
| 解析方式 | 内存占用 | 解析速度 | 适用场景 |
|---|---|---|---|
| JsonReader | 低 | 较快 | 大体积JSON、流式数据、内存敏感场景 |
| Gson | 中 | 快 | 常规JSON解析、需要自动映射对象场景 |
| JSONObject原生解析 | 高 | 较慢 | 简单小体积JSON、快速临时解析场景 |
JsonReaderAndroidJSON解析JSON修改时间:2026-06-06 14:29:57