赞
踩
什么是Json?
Json(Javascript Object Notation):Javascript对象表示法。是一种轻量级的数据交换格式,相比于xml这种数据交换格式来说,因为解析xml比较的复杂,而且需要编写大段的代码,所以客户端和服务器的数据交换格式往往通过Json来进行交换。
Json一共有两种数据结构:
1、一种是以 (key/value)对形式存在的无序的jsonObject对象,一个对象以“{”(左花括号)开始,“}”(右花括号)结束。每个“名称”后跟一个“:”(冒号);“‘名称/值’ 对”之间使用“,”(逗号)分隔。
2、另一种数据格式就是有序的value的集合,这种形式被称为是jsonArray集合,数组是值(value)的有序集合。一个数组以“[”(左中括号)开始,“]”(右中括号)结束。值之间使用“,”(逗号)分隔。
{}双括号表示对象;
[]中括号表示数组;
" " 双引号内是属性或值;
: 冒号表示后者是前者的值(这个值可以是字符串、数字、也可以是另一个数组或对象);
所以 {"name": "Michael"} 可以理解为是一个包含name为Michael的对象;
而[{"name": "Michael"},{"name": "Jerry"}]就表示包含两个对象的数组。
当然了,你也可以使用{"name":["Michael","Jerry"]}来简化上面一部,这是一个拥有一个name数组的对象。
下面通过解析Json的三种方式来实现在Android客户端和服务器端使用json这种数据格式来进行数据的交换。
一、解析JSON之使用原生态解析
Android客户端通过一个AsyncTask异步任务请求服务器端的某些数据,AsyncTask两个方法(1)获取网络数据:doInBackground();(2)更新UI(数据):onPostExecute()。在解析完这些数据后,onPostExecute()方法会将解析的数据内容更新到适配器,通知适配器发送改变。代码注释如下:
- public class JsonActivity extends AppCompatActivity {
-
- private ListView lv_main_jsondata;
- private List<UserEntity> list=new ArrayList<>();//定义一个对象集合
- private ProgressDialog progress;
- private JsonActivity.myAdapter myAdapter;
-
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_json);
- lv_main_jsondata = (ListView) findViewById(R.id.lv_main_jsondata);//获取listview控件
- myAdapter = new myAdapter();//实列化对象
- //给listview一个适配器,需要自己写一个类继承BaseAdapter
- lv_main_jsondata.setAdapter(myAdapter);
- //增加动画加载效果
- progress = new ProgressDialog(this);
- progress.setMessage("locating.....");//获取动画加载消息内容
-
- }
- //1、写一个类继承BaseAdapter,重写它的四个方法
- class myAdapter extends BaseAdapter{
- @Override
- public int getCount() {//获取总数量
- return list.size();
- }
- @Override
- public Object getItem(int position) {//获取当前位置
- return list.get(position);
- }
- @Override
- public long getItemId(int position) {//获取当前位置的ID
- return position;
- }
- @Override
- public View getView(int position, View convertView, ViewGroup parent) {//获取视图
- if (convertView==null){
- convertView= LayoutInflater.from(JsonActivity.this).inflate(R.layout.dom_listview,null);
- DomActivity activity=new DomActivity();//实列化一个对象
- //将对象的属性增加到相对应的控件中
- activity.uname= (TextView) convertView.findViewById(R.id.tv_listview_one);
- activity.content= (TextView) convertView.findViewById(R.id.tv_listview_two);
- activity.anthour= (TextView) convertView.findViewById(R.id.tv_listview_three);
- convertView.setTag(activity);//获取标签
- }
- DomActivity domActivity= (DomActivity) convertView.getTag();//通过convertView得到标签
- //获取对象的属性,将每个属性增加到它相对应的位置
- domActivity.uname.setText(list.get(position).getUname());
- domActivity.content.setText(list.get(position).getContent());
- domActivity.anthour.setText(list.get(position).getAnthour());
- return convertView;
- }
- }
- //获取Json数据
- public void getjson(View view){
- progress.show();//更新数据之前增加动画加载
- new myTask().execute();
-
- }
- //1、写一个类继承AsyncTask,重写它的两个方法
- // <1、获取网络数据:doInBackground
- // <2、更新UI(数据):onPostExecute
- class myTask extends AsyncTask{
-
- private StringBuffer stringBuffer;
-
- //获取网络数据:doInBackground
- @Override
- protected Object doInBackground(Object[] params) {
- //(1)、获得数据路径
- String path=getString(R.string.path)+"android_json.xhtml";
- try {
- //(2)、实例化url:将获取网络数据的路径放到URL中。
- URL url=new URL(path);
- //(3)/通过URL获取连接的对象
- HttpURLConnection httpURLConnection= (HttpURLConnection) url.openConnection();
- //(4)、设置参数 01请求的方式:1、get;2、post; 02设置请求时间
- httpURLConnection.setRequestMethod("GET");
- httpURLConnection.setConnectTimeout(5000);
- //(5)、判断响应码是否是200 是的话就请求到数据
- if (httpURLConnection.getResponseCode()==200){//如果请求到的响应码是200 那么就要去读取它的数据
- InputStream inputStream=httpURLConnection.getInputStream();//以字节流的形式得到数据
- //通过字符流(bufferedread)的形式读取数据
- BufferedReader bufferedReader=new BufferedReader(new InputStreamReader(inputStream));//将字符流转成字节流
- //实列化一个对象
- stringBuffer = new StringBuffer();
- String str=null;//定义一个接收的字符串
- while((str=bufferedReader.readLine())!=null){//字符流读取数据不为空
- stringBuffer.append(str);//把字符流读取的数据增加到对象中
- }
- Log.i("test", "doInBackground: "+ stringBuffer.toString());
- }
- //解析JSON
- try {
- // 一、使用原生态解析
- //1、通过jsonobject对象获取数据
- JSONObject jsonObject=new JSONObject(stringBuffer.toString());
- //2、获取数据的属性
- String clazz=jsonObject.getString("class");
- Log.i("test", "doInBackground: "+clazz);
- int munber=jsonObject.getInt("lists");//获取它的数量
- Log.i("test", "doInBackground: "+munber);
- //3、获取集合的属性
- JSONArray array= jsonObject.getJSONArray("fqs");
- for (int i = 0; i <array.length() ; i++) {//循环获取array的长度
- JSONObject object= array.getJSONObject(i);//拿到每一个对象
- //通过对象获取每个属性
- String name=object.getString("name");
- String content=object.getString("content");
- String anthour=object.getString("anthour");
- UserEntity user=new UserEntity(name,content,anthour);//实列化一个对象,每循环一次实列化一次
- list.add(user);
-
-
-
- }
-
-
- } catch (JSONException e) {
- e.printStackTrace();
- }
-
-
- } catch (MalformedURLException e) {
- e.printStackTrace();
- } catch (IOException e) {
- e.printStackTrace();
- }
- return null;
- }
- //更新UI(数据):onPostExecute
- @Override
- protected void onPostExecute(Object o) {
- myAdapter.notifyDataSetChanged();//通知适配器数据发生改变
- progress.cancel();//动画取消
- super.onPostExecute(o);
- }
- }
- }

