Json的全称:JavaScript Object Notation
Android 常用传递数据的格式 分两种 一种XML另一种JSON。 JSON与XML的相比较 的优点是 作为数据传输格式,跟XML类似,但是比XML更加轻巧 由于JSON是JavaScript的原生格式,所以JSON不需要包含特定内容的首部信息 所以速度 远远快于XML。
现在我们常用解析 JSON的方法一般 有以下几种 1 android 原生 api 解析 2.阿里巴巴 的 fastjson 3. 谷歌 的Gson. 这三种解析 的原理 以及解析效率 有什么不同?第一种 ,android 中自带的原生解析api 。
例如 这样一个json串
// 假设现在要创建这样一个json文本
{
"phone" : ["12345678", "87654321"], // 数组
"name" : "yuanzhifei89", // 字符串
"age" : 100, // 数值
"address" : { "country" : "china", "province" : "jiangsu" }, // 对象
"married" : false // 布尔值
}
首先生成一个json 串private String compilejson() {
try {
JSONObject person = new JSONObject();
// 第一个键phone的值是数组,所以需要创建数组对象
JSONArray phone = new JSONArray();
phone.put("12345678").put("87654321");
person.put("phone", phone);
person.put("name", "yuanzhifei89");
person.put("age", 100);
// 键address的值是对象,所以又要创建一个对象
JSONObject address = new JSONObject();
address.put("country", "china");
address.put("province", "jiangsu");
person.put("address", address);
person.put("married", false);
return person.toString();
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
然后解析 这个json串一般我们不这样写
public void parseJson(String json){
try {
JSONTokener jsonParser = new JSONTokener(json);
// 此时还未读取任何json文本,直接读取就是一个JSONObject对象。
// 如果此时的读取位置在"name" : 了,那么nextValue就是"yuanzhifei89"(String)
JSONObject person = (JSONObject) jsonParser.nextValue();
// 接下来的就是JSON对象的操作了
person.getJSONArray("phone");
person.getString("name");
person.getInt("age");
person.getJSONObject("address");
person.getBoolean("married");
} catch (JSONException e) {
e.printStackTrace();
}
}
通常我们都是这么写 public void parseJson2(String Json){
try {
JSONObject jsonObj=new JSONObject(Json);
jsonObj.getJSONArray("phone");
jsonObj.getString("name");
jsonObj.getInt("age");
jsonObj.getJSONObject("address");
jsonObj.getBoolean("married");
} catch (JSONException e) {
e.printStackTrace();
}
其实第一种 JSONObject person = (JSONObject) jsonParser.nextValue(); 与第二行JSONObject jsonObj=new JSONObject(Json);是一样的。
都是创建了一JSONObject对象。
看下 nextValue() 源码public Object nextValue() throws JSONException {
int c = nextCleanInternal();
switch (c) {
case -1:
throw syntaxError("End of input");
case '{':
return readObject();
case '[':
return readArray();
case '\'':
case '"':
return nextString((char) c);
default:
pos--;
return readLiteral();
}
}
这里第一次解析 执行的代码是 case '{' :
return readObject();
这个readObject() 方法
private JSONObject readObject() throws JSONException {
JSONObject result = new JSONObject();
/* Peek to see if this is the empty object. */
int first = nextCleanInternal();
if (first == '}') {
return result;
} else if (first != -1) {
pos--;
}
while (true) {
Object name = nextValue();
if (!(name instanceof String)) {
if (name == null) {
throw syntaxError("Names cannot be null");
} else {
throw syntaxError("Names must be strings, but " + name
+ " is of type " + name.getClass().getName());
}
}
/*
* Expect the name/value separator to be either a colon ':', an
* equals sign '=', or an arrow "=>". The last two are bogus but we
* include them because that's what the original implementation did.
*/
int separator = nextCleanInternal();
if (separator != ':' && separator != '=') {
throw syntaxError("Expected ':' after " + name);
}
if (pos < in.length() && in.charAt(pos) == '>') {
pos++;
}
<span style="color:#6666cc;">result.put((String) name, nextValue());</span>
switch (nextCleanInternal()) {
case '}':
return result;
case ';':
case ',':
continue;
default:
throw syntaxError("Unterminated object");
}
}
}
这个方法的意思是 ,只要没有循环到Json 串 结束的标志}
while (true)
就一直遍历执行
result.put((String) name, nextValue());</span>
就是创建了而一个 JSONObject result = new JSONObject();
不断地把json 串中的 键值 放到JSONObeject 对象身上。
然后通过 getXX(key)方法 取值。例 person.getString("name"); get()方法的原理是
/**
* Returns the value mapped by {@code name}.</span></span>
*
* @throws JSONException if no such mapping exists.
*/
public Object get(String name) throws JSONException {
Object result = nameValuePairs.get(name);
if (result == null) {
throw new JSONException("No value for " + name);
}
return result;
}
nameValuePairs 是一个map 对象 private final Map<String, Object> nameValuePairs;在构造方法
public JSONObject(String json) throws JSONException {
this(new JSONTokener(json));
}
调用了这个方法
public JSONObject(JSONTokener readFrom) throws JSONException {
/*
* Getting the parser to populate this could get tricky. Instead, just
* parse to temporary JSONObject and then steal the data from that.
*/
Object object = readFrom.nextValue();
if (object instanceof JSONObject) {
this.nameValuePairs = ((JSONObject) object).nameValuePairs;
} else {
throw JSON.typeMismatch(object, "JSONObject");
}
}
而我们已经看过readFrom.nextValue(); 是 return readObject(); 而 这个 方法的返回值类型上面已经有 就是 JSONObject。至此 原生API 解析json 我们已经理解了,就是将一个json串 存到 map 中 然后通过键值对 取出来。
那么看一下Gson 解析
public ArrayList<JsonBean> gsonParse(String json){
ArrayList<JsonBean> result = null;
try {
Gson gson = new Gson();
result = gson.fromJson(json, new TypeToken<List<JsonBean>>() {
}.getType());
} catch (JsonSyntaxException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return result;
}
主要就是 fromJson (String json,Type typeOfT)这个方法。 第一个是json 串,第二个参数 Type 对线 ,这里 看注释
Parameters:
<T> the type of the desired object
json the string from which the object is to be deserialized
typeOfT The specific genericized type of src. You can obtain this type by using thecom.google.gson.reflect.TypeToken class. For example, to get the type forCollection<Foo>, you should use:
Type typeOfT = new TypeToken<Collection<Foo>>(){}.getType();
只要 new 一个对象就可以。
参数确定了,看下 源码
public <T> T fromJson(String json, Type typeOfT) throws JsonSyntaxException {
if (json == null) {
return null;
}
StringReader reader = new StringReader(json);
T target = (T) fromJson(reader, typeOfT);
return target;
}
还是 还是同一个方法的重载, 参数 由 String ----> StringReader 继续看。@SuppressWarnings("unchecked")
public <T> T fromJson(Reader json, Type typeOfT) throws JsonIOException, JsonSyntaxException {
JsonReader jsonReader = new JsonReader(json);
T object = (T) fromJson(jsonReader, typeOfT);
assertFullConsumption(object, jsonReader);
return object;
同理 还是 重载 StringReader ------>JsonReader public <T> T fromJson(JsonReader reader, Type typeOfT) throws JsonIOException, JsonSyntaxException {
boolean isEmpty = true;
boolean oldLenient = reader.isLenient();
reader.setLenient(true);
try {
reader.peek();
isEmpty = false;
TypeToken<T> typeToken = (TypeToken<T>) TypeToken.get(typeOfT);
TypeAdapter<T> typeAdapter = getAdapter(typeToken);
T object = typeAdapter.read(reader);
return object;
} catch (EOFException e) {
/*
* For compatibility with JSON 1.5 and earlier, we return null for empty
* documents instead of throwing.
*/
if (isEmpty) {
return null;
}
throw new JsonSyntaxException(e);
} catch (IllegalStateException e) {
throw new JsonSyntaxException(e);
} catch (IOException e) {
// TODO(inder): Figure out whether it is indeed right to rethrow this as JsonSyntaxException
throw new JsonSyntaxException(e);
} finally {
reader.setLenient(oldLenient);
}
}
这里只看关键代码
reader.peek();
isEmpty = false;
TypeToken<T> typeToken = (TypeToken<T>) TypeToken.get(typeOfT);
TypeAdapter<T> typeAdapter = getAdapter(typeToken);
T object = typeAdapter.read(reader); return object;
主要是通过 TypeAdapter 组装 拿到了 反序列化对象。既 解析String----> Object.FastJson 解析 json的过程是怎么样的,下载源码来看看, 下载地址 https://github.com/alibaba/fastjson/wiki
下载下来以后 导入工程,关联源码 不会关联的 可以看我另一篇文章或者参看这里 http://jingyan.baidu.com/article/60ccbceb0be34b64cbb1976b.html。
public <T> T fastJsonParseJson(String json,Class<T> cls){
T object = JSON.parseObject(json, cls);
return object;
}
看parseObject 方法 怎么做的public static final <T> T parseObject(String text, Class<T> clazz) {
return parseObject(text, clazz, new Feature[0]);
}
最终 执行的代码是这个方法 public static final <T> T parseObject(String input, Type clazz, ParserConfig config, ParseProcess processor,
int featureValues, Feature... features) {
if (input == null) {
return null;
}
for (Feature featrue : features) {
featureValues = Feature.config(featureValues, featrue, true);
}
DefaultJSONParser parser = new DefaultJSONParser(input, config, featureValues);
if (processor instanceof ExtraTypeProvider) {
parser.getExtraTypeProviders().add((ExtraTypeProvider) processor);
}
if (processor instanceof ExtraProcessor) {
parser.getExtraProcessors().add((ExtraProcessor) processor);
}
T value = (T) parser.parseObject(clazz);
parser.handleResovleTask(value);
parser.close();
return (T) value;
}
这个方法中的关键代码就是 T value = (T) parser.parseObject(clazz);
这一句就是解析json 转成对象
下面 我们将要 从解析数据性能方面 做一下 比较 mark. 未完