Android--Json解析

前言

  上一篇博客已经介绍了在.Net下如何把对象序列化成Json字符串和Json数据的格式。如果不清楚的朋友可以过去看看:对象转Json序列化。这篇博客就来聊聊在Android平台下如何解析Json数据。

org.json

  我们知道,Json有两种格式,键值对和数组,而Android对于Json的支持源于org.json包下的几个类。org.json下一共有四个类,但是经常使用的也就是两个类,分别对应了键值对和数组:JSONObject、JSONArray,弄清楚这两个类,基本上就了解了在Android下解析Json的方式。

  对于这两个类的选择使用,其实可以简单的区分,如果是被包括在方括号"[]"内的Json数据,则使用JSONArray对象存放数据。如果是被包括在花括号"{}"内的Json数据,则使用JSONObject对象存放数据。

  如上图,对于上面这个Json数据,解析的思路是先使用JSONArray解析Json数组,再遍历这个Json数组,使用JSONObject解析这个Json数组中的每个Json对象。

示例程序

  JSONObject、JSONArray提供了一系列getXxx()的方法,获取其内部的值。下面就通过一个例子来讲解一下Android应用程序中解析Json的方法。

  这个例子模拟现实情况,访问IIS上一个一般处理程序,通过不同的GET参数,返回不同的Json数据,具体数据的返回情况参见上一篇博客对象转Json序列化

  在此示例中展示解析四种数据的方式:

  • Person:{"age":24,"id":20,"name":"slive"}
  • List<Person>:[{"age":24,"id":20,"name":"slive"},{"age":34,"id":30,"name":"jack"},{"age":54,"id":40,"name":"damon"}]
  • List<string>:["jack","dick","sean"]
  • List<Map<String,Object>>:[[{"Key":"id","Value":17},{"Key":"name","Value":"jerry"},{"Key":"age","Value":24}],[{"Key":"id","Value":18},{"Key":"name","Value":"meimei"},{"Key":"age","Value":23}],[{"Key":"id","Value":19},{"Key":"name","Value":"damon"},{"Key":"age","Value":28}]]

  从IIS上获取Json数据的方法,在另外一篇博客中有介绍:Http协议。这里方便大家查看:

 1 package cn.bgxt.http;
 2 
 3 import java.io.ByteArrayOutputStream;
 4 import java.io.IOException;
 5 import java.io.InputStream;
 6 import java.net.HttpURLConnection;
 7 import java.net.URL;
 8 import android.util.Log;
 9 