二、解析JSON之GSON解析
使用Gson解析需要去下载Gson这个jar包,导入到我们的项目中。用Gson,我们可以非常轻松的实现数据对象和json对象的相互转化,其中我们最常用的方法fromJSON(),将json对象转换成我们需要的数据对象。代码注释如下:
- public class JsonActivity extends AppCompatActivity {
-
- private ListView lv_main_jsondata;
- private List<UserEntity> list=new ArrayList<>();//定义一个对象集合
- private ProgressDialog progress;
- private JsonActivity.myAdapter myAdapter;
-
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_json);
- lv_main_jsondata = (ListView) findViewById(R.id.lv_main_jsondata);//获取listview控件
- myAdapter = new myAdapter();//实列化对象
- //给listview一个适配器,需要自己写一个类继承BaseAdapter
- lv_main_jsondata.setAdapter(myAdapter);
- //增加动画加载效果
- progress = new ProgressDialog(this);
- progress.setMessage("locating.....");//获取动画加载消息内容
-
- }
- //1、写一个类继承BaseAdapter,重写它的四个方法
- class myAdapter extends BaseAdapter{
- @Override
- public int getCount() {//获取总数量
- return list.size();
- }
- @Override
- public Object getItem(int position) {//获取当前位置
- return list.get(position);
- }
- @Override
- public long getItemId(int position) {//获取当前位置的ID
- return position;
- }
- @Override
- public View getView(int position, View convertView, ViewGroup parent) {//获取视图
- if (convertView==null){
- convertView= LayoutInflater.from(JsonActivity.this).inflate(R.layout.dom_listview,null);
- DomActivity activity=new DomActivity();//实列化一个对象
- //将对象的属性增加到相对应的控件中
- activity.uname= (TextView) convertView.findViewById(R.id.tv_listview_one);
- activity.content= (TextView) convertView.findViewById(R.id.tv_listview_two);
- activity.anthour= (TextView) convertView.findViewById(R.id.tv_listview_three);
- convertView.setTag(activity);//获取标签
- }
- DomActivity domActivity= (DomActivity) convertView.getTag();//通过convertView得到标签
- //获取对象的属性,将每个属性增加到它相对应的位置
- domActivity.uname.setText(list.get(position).getUname());
- domActivity.content.setText(list.get(position).getContent());
- domActivity.anthour.setText(list.get(position).getAnthour());
- return convertView;
- }
- }
- //获取Json数据
- public void getjson(View view){
- progress.show();//更新数据之前增加动画加载
- new myTask().execute();
-
- }
- //1、写一个类继承AsyncTask,重写它的两个方法
- // <1、获取网络数据:doInBackground
- // <2、更新UI(数据):onPostExecute
- class myTask extends AsyncTask{
-
- private StringBuffer stringBuffer;
-
- //获取网络数据:doInBackground
- @Override
- protected Object doInBackground(Object[] params) {
- //(1)、获得数据路径
- String path=getString(R.string.path)+"android_json.xhtml";
- try {
- //(2)、实例化url:将获取网络数据的路径放到URL中。
- URL url=new URL(path);
- //(3)/通过URL获取连接的对象
- HttpURLConnection httpURLConnection= (HttpURLConnection) url.openConnection();
- //(4)、设置参数 01请求的方式:1、get;2、post; 02设置请求时间
- httpURLConnection.setRequestMethod("GET");
- httpURLConnection.setConnectTimeout(5000);
- //(5)、判断响应码是否是200 是的话就请求到数据
- if (httpURLConnection.getResponseCode()==200){//如果请求到的响应码是200 那么就要去读取它的数据
- InputStream inputStream=httpURLConnection.getInputStream();//以字节流的形式得到数据
- //通过字符流(bufferedread)的形式读取数据
- BufferedReader bufferedReader=new BufferedReader(new InputStreamReader(inputStream));//将字符流转成字节流
- //实列化一个对象
- stringBuffer = new StringBuffer();
- String str=null;//定义一个接收的字符串
- while((str=bufferedReader.readLine())!=null){//字符流读取数据不为空
- stringBuffer.append(str);//把字符流读取的数据增加到对象中
- }
- Log.i("test", "doInBackground: "+ stringBuffer.toString());
- }
- //解析JSON
- //二、使用Gson解析Json
- Gson gson=new Gson();//实列化一个对象
- //通过gson解析一个对象,将buffered流解析到a对象中
- BigjsonActivity bjson=gson.fromJson(stringBuffer.toString(),BigjsonActivity.class);
- //通过对象获取这个对象中相对应的属性
- String clazz=bjson.getClazz();
- int munber=bjson.getLists();
- Log.i("test", "doInBackground: "+clazz+" ;"+munber);
- list.addAll(bjson.getListuser());//将对象中的集合放入list对象集合中
-
- } catch (MalformedURLException e) {
- e.printStackTrace();
- } catch (IOException e) {
- e.printStackTrace();
- }
- return null;
- }
- //更新UI(数据):onPostExecute
- @Override
- protected void onPostExecute(Object o) {
- myAdapter.notifyDataSetChanged();//通知适配器数据发生改变
- progress.cancel();//动画取消
- super.onPostExecute(o);
- }
- }
- }

