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來開發,減少兼容性的問題。

  請支持原創,尊重原創,轉載請注明出處。謝謝。

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM