public final class JsonReader
extends Object
implements Closeable
java.lang.Object | |
↳ | android.util.JsonReader |
将JSON( RFC 4627 )编码值读取为令牌流。 该流包括文字值(字符串,数字,布尔值和空值)以及对象和数组的开始和结束分隔符。 这些令牌按深度优先顺序遍历,与它们在JSON文档中出现的顺序相同。 在JSON对象中,名称/值对由单个标记表示。
JsonReader
.
接下来,为您的JSON文本中的每个结构创建处理程序方法。 您需要为每种对象类型和每种数组类型提供一种方法。
beginArray()
to consume the array's opening bracket. Then create a while loop that accumulates values, terminating when hasNext()
is false. Finally, read the array's closing bracket by calling endArray()
. beginObject()
to consume the object's opening brace. Then create a while loop that assigns values to local variables based on their name. This loop should terminate when hasNext()
is false. Finally, read the object's closing brace by calling endObject()
. 当遇到嵌套的对象或数组时,委托给相应的处理程序方法。
遇到未知名称时,严格的解析器应该会失败并产生异常。 宽松的解析器应该调用skipValue()
以递归方式跳过该值的嵌套标记,否则这些标记可能会发生冲突。
如果值可能为空,则应首先使用peek()
检查。 可以使用nextNull()
或skipValue()
来消费空文字。
[
{
"id": 912345678901,
"text": "How do I read JSON on Android?",
"geo": null,
"user": {
"name": "android_newb",
"followers_count": 41
}
},
{
"id": 912345678902,
"text": "@android_newb just use android.util.JsonReader!",
"geo": [50.454722, -104.606667],
"user": {
"name": "jesse",
"followers_count": 2
}
}
]
This code implements the parser for the above structure:
public List<Message> readJsonStream(InputStream in) throws IOException {
JsonReader reader = new JsonReader(new InputStreamReader(in, "UTF-8"));
try {
return readMessagesArray(reader);
} finally {
reader.close();
}
}
public List<Message> readMessagesArray(JsonReader reader) throws IOException {
List<Message> messages = new ArrayList<Message>();
reader.beginArray();
while (reader.hasNext()) {
messages.add(readMessage(reader));
}
reader.endArray();
return messages;
}
public Message readMessage(JsonReader reader) throws IOException {
long id = -1;
String text = null;
User user = null;
List<Double> geo = null;
reader.beginObject();
while (reader.hasNext()) {
String name = reader.nextName();
if (name.equals("id")) {
id = reader.nextLong();
} else if (name.equals("text")) {
text = reader.nextString();
} else if (name.equals("geo") && reader.peek() != JsonToken.NULL) {
geo = readDoublesArray(reader);
} else if (name.equals("user")) {
user = readUser(reader);
} else {
reader.skipValue();
}
}
reader.endObject();
return new Message(id, text, user, geo);
}
public List<Double> readDoublesArray(JsonReader reader) throws IOException {
List<Double> doubles = new ArrayList<Double>();
reader.beginArray();
while (reader.hasNext()) {
doubles.add(reader.nextDouble());
}
reader.endArray();
return doubles;
}
public User readUser(JsonReader reader) throws IOException {
String username = null;
int followersCount = -1;
reader.beginObject();
while (reader.hasNext()) {
String name = reader.nextName();
if (name.equals("name")) {
username = reader.nextString();
} else if (name.equals("followers_count")) {
followersCount = reader.nextInt();
} else {
reader.skipValue();
}
}
reader.endObject();
return new User(username, followersCount);
}
[1, "1"]
may be read using either
nextInt()
or
nextString()
. This behavior is intended to prevent lossy numeric conversions: double is JavaScript's only numeric type and very large values like
9007199254740993
cannot be represented exactly on that platform. To minimize precision loss, extremely large values should be written and read as strings in JSON.
每个JsonReader
可用于读取单个JSON流。 这个类的实例不是线程安全的。
Public constructors |
|
---|---|
JsonReader(Reader in) 创建一个从 |
Public methods |
|
---|---|
void |
beginArray() 使用JSON流中的下一个标记并声明它是新数组的开始。 |
void |
beginObject() 使用JSON流中的下一个标记并声明它是新对象的开始。 |
void |
close() 关闭这个JSON阅读器和底层的 |
void |
endArray() 使用JSON流中的下一个标记并声明它是当前数组的结尾。 |
void |
endObject() 使用JSON流中的下一个标记并声明它是当前数组的结尾。 |
boolean |
hasNext() 如果当前数组或对象具有其他元素,则返回true。 |
boolean |
isLenient() 如果此解析器在接受它时是自由的,则返回true。 |
boolean |
nextBoolean() 返回下一个标记的 |
double |
nextDouble() 返回下一个标记的 |
int |
nextInt() 返回下一个标记的 |
long |
nextLong() 返回下一个标记的 |
String |
nextName() 返回下一个标记 |
void |
nextNull() 使用JSON流中的下一个标记并声明它是一个空字符串。 |
String |
nextString() 返回下一个标记的 |
JsonToken |
peek() 返回下一个标记的类型而不消耗它。 |
void |
setLenient(boolean lenient) 将此解析器配置为接受它的自由。 |
void |
skipValue() 递归跳过下一个值。 |
String |
toString() 返回对象的字符串表示形式。 |
Inherited methods |
|
---|---|
From class java.lang.Object
|
|
From interface java.io.Closeable
|
|
From interface java.lang.AutoCloseable
|
boolean hasNext ()
如果当前数组或对象具有其他元素,则返回true。
Returns | |
---|---|
boolean |
Throws | |
---|---|
IOException |
boolean nextBoolean ()
返回下一个标记的 boolean
值,并将其消耗。
Returns | |
---|---|
boolean |
Throws | |
---|---|
IllegalStateException |
if the next token is not a boolean or if this reader is closed. |
IOException |
double nextDouble ()
返回下一个标记的double
值,并将其消耗。 如果下一个标记是字符串,则此方法将尝试使用parseDouble(String)
将其解析为双parseDouble(String)
。
Returns | |
---|---|
double |
Throws | |
---|---|
IllegalStateException |
if the next token is not a literal value. |
IOException |
int nextInt ()
返回下一个标记的int
值,并将其消耗。 如果下一个标记是一个字符串,则此方法将尝试将其解析为一个int。 如果Java int
无法准确表示下一个标记的数值, int
引发此方法。
Returns | |
---|---|
int |
Throws | |
---|---|
IllegalStateException |
if the next token is not a literal value. |
NumberFormatException |
if the next literal value cannot be parsed as a number, or exactly represented as an int. |
IOException |
long nextLong ()
返回下一个标记的long
值,并将其消耗。 如果下一个标记是一个字符串,则此方法将尝试将其解析为长整型。 如果下一个标记的数值不能完全由Java long
表示,则此方法会抛出。
Returns | |
---|---|
long |
Throws | |
---|---|
IllegalStateException |
if the next token is not a literal value. |
NumberFormatException |
if the next literal value cannot be parsed as a number, or exactly represented as a long. |
IOException |
String nextName ()
返回下一个标记 property name
,并将其消耗。
Returns | |
---|---|
String |
Throws | |
---|---|
IOException |
if the next token in the stream is not a property name. |
void nextNull ()
使用JSON流中的下一个标记并声明它是一个空字符串。
Throws | |
---|---|
IllegalStateException |
if the next token is not null or if this reader is closed. |
IOException |
String nextString ()
返回下一个标记的string
值,并将其消耗。 如果下一个标记是一个数字,则此方法将返回其字符串形式。
Returns | |
---|---|
String |
Throws | |
---|---|
IllegalStateException |
if the next token is not a string or if this reader is closed. |
IOException |
void setLenient (boolean lenient)
将此解析器配置为接受它的自由。 默认情况下,此解析器是严格的,只接受RFC 4627指定的JSON 。 将解析器设置为宽松会导致它忽略以下语法错误:
//
or #
and ending with a newline character. /*
and ending with *
/
. Such comments may not be nested. 'single quoted'
. 'single quoted'
. ;
instead of ,
. =
or =>
instead of :
. ;
instead of ,
. Parameters | |
---|---|
lenient |
boolean
|
void skipValue ()
递归跳过下一个值。 如果它是一个对象或数组,则会跳过所有嵌套元素。 此方法适用于JSON令牌流包含无法识别或未处理的值的情况。
Throws | |
---|---|
IOException |
String toString ()
返回对象的字符串表示形式。 通常, toString
方法会返回一个“文本地表示”该对象的字符串。 结果应该是一个简洁但内容丰富的表述,对于一个人来说很容易阅读。 建议所有子类重写此方法。
类Object
的toString
方法返回一个字符串,其中包含对象为实例的类的名称,符号字符“ @
”以及该对象的哈希代码的无符号十六进制表示形式。 换句话说,这个方法返回一个字符串,其值等于:
getClass().getName() + '@' + Integer.toHexString(hashCode())
Returns | |
---|---|
String |
a string representation of the object. |