首页 > 系统 > Android > 正文

Android:解析JSON的三种方式

2019-11-06 09:43:03
字体:
来源:转载
供稿:网友

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


发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表