前言
上一篇博客已经介绍了在.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来开发,减少兼容性的问题。
本文转自承香墨影博客园博客,原文链接:http://www.cnblogs.com/plokmju/p/android_JsonParser.html,如需转载请自行联系原作者