转载自:[https://blog.csdn.net/abbydream/article/details/58588076]

什么是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 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的长度                        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 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 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中用到的异常

更多相关文章

  1. SpringBoot 2.0 中 HikariCP 数据库连接池原理解析
  2. 一句话锁定MySQL数据占用元凶
  3. Android集成百度定位SDK实现获取定位地址
  4. Android(安卓)安卓MVC架构
  5. SystemServer(一):恢复出厂设置后wifi、数据流量、gps设置关闭
  6. Android(安卓)ListView列表视图的使用方法
  7. Android中EditText控件的几种使用方法
  8. Android6.0(包括)以后获取Wifi 扫描信息列表即getScanResults()
  9. Android中获取字符串长度、宽度(所占像素宽度)

随机推荐

  1. 大数据和Android
  2. Android(安卓)DexHelper帮你解决65536问
  3. Android(安卓)WebViewClient 处理跳转URL
  4. Android(安卓)P 开发者预览版支持 DNS ov
  5. android studio 学习入门篇(转载)
  6. android的touch事件分发响应机制
  7. android菜单中的见解
  8. Android(安卓)将自己写的android library
  9. Drawable专讲 Android
  10. Android(安卓)DataBinding