三、解析JSON之FastJson解析
使用FastJson需要导入第三方包,用法和Gson一样,实现数据对象和json对象的相互转化Gson是用fromJSON()方法,而FastJson用JSON.parseObject()方法,然后将json对象中的集合放入我们需要的数据对象集合中。代码注释如下:
- public class JsonActivity extends AppCompatActivity {
-
- private ListView lv_main_jsondata;
- private List<UserEntity> list=new ArrayList<>();//定义一个对象集合
- private ProgressDialog progress;
- private JsonActivity.myAdapter myAdapter;
-
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_json);
- lv_main_jsondata = (ListView) findViewById(R.id.lv_main_jsondata);//获取listview控件
- myAdapter = new myAdapter();//实列化对象
- //给listview一个适配器,需要自己写一个类继承BaseAdapter
- lv_main_jsondata.setAdapter(myAdapter);
- //增加动画加载效果
- progress = new ProgressDialog(this);
- progress.setMessage("locating.....");//获取动画加载消息内容
-
- }
- //1、写一个类继承BaseAdapter,重写它的四个方法
- class myAdapter extends BaseAdapter{
- @Override
- public int getCount() {//获取总数量
- return list.size();
- }
- @Override
- public Object getItem(int position) {//获取当前位置
- return list.get(position);
- }
- @Override
- public long getItemId(int position) {//获取当前位置的ID
- return position;
- }
- @Override
- public View getView(int position, View convertView, ViewGroup parent) {//获取视图
- if (convertView==null){
- convertView= LayoutInflater.from(JsonActivity.this).inflate(R.layout.dom_listview,null);
- DomActivity activity=new DomActivity();//实列化一个对象
- //将对象的属性增加到相对应的控件中
- activity.uname= (TextView) convertView.findViewById(R.id.tv_listview_one);
- activity.content= (TextView) convertView.findViewById(R.id.tv_listview_two);
- activity.anthour= (TextView) convertView.findViewById(R.id.tv_listview_three);
- convertView.setTag(activity);//获取标签
- }
-
- DomActivity domActivity= (DomActivity) convertView.getTag();//通过convertView得到标签
- //获取对象的属性,将每个属性增加到它相对应的位置
- domActivity.uname.setText(list.get(position).getUname());
- domActivity.content.setText(list.get(position).getContent());
- domActivity.anthour.setText(list.get(position).getAnthour());
- return convertView;
- }
- }
- //获取Json数据
- public void getjson(View view){
- progress.show();//更新数据之前增加动画加载
- new myTask().execute();
-
- }
- //1、写一个类继承AsyncTask,重写它的两个方法
- // <1、获取网络数据:doInBackground
- // <2、更新UI(数据):onPostExecute
- class myTask extends AsyncTask{
-
- private StringBuffer stringBuffer;
-
- //获取网络数据:doInBackground
- @Override
- protected Object doInBackground(Object[] params) {
- //(1)、获得数据路径
- String path=getString(R.string.path)+"android_json.xhtml";
- try {
- //(2)、实例化url:将获取网络数据的路径放到URL中。
- URL url=new URL(path);
- //(3)/通过URL获取连接的对象
- HttpURLConnection httpURLConnection= (HttpURLConnection) url.openConnection();
- //(4)、设置参数 01请求的方式:1、get;2、post; 02设置请求时间
- httpURLConnection.setRequestMethod("GET");
- httpURLConnection.setConnectTimeout(5000);
- //(5)、判断响应码是否是200 是的话就请求到数据
- if (httpURLConnection.getResponseCode()==200){//如果请求到的响应码是200 那么就要去读取它的数据
- InputStream inputStream=httpURLConnection.getInputStream();//以字节流的形式得到数据
- //通过字符流(bufferedread)的形式读取数据
- BufferedReader bufferedReader=new BufferedReader(new InputStreamReader(inputStream));//将字符流转成字节流
- //实列化一个对象
- stringBuffer = new StringBuffer();
- String str=null;//定义一个接收的字符串
- while((str=bufferedReader.readLine())!=null){//字符流读取数据不为空
- stringBuffer.append(str);//把字符流读取的数据增加到对象中
- }
- Log.i("test", "doInBackground: "+ stringBuffer.toString());
- }
- //解析JSON
- //三、使用FsatJson解析
- //通过json解析一个对象,将buffered流解析到对象中
- BigjsonActivity bjson =JSON.parseObject(stringBuffer.toString(),BigjsonActivity.class);
- //通过对象获取这个对象中相对应的属性
- String clazz=bjson.getClazz();
- int munber=bjson.getLists();
- Log.i("test", "doInBackground: "+clazz+" ;"+munber);
- list.addAll(bjson.getFqs());//将对象中的集合放入list对象集合中
-
-
- } catch (MalformedURLException e) {
- e.printStackTrace();
- } catch (IOException e) {
- e.printStackTrace();
- }
- return null;
- }
- //更新UI(数据):onPostExecute
- @Override
- protected void onPostExecute(Object o) {
- myAdapter.notifyDataSetChanged();//通知适配器数据发生改变
- progress.cancel();//动画取消
- super.onPostExecute(o);
- }
- }
- }