10 public class HttpUtils {
11     public HttpUtils() {
12         // TODO Auto-generated constructor stub
13     }    
14     public static String getJsonContent(String url_path)
15     {
16         try {
17             URL url=new URL(url_path);
18             HttpURLConnection connection=(HttpURLConnection)url.openConnection();
19             connection.setConnectTimeout(3000);
20             connection.setRequestMethod("GET");
21             connection.setDoInput(true);
22             int code=connection.getResponseCode();
23             if(200==code)
24             {
25                 return changeJsonString(connection.getInputStream());
26             }
27         } catch (Exception e) {
28             // TODO: handle exception
29             Log.i("main", e.getMessage());
30         }
31         return null;
32     }
33 
34     private static String changeJsonString(InputStream inputStream) {
35         String jsonString="";
36         try {            
37             ByteArrayOutputStream outputStream=new ByteArrayOutputStream();
38             int len=0;
39             byte[] data=new byte[1024];
40             while((len=inputStream.read(data))!=-1)
41             {
42                 outputStream.write(data,0,len);
43             }
44             jsonString=new String(outputStream.toByteArray());
45         } catch (IOException e) {
46             // TODO Auto-generated catch block
47             e.printStackTrace();
48         }
49         return jsonString;
50     }
51 }

   从IIS上获取到Json数据之后,需要新建一个类来解析服务端获取到的Json数据:

  1 package cn.bgxt.jsonUtils;
  2 
  3 import java.util.ArrayList;
  4 import java.util.HashMap;
  5 import java.util.List;
  6 import java.util.Map;
  7 
  8 import org.json.JSONArray;
  9 import org.json.JSONObject;
 10 
 11 import cn.bgxt.domain.Person;
 12 
 13 public class JsonTools {
 14 
 15     public JsonTools() {
 16         // TODO Auto-generated constructor stub
 17     }
 18     
 19     public static Person getPerson(String jsonString)
 20     {
 21         Person person=new Person();
 22         try {
 23             //一个Json对象,使用JSONObject
 24             JSONObject jsonObject=new JSONObject(jsonString);
 25             //对JSONObject对象中直接以key的形式取其Value
 26             person.setId(jsonObject.getInt("id"));
 27             person.setName(jsonObject.getString("name"));
 28             person.setAge(jsonObject.getInt("age"));
 29         } catch (Exception e) {
 30             // TODO: handle exception
 31         }        
 32         return person;
 33     }
 34     
 35     public static List<Person> getPersonList(String jsonString)
 36     {
 37         List<Person> list=new ArrayList<Person>();
 38         try {
 39             //最外层是一个数组[],所以使用JSONArray
 40             JSONArray jsonarr=new JSONArray(jsonString);
 41             Person person=null;            
 42             for(int i=0;i<jsonarr.length();i++)
 43             {
 44                 //遍历数组获得数组中Json对象。
 45                 person=new Person();
 46                 JSONObject jsonObject= jsonarr.getJSONObject(i);
 47                 //获取到Json对象,就可以直接通过Key获取Value
 48                 person.setId(jsonObject.getInt("id"));
 49                 person.setName(jsonObject.getString("name"));
 50                 person.setAge(jsonObject.getInt("age"));
 51                 list.add(person);
 52             }
 53         } catch (Exception e) {
 54             // TODO: handle exception
 55         }
 56         return list;
 57     
 58     }
 59     
 60     public static List<String> getStringList(String jsonString)
 61     {
 62         List<String> list=new ArrayList<String>();
 63         try {
 64             JSONArray jsonArray=new JSONArray(jsonString);
 65             for(int i =0;i<jsonArray.length();i++)
 66             {
 67                 String str=jsonArray.getString(i);
 68                 list.add(str); 
 69             }
 70         } catch (Exception e) {
 71             // TODO: handle exception
 72         }
 73         return list;        
 74     }
 75     
 76     public static List<Map<String, Object>> getMapList(String jsonString)
 77     {
 78         List<Map<String, Object>> maps=new ArrayList<Map<String,Object>>();
 79         try {
 80             //最外层是一个Json数组
 81             JSONArray jsonArray=new JSONArray(jsonString);
 82             for(int i =0;i<jsonArray.length();i++)
 83             {
 84                 //Json数组中又包含了一个Json数组
 85                 Map<String,Object> map=new HashMap<String, Object>();
 86                 JSONArray mapArray=jsonArray.getJSONArray(i);
 87                 for(int j=0;j<mapArray.length();j++)
 88                 {
 89                     //第二层Json数组中才能取到Json对象,有对象就可以取值。
 90                     JSONObject jsonObject=mapArray.getJSONObject(j);
 91                     String key=jsonObject.getString("Key");
 92                     Object value=jsonObject.get("Value");
 93                     map.put(key, value);                    
 94                 }
 95                 maps.add(map);
 96             }
 97         } catch (Exception e) {
 98             // TODO: handle exception
 99         }
100         return maps;
101         
102     }
103     
104     
105 }

  再就是在Activity中添加4个按钮,分别响应这四次解析,布局相对简单,仅四个按钮,此处不给出布局代码,有兴趣的可以下载源码查看。因为是Android4.0+的平台,所以不能在主线程中访问网络,需要另起线程,还有别忘记增加访问网络的权限。

  Activity代码:

  1 package cn.bgxt.jsonparser;
  2 
  3 import java.util.List;
  4 import java.util.Map;
  5 
  6 import cn.bgxt.domain.Person;
  7 import cn.bgxt.http.HttpUtils;
  8 import cn.bgxt.jsonUtils.JsonTools;
  9 import android.os.Bundle;
 10 import android.app.Activity;
 11 import android.util.Log;
 12 import android.view.Menu;
 13 import android.view.View;
 14 import android.view.View.OnClickListener;
 15 import android.widget.Button;
 16 
 17 public class MainActivity extends Activity implements OnClickListener {
 18 
 19     private String path_url = "http://192.168.1.106:1231/json/returnJson.ashx?JsonData=";
 20     private Button person, personList, stringList, dicList;
 21     private String path = "";
 22 
 23     @Override
 24     protected void onCreate(Bundle savedInstanceState) {
 25         super.onCreate(savedInstanceState);
 26         setContentView(R.layout.activity_main);
 27 
 28         person = (Button) findViewById(R.id.person);
 29         personList = (Button) findViewById(R.id.personList);
 30         stringList = (Button) findViewById(R.id.stringList);
 31         dicList = (Button) findViewById(R.id.dicList);
 32         person.setOnClickListener(this);
 33         personList.setOnClickListener(this);
 34         stringList.setOnClickListener(this);
 35         dicList.setOnClickListener(this);
 36     }
 37 
 38     @Override
 39     public boolean onCreateOptionsMenu(Menu menu) {
 40         getMenuInflater().inflate(R.menu.main, menu);
 41         return true;
 42     }
 43 
 44     @Override
 45     public void onClick(View v) {
 46 
 47         switch (v.getId()) {
 48         case R.id.person:
 49             Thread thread = new Thread(new Runnable() {
 50 
 51                 @Override
 52                 public void run() {
 53                     // TODO Auto-generated method stub
 54                     path = path_url + "Person";
 55                     String jsonString = HttpUtils.getJsonContent(path);
 56                     Person person = JsonTools.getPerson(jsonString);
 57                     Log.i("main", person.toString());
 58                 }
 59             });
 60             thread.start();
 61             break;
 62         case R.id.personList:
 63             Thread thread1 = new Thread(new Runnable() {
 64                 @Override
 65                 public void run() {
 66                     // TODO Auto-generated method stub
 67                     path = path_url + "PersonList";
 68                     String jsonString = HttpUtils.getJsonContent(path);
 69                     List<Person> persons = JsonTools.getPersonList(jsonString);
 70                     for(Person p:persons)
 71                     {
 72                         Log.i("main",  p.toString());
 73                     }                    
 74                 }
 75             });
 76             thread1.start();
 77             break;
 78         case R.id.stringList:
 79             Thread thread2 = new Thread(new Runnable() {
 80                 @Override
 81                 public void run() {
 82                     // TODO Auto-generated method stub
 83                     path = path_url + "StringList";
 84                     String jsonString = HttpUtils.getJsonContent(path);
 85                     List<String> strings = JsonTools.getStringList(jsonString);
 86                     for(String s:strings)
 87                     {
 88                         Log.i("main",  s);
 89                     }                    
 90                 }
 91             });
 92             thread2.start();
 93             break;
 94         case R.id.dicList:
 95             Thread thread3 = new Thread(new Runnable() {
 96                 @Override
 97                 public void run() {
 98                     // TODO Auto-generated method stub
 99                     path = path_url + "DicList";
100                     String jsonString = HttpUtils.getJsonContent(path);
101                     List<Map<String, Object>> maps = JsonTools.getMapList(jsonString);
102                     for(Map<String, Object> m:maps)
103                     {
104                         Log.i("main",  m.toString());
105                     }                    
106                 }
107             });
108             thread3.start();
109             break;
110         }
111 
112     }
113 
114 }

  依次按顺序点击按钮,可以再LogCat中查看数据:

  示例程序下载

总结

  本来Java中有一套自己的序列化办法,序列化出来的Json数据并不是如此的格式,可这里使用的.Net序列化的办法,但是参照本文的思想,只要知道Json的格式,无论Json数据变什么样子,都是可以解析出来的。真实的Android开发服务端的时候,还是尽量使用Java来开发,减少兼容性的问题。

  请支持原创,尊重原创,转载请注明出处。谢谢。

 

 

posted @ 2013-06-25 22:00  承香墨影  阅读(4803)  评论(0编辑  收藏  举报