javascript
android JSONObject的使用
今天,簡單講講android里如何使用
JSONObject。
昨天,自己使用JSONObject構造json數據時,居然發現構造6個之后,json數據就沒有構造進json的括號里,當時是用Debug進行調試,所以百思不得其解。在網上查了資料,也沒有明白,后來發現用log打印的json數據是正確的,是debug顯示的問題。所以這里還是記錄一下JSONObject的使用,避免以后出現這樣的問題。
Android之JSON全面解析與使用
什么是JSON
- JSON 指的是 JavaScript 對象表示法(JavaScript Object Notation)
- JSON 是輕量級的文本數據交換格式
- JSON 獨立于語言 (單純的數據格式,不受語言的約束)
- JSON 具有自我描述性,更易理解
對于JSON的定義以及數據格式,沒有什么太多的難點,這里為官網對JSON的定義。從官網描述中可以看出,JSON本身是JavaScript中對象的描述格式,后來得以推廣并逐漸取代xml。
JSON和XML的比較
相比 XML 的不同之處
- 沒有結束標簽(類似于鍵值對的形式)
- 更短(沒有結束標簽,當然短了)
- 讀寫的速度更快
- 能夠使用內建的 JavaScript eval() 方法進行解析
- 使用數組
- 不使用保留字
原生JSON解析
Android原生的解析實際上使用的JSON的一個官方jar包。對于JSON,不需要頁面展示,所以使用intellij idea進行演示。
在使用之前我們需要下載org.json的jar包。對于Android 開發環境不需要下載此jar包。因為Android SDK 中已經默認包含了該jar包。
json jar 下載地址
下載完之后導入即可。
JSONObject對象解析
下面看一下數據
{"user":{"name":"alex","age":"18","isMan":true} }
有一個user字段,其中包含了該user的一些基本屬性。那么如何解析呢?
在解析時,有一個很關鍵的地方:如果是{}包含,則為JSONObject對象,如果為[]則為JSONArray對象。
看到上面的例子,我們看到整個數據為JSONObject,其內部包含了一個user字段,該字段的值也是一個JSONObject對象。
public class OrgJSONTest {public static String json = "{\"user\":{\"name\":\"alex\",\"age\":\"18\",\"isMan\":true}}";public static void main(String[] args){JSONObject obj = new JSONObject(json);//最外層的JSONObject對象JSONObject user = obj.getJSONObject("user");//通過user字段獲取其所包含的JSONObject對象String name = user.getString("name");//通過name字段獲取其所包含的字符串System.out.println(name);} }
打印結果如下
alex可以看到獲取到了相應的值。
在JSONObject對象中封裝了getXXX()等一系列方法。用以獲取字符串,整形等等一系列的值。
對于如上例子,完全解析user對象如下
結果如下
name:alex age:18 isMan:true
這種通過getXXX的方式,無疑會出現一些問題,我們開始一一嘗試。
getXXX方法獲取的類型不符
- 字符串類型轉整形
對于上面的例子,我們可以看到age字段雖然其對應的值是雙引號括起的字符串,但其實際上是一個整形,那么我們是否能夠通過getInt獲取整形呢。
? int age = user.getInt("age");
?? age:18
當然是可以得,同時字符串類型可以轉化為布爾類型,整數類型,浮點型等等。但字符串的內容必須符合規范,否則會報異常。如果看其源碼可知,其內部實質是調用了對應對象的parseXXX()方法進行轉化操作。
//getInt源碼public int getInt(String key) throws JSONException {Object object = this.get(key);try {//關鍵點,如果是數值類型,則調用intValue(),否則強轉成字符串之后調用parserInt方法()return object instanceof Number?((Num,ber)object).intValue():Integer.parseInt((String)object);} catch (Exception var4) {throw new JSONException("JSONObject[" + quote(key) + "] is not an int.");}}
- 整形等轉字符串類型
按照如上的思維邏輯,直接getString("xxx")就可以了。但事實正好相反,該方法,如果對應值不是雙引號括起的,則會拋出異常。
//getString 源碼public String getString(String key) throws JSONException {Object object = this.get(key);//直接判斷是否是字符串類型,如果不是,則拋出異常if(object instanceof String) {return (String)object;} else {throw new JSONException("JSONObject[" + quote(key) + "] not a string.");}}
getXXX(“”) 沒有對應的鍵值
通過上面的例子,可以得知getXXX("")方法是通過字段(鍵)獲取對應的值。那么肯定存在一種情況,及沒有鍵的存在。
System.out.println(user.getString("sex"));
Exception in thread "main" org.json.JSONException: JSONObject["sex"] not found.at org.json.JSONObject.get(JSONObject.java:471)at org.json.JSONObject.getString(JSONObject.java:717)at json.OrgJSONTest.main(OrgJSONTest.java:24)
果斷報異常。
那么怎么辦呢:使用optXXX()。
這里簡單講解了JSONObject解析字符串,下面具體舉一個例子:
實驗要求,創建以下的JSON數據并對其進行解析顯示到TextView組件中:
{
?? ?"cat":"it",
?? ?"languages":[
?? ??? ?{"id":1,"ide":"Eclipse","name":"Java"},
?? ??? ?{"id":2,"ide":"XCode","name":"Swift"},
?? ??? ?{"id":3,"ide":"Visual Studio","name":"C#"}
?? ?]
}
下面先創建一個空的項目,然對activity_main.xml和MainActivity.java進行編輯
activity_main.xml代碼:
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"xmlns:tools="http://schemas.android.com/tools"android:layout_width="match_parent"android:layout_height="match_parent"android:orientation="vertical"tools:context="com.oak.d4_json.MainActivity"><Buttonandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:text="創建"android:id="@+id/bt_create"/><Buttonandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:text="讀取"android:id="@+id/bt_read"/><TextViewandroid:layout_width="match_parent"android:layout_height="wrap_content"android:id="@+id/tv"/> </LinearLayout>
MainActivity.java代碼:
package com.oak.d4_json;import android.os.Bundle; import android.support.v7.app.AppCompatActivity; import android.view.View; import android.widget.Button; import android.widget.TextView; import android.widget.Toast;import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject;import java.io.BufferedReader; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStreamReader; import java.io.UnsupportedEncodingException;public class MainActivity extends AppCompatActivity {private Button bt_create;//聲明創建按鈕組件變量private Button bt_read;//聲明讀取按鈕組件變量private File file;//聲明一個文件對象private TextView tv;//聲明TextView組件變量@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);bt_create = (Button) findViewById(R.id.bt_create);//獲取到創建按鈕組件bt_read = (Button) findViewById(R.id.bt_read);//獲取到讀取按鈕組件tv = (TextView) findViewById(R.id.tv);//獲取到TextView組件file = new File(getFilesDir(),"Test.json");//獲取到應用在內部的私有文件夾下對應的Test.json文件bt_create.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View view) {try {JSONObject root = new JSONObject();//實例一個JSONObject對象root.put("cat","it");//對其添加一個數據JSONArray languages = new JSONArray();//實例一個JSON數組JSONObject lan1 = new JSONObject();//實例一個lan1的JSON對象lan1.put("id",1);//對lan1對象添加數據lan1.put("ide","Eclipse");//對lan1對象添加數據lan1.put("name","Java");//對lan1對象添加數據JSONObject lan2 = new JSONObject();//實例一個lan2的JSON對象lan2.put("id",2);//對lan2對象添加數據lan2.put("ide","XCode");//對lan2對象添加數據lan2.put("name","Swift");//對lan2對象添加數據JSONObject lan3 = new JSONObject();//實例一個lan3的JSON對象lan3.put("id",3);//對lan3對象添加數據lan3.put("ide","Visual Studio");//對lan3對象添加數據lan3.put("name","C#");//對lan3對象添加數據languages.put(0,lan1);//將lan1對象添加到JSON數組中去,角標為0languages.put(1,lan2);//將lan2對象添加到JSON數組中去,角標為1languages.put(2,lan3);//將lan3對象添加到JSON數組中去,角標為2root.put("languages",languages);//然后將JSON數組添加到名為root的JSON對象中去FileOutputStream fos = new FileOutputStream(file);//創建一個文件輸出流fos.write(root.toString().getBytes());//將生成的JSON數據寫出fos.close();//關閉輸出流Toast.makeText(getApplicationContext(),"創建成功!",Toast.LENGTH_SHORT).show();} catch (JSONException e) {e.printStackTrace();} catch (FileNotFoundException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();}}});bt_read.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View view) {try {FileInputStream fis = new FileInputStream(file);//獲取一個文件輸入流InputStreamReader isr = new InputStreamReader(fis);//讀取文件內容BufferedReader bf = new BufferedReader(isr);//將字符流放入緩存中String line;//定義一個用來臨時保存數據的變量StringBuilder sb = new StringBuilder();//實例化一個字符串序列化while((line = bf.readLine()) != null){sb.append(line);//將數據添加到字符串序列化中}//關閉流fis.close();isr.close();bf.close();JSONObject root = new JSONObject(sb.toString());//用JSONObject進行解析String cat = root.getString("cat");//獲取字符串類型的鍵值對tv.append("cat"+"="+cat+"\n");//顯示數據tv.append("---------------"+"\n");//分割線JSONArray array = root.getJSONArray("languages");//獲取JSON數據中的數組數據for (int i=0; i<array.length(); i++){JSONObject object = array.getJSONObject(i);//遍歷得到數組中的各個對象int id = object.getInt("id");//獲取第一個值String ide = object.getString("ide");//獲取第二個值String name = object.getString("name");//獲取第三個值tv.append("id"+"="+id+"\n");//顯示數據tv.append("ide"+"="+ide+"\n");//顯示數據tv.append("name"+"="+name+"\n");//顯示數據tv.append("---------------"+"\n");//分割線}} catch (FileNotFoundException e) {e.printStackTrace();} catch (UnsupportedEncodingException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();} catch (JSONException e) {e.printStackTrace();}}});} }
android JSONObject的使用就講完了。
就這么簡單。
總結
以上是生活随笔為你收集整理的android JSONObject的使用的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: android edittext 不可编
- 下一篇: Android Studio删除无用的资