总结:
JSON对于移动设备来说,尤其对于网络环境较差和流量限制的情况下,相对于XML格式的数据传输会更节省流量,传输效率更高。在这三种解析方式中FastJson是效率最高的。
Android的JSON解析部分都在包org.json下,主要有以下几个类:
《1、JSONObject:可以看作是一个json对象,这是系统中有关JSON定义的基本单元,其包含一对儿(Key/Value)数值。它对外部(External:应用toString()方法输出的数值)调用的响应体现为一个标准的字符串(例如:{"JSON": "Hello, World"},最外被大括号包裹,其中的Key和Value被冒号":"分隔)。其对于内部(Internal)行为的操作格式略微,例如:初始化一个JSONObject实例,引用内部的put()方法添加数值:new JSONObject().put("JSON", "Hello, World!"),在Key和Value之间是以逗号","分隔。Value的类型包括:Boolean、JSONArray、JSONObject、Number、String或者默认值JSONObject.NULL object。
《2、JSONStringer:json文本构建类 ,根据官方的解释,这个类可以帮助快速和便捷的创建JSON text。其最大的优点在于可以减少由于 格式的错误导致程序异常,引用这个类可以自动严格按照JSON语法规则(syntax rules)创建JSON text。每个JSONStringer实体只能对应创建一个JSON text。。其最大的优点在于可以减少由于格式的错误导致程序异常,引用这个类可以自动严格按照JSON语法规则(syntax rules)创建JSON text。每个JSONStringer实体只能对应创建一个JSON text。
《3、JSONArray:它代表一组有序的数值。将其转换为String输出(toString)所表现的形式是用方括号包裹,数值以逗号”,”分隔(例如:[value1,value2,value3],大家可以亲自利用简短的代码更加直观的了解其格式)。这个类的内部同样具有查询行为,get()和opt()两种方法都可以通过index索引返回指定的数值,put()方法用来添加或者替换数值。同样这个类的value类型可以包括:Boolean、JSONArray、JSONObject、Number、String或者默认JSONObject.NULL object。
《4、JSONTokener:json解析类。
《5、JSONException:json中用到的异常
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。