由于个人觉得android目前的JSON解析框架,在获取键值时操作过于繁琐,因此特意制作了这个小工具,主要有如下几个优点,可能已经有这样的工具了,不过博主暂时没找到。
工具优点:
1、支持直接访问JSON各节点,只需传递JSON格式的字符串。
2、支持点连接(.)访问键值。
废话不多说,看代码:
package com.yourpackage.utils;
import android.util.Log;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
/**
* JSON实用工具,方便快速访问JSON各节点
*
* 支持点连接访问
*/
public class JSONUtils {
String TAG = "JSONUTILS";
private JSONObject jsonObject;
//临时对象
private JSONObject tmpJsonObject;
private JSONArray tmpJsonArray;
private Object tmpObject;
/**
* 初始化
*
* @param json
*/
public JSONUtils(String json) {
try {
this.tmpJsonObject = this.jsonObject = new JSONObject(json);
} catch (JSONException e) {
e.printStackTrace();
}
}
/**
* 获取JSON对象
*
* @param key
* @return
*/
public JSONUtils getJSONObject(String key) {
try {
this.tmpJsonObject = this.tmpJsonObject.getJSONObject(key);
} catch (JSONException e) {
Log.e(TAG, "键值:" + key + "不存在或是一个数组,正在尝试解析为数组...");
this.getJSONArray(key);
}
return this;
}
/**
* 获取对象,指非JSON对象,调用这个方法可以进行格式化返回结果,如toInt,toString等
*
* @param key
* @return
*/
public JSONUtils get(String key) {
try {
this.tmpObject = this.tmpJsonObject.get(key);
} catch (JSONException e) {
Log.e(TAG, "键值:" + key + "不存在或是一个数组,正在尝试解析为数组...");
this.getJSONArray(key);
}
return this;
}
//重置临时JSON对象,调用toXXX函数时自动重置
public JSONUtils reset() {
this.tmpJsonObject = this.jsonObject;
return this;
}
/**
* 获取JSON数组对象
*
* @param key
* @return
*/
public JSONUtils getJSONArray(String key) {
try {
this.tmpJsonArray = this.tmpJsonObject.getJSONArray(key);
} catch (JSONException e) {
Log.e(TAG, "键值:" + key + "不是一个数组");
}
return this;
}
/**
* 获取指定索引的数组项,JSON数组
*
* @param idx
* @return
*/
public JSONUtils getJSONArrayItem(int idx) {
try {
this.tmpJsonObject = this.tmpJsonArray.getJSONObject(idx);
} catch (JSONException e) {
e.printStackTrace();
}
return this;
}
/**
* 获取指定索引的数组项,非JSON数组
*
* @param idx
* @return
*/
public JSONUtils getArraytem(int idx) {
try {
this.tmpObject = this.tmpJsonArray.get(idx);
} catch (JSONException e) {
e.printStackTrace();
}
return this;
}
/**
* 点连接的方式访问键值,示例:a.b.c
* @param key
* @return
*/
public JSONUtils getByDotKey(String key)
{
String[] keys = key.split("\\.");
String tmpKey = "";
String[] tmpKeys;
JSONObject tmpJsonObject = this.tmpJsonObject;
try
{
for(int i=0;i<keys.length;i++)
{
tmpKey = keys[i];
//是一个数组
if (tmpKey.contains(":"))
{
tmpKeys = tmpKey.split(":");
this.tmpJsonArray = tmpJsonObject.getJSONArray(tmpKeys[0]);
tmpJsonObject = this.tmpJsonArray.getJSONObject(Integer.valueOf(tmpKeys[1]));
}else
{
if (i+1>=keys.length)
{
this.tmpObject = tmpJsonObject.get(tmpKey);
}else{
tmpJsonObject = tmpJsonObject.getJSONObject(tmpKey);
}
}
}
}catch (Exception e)
{
e.printStackTrace();
}
return this;
}
public int toInt()
{
reset();
return Integer.valueOf(tmpObject.toString());
}
public float toFloat()
{
reset();
return Float.valueOf(tmpObject.toString());
}
public String toString()
{
reset();
return tmpObject.toString();
}
public Boolean toBoolean()
{
reset();
return Boolean.valueOf(tmpObject.toString());
}
}
下边来看下用法:
假设我们有如下的JSON数据,下边这个是PHP版,方便预览观看:
$ret = [
'a'=>[
'i'=>11
],
'b'=>[
['c'=>3,'c1'=>31,'c2'=>[
['y1'=>1],
['y2'=>2]
]],
['f'=>5,'f1'=>51],
['g'=>5,'g1'=>51]
],
'd'=>'5'
];
转换为JSON字符串就是下边的样子:
{"a":{"i":11},"b":[{"c":3,"c1":31,"c2":[{"y1":1},{"y2":2}]},{"f":5,"f1":51},{"g":5,"g1":51}],"d":"5"}
这个实用工具有两种方式可以访问键值,我们先来看下点连接(.)的方式如何访问键值:
1、点连接(.)为了方便我设计了一个约定,用冒号(:)代表访问数组,用(.)代表访问下一个键值
假设我们想获取上边JSON中的y2的值,我们可以这样写:
//初始化
JSONUtils jsonUtils = new JSONUtils(json字符串);
int a = jsonUtils.getByDotKey("b:0.c2:1.y2").toInt();
上边,b:0中的冒号(:)代表b键值对应的是一个数组,然后访问第0个索引,点(.)代表下一个节点,c2跟b一样,也是一个数组然后访问第1个索引,接着访问y2,最后调用toInt转换为整数值。
2、第二种方式就是调用函数的方式,代码看起来比较多,一般推荐第一种就可以了,第2种我们可以这样写:
//初始化
JSONUtils jsonUtils = new JSONUtils(json字符串);
int a = jsonUtils
.getJSONArray("b")
.getJSONArrayItem(0)
.getJSONArray("c2")
.getJSONArrayItem(1)
.get("y2")
.toInt();
效果是一样的,只是第二种代码含义看起来更加明朗一些,代码量更多些。
代码没有经过严格测试,如果大家在使用过程中遇到bug可以给我留言~~~
完