1 JSON解析
1.1 JSON的概念
Ø JSON(JavaScript Object Natation)
Ø 是一种轻量级的数据交换格式
Ø 是基于纯文本的数据格式
Ø 可以用JSON传输的数据类型:
ü 单个数据(字符串、数字)
ü 复杂的Object类型
ü 数组
1.2 JSON的解析实现
l 数据格式
Ø Key-Value对,以冒号间隔
Ø 值用双引号
例:{“name”:“xiaoqiang”,“age”:“18”}
Ø 值也可以是另一个键值对的集合
{“data”:{“city”:“ShangHai”,“cityId”:“21”}}
Ø 值还可以是一个数组
{“data”: [{“city”:“ShangHai”,“cityId”:“21”},
{“city”:“BeiJing”,“cityId”:“18”}]}
l JSON解析的三种主流解析方式
Ø 传统JSON
Ø GSON
Ø Fast Json
l 传统的JSON解析
Ø Android自带的JSON解析方式,也是比较传统的JSON解析方式
Ø JSONObject代表了一个带解析的键值对集合
例:JSONObject jsonObj = newJSONObject(data)
Ø 通过getXXX方法获取值
例: String name = jsonObj.getString(“name”)
int age = jsonObj.getInt(“age”);
…
Ø 如果value是对象,用对象接收,继续解析
JSONObjectjobj = jsonObj.getJSONObject(key)
Ø 如果value是数组,用数组接收,继续解析
JSONArrayjarr = jsonObj.getJSONArray(key)
l GSON
Ø GSON是 Google提供的用来在 Java 对象和 JSON 数据之间进行映射的 Java 类库。可以将一个 JSON 字符串转成一个 Java 对象,或者反过来。
Ø GSON支持任意复杂Java对象包括没有源代码的对象。
l FastJson
Ø 阿里巴巴FastJson是一个Json处理工具包,包括“序列化”和“反序列化”两部分,它具备如下特征:
ü 速度最快,测试表明,fastjson具有极快的性能,超越任何其他的Java Json parser。包括自称最快的JackJson
ü 功能强大,完全支持Java Bean、集合、Map、日期、Enum,支持泛型,支持自省。
ü 无依赖,能够直接运行在JDK5以上版本
ü 支持Android
ü 开源(Apache2.0)
1.3 原始Json解析实例
【
public class MainActivity extends Activity {
@Override
protected voidonCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
// 简单数据解析
public voidjsonParse1(View v) throwsJSONException {
Stringjson = "{name:xiaoqiang,age:18}";
JSONObjectmjson = new JSONObject(json);
Stringname = mjson.getString("name");
int age = mjson.getInt("age");
Toast.makeText(getApplicationContext(),name + "..." + age, 0).show();
}
// 简单对象解析
public voidjsonParse2(View v) throwsJSONException {
Stringjson = "{data:{city:ShangHai,cityId:21}}";
JSONObjectmjson = new JSONObject(json);
JSONObjectdata = mjson.getJSONObject("data");
Stringcity = data.getString("city");
int cityId = data.getInt("cityId");
Toast.makeText(getApplicationContext(),city + "..." + cityId, 0)
.show();
}
// 简单数组解析
public voidjsonParse3(View v) throwsJSONException {
Stringjson = "{data:[{city:ShangHai,cityId:21},{city:BeiJing,cityId:18}]}";
JSONObjectmjson = new JSONObject(json);
JSONArraydata = mjson.getJSONArray("data");
StringBufferbuffer = new StringBuffer();
for (inti = 0; i < data.length(); i++) {
JSONObjecttemp = data.getJSONObject(i);
Stringcity = temp.getString("city");
int cityId = temp.getInt("cityId");
buffer.append(city+ "...");
buffer.append(cityId+ "...");
}
Toast.makeText(getApplicationContext(),buffer, 0).show();
}
}
】
1.4 Json字符串的自动解析
【
作用:自动解析指定的json字符串,并将指定的解析结果返回
支持的自动解析工具:
1. Gson google 出品
2. FastJson 阿里巴巴出品
Gson ---官方推出的自动解析工具
FastJson ---- 号称最快的json解析工具
手写实体封装类(JavaBeen)的严格要求,这是Gson和FastJson通过反射解析成功的前提条件,AS通过GsonFormat可以自动完成实体类的封装,大大提高开发效率,减少人为失误!
/**
* Created by xuyangsheng on 2015/4/8.
* 用于封装fastjson或者gson解析后的得到的结果类型
* 在封装此类中有以下几点要求:
* 1. 该类中的所有属性的名字必须是json字符串中key的名字
* 2. 属性的类型,必须是key所对应的value的类型
* 3. 该类中的所有属性必须是private,并且必须按要求提供get,set方法
* 4. 该类中必须提供无参,有参的构造方法
*/
FastJson的使用方式:
1. 将fastjson对应的jar包添加到工程的libs文件夹中,并且选择Add As Library方法将jar包添加到工程中使用
2. 根据json字符串创建一个JavaBean类文件(即自定义类文件)
3. 通过fastjson包中的JsonObject调用静态方法parseObject即可获取解析结果
Gson的使用方式:
1. 将gson对应的jar包添加到工程的libs文件夹中,并且选择Add As Library方法将jar包添加到工程中使用
2. 根据json字符串创建一个JavaBean类文件(即自定义类文件)
3. 通过gson包中的Gson对象调用方法fromJson即可获取解析结果
自动生成解析结果的JavaBean类的方式:(适用于AndroidStudio)
1. 先判断当前studio中是否用于GsonFormat插件
判断方式:
在任意类的空白位置右键,选择Generate选项,在弹出的窗口中如果含有GsonFormat选项则视为插件已安装,反之,则是未安装
安装方式:
Settings---Plugins----Browserepositories,在弹出窗口的搜索框中填写gson或者GsonFormat进行搜索
在下方列表中找到搜索结果后点击搜索结果的Install plugin按钮即可完成安装
2. 在安装好GsonFormat插件后,新建一个类,在任意类的空白位置右键,选择Generate选项,并在弹出的窗口中选择GsonFormat选项
3. 在新弹出的窗口中将要解析的完整的json字符串粘贴到当前窗口中,点击ok按钮后即可生成对应的JavaBean类
有了自动解析后,异步任务类的优化处理方式:
作用:可以实现所有的文字加载解析工作都通过同一个异步任务类完成,不再需要给每个网址接口提供一个异步任务了
实现方式:
//类名后的<T> 用于自定义泛型,作用是可以通过泛型中的字母指代任意类型的对象 //因此不管最终的解析结果是什么样的类型都可以通过T进行替代 public class MyTextTask_Auto<T> extends AsyncTask<String,Void,T>{ public interface DataCallback<T> { void getData(T t); } DataCallback callback; //声明T的class类型类对象,并通过构造方法进行赋值 Class<T> cls; public MyTextTask_Auto(DataCallback callback,Class<T> cls) { this.callback = callback; this.cls = cls; } @Override protected T doInBackground(String... params) { try { HttpURLConnection conn = (HttpURLConnection) new URL(params[0]).openConnection(); conn.setRequestMethod("GET"); conn.connect(); if (conn.getResponseCode() == 200) { InputStream is = conn.getInputStream(); byte[] b = new byte[1024]; int num=-1; StringBuilder builder = new StringBuilder(); while ((num=is.read(b)) != -1) { builder.append(new String(b,0,num)); } String json = builder.toString(); //使用Gson进行自动解析 return new Gson().fromJson(json,cls); } } catch (IOException e) { e.printStackTrace(); } return null; } @Override protected void onPostExecute(T gaos) { super.onPostExecute(gaos); callback.getData(gaos); } }
】
1.4.1 Gson与FastJson简单实例
【根据Json严格的实体封装类略……..
异步任务和网络访问:
public classMyTextTask extendsAsyncTask<String,Void,Gao> {
/**
*通过接口回调,用于数据的返回
*/
publicinterface DataCallback{
void getData(Gao list);
}
DataCallback callback;
public MyTextTask(DataCallbackcallback){
this.callback= callback;
}
@Override
protected GaodoInBackground(String... strings){
try {
HttpURLConnection conn =(HttpURLConnection) newURL(strings[0]).openConnection();
conn.setRequestMethod("GET");
conn.connect();
if(conn.getResponseCode()== 200){
InputStream is =conn.getInputStream();
byte[] b = new byte[1024];
int num = -1;
StringBuilderbuilder = new StringBuilder();
while((num =is.read(b))!=-1){
builder.append(new String(b,0,num));
}
String json = builder.toString();
/**
* 通过fastjson中的JSONObject对象调用
* parseObject方法即可实现json字符串的自动解析
* 参数:
* 1:要解析的字符串
* 2:字符串要解析成什么样类型的对象
*
*/
// Gao gao =com.alibaba.fastjson.JSONObject.parseObject(json,Gao.class);
/**
* 使用Gson进行自动解析
*/
Gson gson =new Gson();
Gao gao =gson.fromJson(json,Gao.class);
return gao;
}
} catch (IOException e){
e.printStackTrace();
}
return null;
}
@Override
protected void onPostExecute(Gao gao) {
super.onPostExecute(gao);
callback.getData(gao);
}
}
测试引用:
public classMainActivity extendsActivity {
@Override
protected void onCreate(BundlesavedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
/**
* 用于自动JSON解析数据返回测试
*/
/* new MyTextTask(newMyTextTask.DataCallback() {
@Override
public void getData(Gao list){
List<Info> infos =list.getInfo();
Log.i("===","====== gao infos "+infos.toString());
}
}).execute("http://www.h5151.com/ajax/hd_game/platform=2&compare=af9cd783af6a57e43edeb8bd54421d45");
*/
}
}
】
1.5 JsonUtils自动解析工具类
【
public classJsonUtils<T> {
public TgetData(String json, Class<T> cls){
return new Gson().fromJson(json,cls);
}
}
异步任务+接口回调+泛型+反射机制:
public classMyTextTask_Auto<T>extends AsyncTask<String,Void,T> {
/**
*定义接口回调,用于数据返回
*/
publicinterface DataCallback<T> {
void getData(Tt);
}
DataCallback callback;
Class<T>cls;
public MyTextTask_Auto(DataCallback callback,Class<T> cls){
this.callback= callback;
this.cls=cls;
}
@Override
protected TdoInBackground(String...strings) {
try {
HttpURLConnection conn =(HttpURLConnection) newURL(strings[0]).openConnection();
conn.setRequestMethod("GET");
conn.connect();
if(conn.getResponseCode()==200){
InputStream is =conn.getInputStream();
byte[] b = new byte[1024];
int num = -1;
StringBuilderbuilder = new StringBuilder();
while((num=is.read(b))!=-1){
builder.append(new String(b,0,num));
}
String json =builder.toString();
/**
* 使用Gson进行自动解析
*/
return new JsonUtils<T>().getData(json,cls);
}
} catch (IOException e){
e.printStackTrace();
}
return null;
}
@Override
protected void onPostExecute(Tt) {
super.onPostExecute(t);
callback.getData(t); //返回封装的对象
}
}
测试引用:
public classMainActivity extendsActivity {
@Override
protected void onCreate(BundlesavedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
/**
* 泛型对象接口封装+接口回调+JsonFormat实体类自动生成
*/
new MyTextTask_Auto<GaoBean>(newMyTextTask_Auto.DataCallback<GaoBean>(){
@Override
public void getData(GaoBeangaoBean) {
List<GaoBean.InfoBean> infos = gaoBean.getInfo();
Log.i("====","===== gaoinfos "+ infos.toString());
}
},GaoBean.class).execute("http://www.h5151.com/ajax/hd_game/platform=2&compare=af9cd783af6a57e43edeb8bd54421d45");
new MyTextTask_Auto<GiftBean>(newMyTextTask_Auto.DataCallback<GiftBean>(){
@Override
public void getData(GiftBeangiftBean) {
List<GiftBean.ResultBean> infos = giftBean.getResult();
Log.i("====","====="+ infos.toString());
}
},GiftBean.class).execute("http://api.k780.com:88/?app=weather.future&weaid=1&&appkey=10003&sign=b59bc3ef6191eb9f747dd4e83c99f2a4&format=json");
}
}
】