Android:解析JSON的三种方式

转载自:[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<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中用到的异常
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值