編輯:Android開發實例
前言
上一篇已經介紹了在.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序列化。
在此示例中展示解析四種數據的方式:
從IIS上獲取Json數據的方法,在另外一篇中有介紹:Http協議。這裡方便大家查看:
- package cn.bgxt.http;
- import java.io.ByteArrayOutputStream;
- import java.io.IOException;
- import java.io.InputStream;
- import java.net.HttpURLConnection;
- import java.net.URL;
- import android.util.Log;
- public class HttpUtils {
- public HttpUtils() {
- // TODO Auto-generated constructor stub
- }
- public static String getJsonContent(String url_path)
- {
- try {
- URL url=new URL(url_path);
- HttpURLConnection connection=(HttpURLConnection)url.openConnection();
- connection.setConnectTimeout(3000);
- connection.setRequestMethod("GET");
- connection.setDoInput(true);
- int code=connection.getResponseCode();
- if(200==code)
- {
- return changeJsonString(connection.getInputStream());
- }
- } catch (Exception e) {
- // TODO: handle exception
- Log.i("main", e.getMessage());
- }
- return null;
- }
- private static String changeJsonString(InputStream inputStream) {
- String jsonString="";
- try {
- ByteArrayOutputStream outputStream=new ByteArrayOutputStream();
- int len=0;
- byte[] data=new byte[1024];
- while((len=inputStream.read(data))!=-1)
- {
- outputStream.write(data,0,len);
- }
- jsonString=new String(outputStream.toByteArray());
- } catch (IOException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- return jsonString;
- }
- }
從IIS上獲取到Json數據之後,需要新建一個類來解析服務端獲取到的Json數據:
- package cn.bgxt.jsonUtils;
- import java.util.ArrayList;
- import java.util.HashMap;
- import java.util.List;
- import java.util.Map;
- import org.json.JSONArray;
- import org.json.JSONObject;
- import cn.bgxt.domain.Person;
- public class JsonTools {
- public JsonTools() {
- // TODO Auto-generated constructor stub
- }
- public static Person getPerson(String jsonString)
- {
- Person person=new Person();
- try {
- //一個Json對象,使用JSONObject
- JSONObject jsonObject=new JSONObject(jsonString);
- //對JSONObject對象中直接以key的形式取其Value
- person.setId(jsonObject.getInt("id"));
- person.setName(jsonObject.getString("name"));
- person.setAge(jsonObject.getInt("age"));
- } catch (Exception e) {
- // TODO: handle exception
- }
- return person;
- }
- public static List<Person> getPersonList(String jsonString)
- {
- List<Person> list=new ArrayList<Person>();
- try {
- //最外層是一個數組[],所以使用JSONArray
- JSONArray jsonarr=new JSONArray(jsonString);
- Person person=null;
- for(int i=0;i<jsonarr.length();i++)
- {
- //遍歷數組獲得數組中Json對象。
- person=new Person();
- JSONObject jsonObject= jsonarr.getJSONObject(i);
- //獲取到Json對象,就可以直接通過Key獲取Value
- person.setId(jsonObject.getInt("id"));
- person.setName(jsonObject.getString("name"));
- person.setAge(jsonObject.getInt("age"));
- list.add(person);
- }
- } catch (Exception e) {
- // TODO: handle exception
- }
- return list;
- }
- public static List<String> getStringList(String jsonString)
- {
- List<String> list=new ArrayList<String>();
- try {
- JSONArray jsonArray=new JSONArray(jsonString);
- for(int i =0;i<jsonArray.length();i++)
- {
- String str=jsonArray.getString(i);
- list.add(str);
- }
- } catch (Exception e) {
- // TODO: handle exception
- }
- return list;
- }
- public static List<Map<String, Object>> getMapList(String jsonString)
- {
- List<Map<String, Object>> maps=new ArrayList<Map<String,Object>>();
- try {
- //最外層是一個Json數組
- JSONArray jsonArray=new JSONArray(jsonString);
- for(int i =0;i<jsonArray.length();i++)
- {
- //Json數組中又包含了一個Json數組
- Map<String,Object> map=new HashMap<String, Object>();
- JSONArray mapArray=jsonArray.getJSONArray(i);
- for(int j=0;j<mapArray.length();j++)
- {
- //第二層Json數組中才能取到Json對象,有對象就可以取值。
- JSONObject jsonObject=mapArray.getJSONObject(j);
- String key=jsonObject.getString("Key");
- Object value=jsonObject.get("Value");
- map.put(key, value);
- }
- maps.add(map);
- }
- } catch (Exception e) {
- // TODO: handle exception
- }
- return maps;
- }
- }
再就是在Activity中添加4個按鈕,分別響應這四次解析,布局相對簡單,僅四個按鈕,此處不給出布局代碼,有興趣的可以下載源碼查看。因為是Android4.0+的平台,所以不能在主線程中訪問網絡,需要另起線程,還有別忘記增加訪問網絡的權限。
Activity代碼:
- package cn.bgxt.jsonparser;
- import java.util.List;
- import java.util.Map;
- import cn.bgxt.domain.Person;
- import cn.bgxt.http.HttpUtils;
- import cn.bgxt.jsonUtils.JsonTools;
- import android.os.Bundle;
- import android.app.Activity;
- import android.util.Log;
- import android.view.Menu;
- import android.view.View;
- import android.view.View.OnClickListener;
- import android.widget.Button;
- public class MainActivity extends Activity implements OnClickListener {
- private String path_url = "http://192.168.1.106:1231/json/returnJson.ashx?JsonData=";
- private Button person, personList, stringList, dicList;
- private String path = "";
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_main);
- person = (Button) findViewById(R.id.person);
- personList = (Button) findViewById(R.id.personList);
- stringList = (Button) findViewById(R.id.stringList);
- dicList = (Button) findViewById(R.id.dicList);
- person.setOnClickListener(this);
- personList.setOnClickListener(this);
- stringList.setOnClickListener(this);
- dicList.setOnClickListener(this);
- }
- @Override
- public boolean onCreateOptionsMenu(Menu menu) {
- getMenuInflater().inflate(R.menu.main, menu);
- return true;
- }
- @Override
- public void onClick(View v) {
- switch (v.getId()) {
- case R.id.person:
- Thread thread = new Thread(new Runnable() {
- @Override
- public void run() {
- // TODO Auto-generated method stub
- path = path_url + "Person";
- String jsonString = HttpUtils.getJsonContent(path);
- Person person = JsonTools.getPerson(jsonString);
- Log.i("main", person.toString());
- }
- });
- thread.start();
- break;
- case R.id.personList:
- Thread thread1 = new Thread(new Runnable() {
- @Override
- public void run() {
- // TODO Auto-generated method stub
- path = path_url + "PersonList";
- String jsonString = HttpUtils.getJsonContent(path);
- List<Person> persons = JsonTools.getPersonList(jsonString);
- for(Person p:persons)
- {
- Log.i("main", p.toString());
- }
- }
- });
- thread1.start();
- break;
- case R.id.stringList:
- Thread thread2 = new Thread(new Runnable() {
- @Override
- public void run() {
- // TODO Auto-generated method stub
- path = path_url + "StringList";
- String jsonString = HttpUtils.getJsonContent(path);
- List<String> strings = JsonTools.getStringList(jsonString);
- for(String s:strings)
- {
- Log.i("main", s);
- }
- }
- });
- thread2.start();
- break;
- case R.id.dicList:
- Thread thread3 = new Thread(new Runnable() {
- @Override
- public void run() {
- // TODO Auto-generated method stub
- path = path_url + "DicList";
- String jsonString = HttpUtils.getJsonContent(path);
- List<Map<String, Object>> maps = JsonTools.getMapList(jsonString);
- for(Map<String, Object> m:maps)
- {
- Log.i("main", m.toString());
- }
- }
- });
- thread3.start();
- break;
- }
- }
- }
依次按順序點擊按鈕,可以再LogCat中查看數據:
示例程序下載
總結
本來Java中有一套自己的序列化辦法,序列化出來的Json數據並不是如此的格式,可這裡使用的.Net序列化的辦法,但是參照本文的思想,只要知道Json的格式,無論Json數據變什麼樣子,都是可以解析出來的。真實的Android開發服務端的時候,還是盡量使用Java來開發,減少兼容性的問題。
第一步:代碼混淆(注意引入的第三方jar) 在新版本的ADT創建項目時,混碼的文件不再是proguard.cfg,而是project.properties和pro
當前比較成熟一點的應用基本上都會在進入應用之顯示一個啟動界面.這個啟動界面或簡單,或復雜,或簡陋,或華麗,用意不同,風格也不同.下面來觀摩幾個流行的應用的啟動界面
Android應用程序可以在許多不同地區的許多設備上運行。為了使應用程序更具交互性,應用程序應該處理以適合應用程序將要使用的語言環境方面的文字,數字,文件等。在本章中,我
公司准備要做一個項目,是p2p配資的app。在網上問了一些人後,發現有的是直接有html5做好後,用軟件封裝的。之前我學過app的開發,當時Android版本的,