天天看點

安卓中的XML和JSON

安卓中的XML和JSON

XML和JSON其實還是比較常見了,JAVASE和JAVAEE的學習中或多或少會有些接觸的,這篇文章主要關于XML和JSON在安卓中的一些應用。

XML

概述

XML是一種常用的存儲資料方式,設計初衷就是為了傳輸和存儲資料。

在Android平台中内部很多地方使用了XML存儲:

比如之前的SharedPreferences的存儲就是使用了XML檔案,持久化存儲的同時又兼具輕量的特性。(

https://blog.csdn.net/nishigesb123/article/details/88875292#t6

XML解析

XML主要有三種方式:

SAX(Simple API for XML)

DOM(Document Object Model)

Android附帶的PULL解析器解析XML檔案

它們對應的特點如下: 

一些性能敏感的資料庫或手機上主要采用SAX方式,SAX讀取是單向的,優點是不占記憶體空間、解析屬性友善,但缺點就是對于套嵌多個分支來說處理不是很友善。

正常在PC上開發我們使用Dom更為輕松一些,DOM方式會把整個XML檔案加載到記憶體中去,優點是可以任意讀取節點,但缺點就是會消耗記憶體。

PULL常常用在移動裝置對于節點處理比較好,也比較節省記憶體。Pull解析器的運作方式與SAX解析器相似,它提供了類似的事件,如:

parser.next()

//開始元素和結束元素事件,可以進入下一個元素并觸發相應事件。事件将作為數值代碼被發送,是以可以使用一個switch對感興趣的事件進行處理。

parser.nextTextl()

//當元素開始解析時,調用該方法可以擷取下一個Text類型元素的值。

畢竟是關于安卓的文章,是以我們主要體來講講PULL解析這部分

PULL解析器解析XML檔案

可用按照下面的步驟解析XML檔案

1、android給我們提供了xml用來得到xmlpull解析器

XmlPullParser parser =Xml.newPullParser()

2、傳入檔案輸入流及xml檔案編碼

parser.setinput(in, "UTF.8);

3、pull讀到xml後傳回EventType,EventType有如下五種

START DOCUMENT——讀取到xml的聲明傳回數字0

END DOCUMENT——讀取到xml的結束傳回數字1

START TAG——讀取到xml的開始标簽傳回數字2

END TAG——讀取到xml的結束标簽傳回數字3

TEXT——讀取到xml的文本傳回數字4

4、擷取目前EventType

int eventType = parser.getEventType()

5、擷取下一下事件類型

while(eventType!-XmlPullParser.END DOCUMENT){

switch (eventTypel) {...}

eventType- parser.next();

}

DEMO

在開始之前,先學習一下怎麼寫一個簡單的XML檔案。

偷一張圖,出處

http://www.w3school.com.cn/xml/xml_tree.asp

package com.example.a4_10xml;

public class Classmate {

int sno;
String name;
String sex;
int age;

@Override
public String toString() {
    return "Classmate{" +
            "sno=" + sno +
            ", name='" + name + '\'' +
            ", sex='" + sex + '\'' +
            ", age=" + age +
            ", grade=" + grade +
            '}';
}

int grade;           

我們把寫好的xml檔案放在res/raw目錄下(原生目錄) 

對xml檔案準備一個類

int sno;
String name;
String sex;
int age;
int grade;           

準備一個Button

<Button
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:id="@+id/xmlpull"
    android:onClick="xmlpull"
    android:text="PULL解析器解析XML檔案"
    app:layout_constraintTop_toTopOf="parent"/>           

import android.support.v7.app.AppCompatActivity;

import android.os.Bundle;

import android.util.Xml;

import android.view.View;

import android.widget.ArrayAdapter;

import org.xmlpull.v1.XmlPullParser;

import org.xmlpull.v1.XmlPullParserException;

import java.io.IOException;

import java.io.InputStream;

import java.io.StringReader;

import java.util.ArrayList;

public class MainActivity extends AppCompatActivity {

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
}

//使用PULL解析XML檔案 (點選事件)
public void xmlpull(View v){
    ArrayList<Classmate> list =  parser();
    for (int i=0;i<list.size();i++){
        System.out.println(list.get(i));
    }

}

private ArrayList<Classmate> parser(){
    //建立ArrayList
    ArrayList<Classmate> list = new ArrayList<>();
    Classmate classmate = null;

    //建立PULL解析器
    XmlPullParser pullParser = Xml.newPullParser();
    //StringReader stringReader = new StringReader(xml);
    InputStream in = getResources().openRawResource(R.raw.test);
    try {
        //設定要解析的檔案流
        pullParser.setInput(in,"UTF-8");
        //擷取目前的事件類型
        int eventType = pullParser.getEventType();

        //不等于文檔解析結束
        while (eventType!=XmlPullParser.END_DOCUMENT){
            switch (eventType){
                //開始标記
                case XmlPullParser.START_TAG:
                    String tag = pullParser.getName();
                    if ("classmate".equals(tag)){
                        classmate = new Classmate();
                        classmate.sno = Integer.parseInt(pullParser.getAttributeValue(null,"sno"));
                    }
                    else if("name".equals(tag)){
                        classmate.name = pullParser.nextText();
                    }
                    else if("sex".equals(tag)){
                        classmate.sex = pullParser.nextText();
                    }
                    else if("name".equals(tag)){
                        classmate.age = Integer.parseInt(pullParser.nextText());
                    }
                    else if("name".equals(tag)){
                        classmate.grade = Integer.parseInt(pullParser.nextText());
                    }
                break;
                    //結束标記
                case XmlPullParser.END_TAG:
                    if("classmate".equals(pullParser.getName())){
                        //添加到list
                        list.add(classmate);
                    }
                    break;
            }
            //擷取下一個事件類型,開始循環
            eventType = pullParser.next();
        }
    } catch (XmlPullParserException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    }
    return list;
}           

效果如下:

JSON

JSON(JavaScript Object Notation) 是一種輕量級的資料交換格式。

它基于JavaScript(Standard ECMA-262 3rd Edition - December 1999)的一個子集。

JSON采用完全獨立于語言的文本格式,但是也使用了類似于C語言家族的習慣(包括C, C++, C#, Java, JavaScript, Perl, Python等)。

這些特性使JSON成為理想的資料交換語言。易于人閱讀和編寫,同時也易于機器解析和生成。

JSON資料格式特點

JSON建構于兩種結構:

“名稱/值”對的集合

值的有序清單(數組)

JSON表示名稱/值對的方式:

表示數組:

出處:

http://www.w3school.com.cn/json/json_syntax.asp

JSONReader

JSONReader是android.util包下的一個用于解析JSON的工具類。

注意:最低版本要求是API 11。

使用方式:

JsonReader reader = new JsonReader(new StringReaderljsonDatal)

使用JsonReader解析JSON資料

類似的準備一個json檔案

{

"user":[

{"name":"中國移動","tel":10086,"Resume":"測試1"},{"name":"中國電信","tel":10000,"Resume":"測試1"}           

]

類似的也需要準備一個對應的類,友善起見全string了....

package com.example.a4_10json;

public class Person {

String name;
String tel;
String Resume;
@Override
public String toString() {
    return "Person{" +
            "name='" + name + '\'' +
            ", tel='" + tel + '\'' +
            ", Resume='" + Resume + '\'' +
            '}';
}           

 完整代碼如下:

import android.util.JsonReader;

import java.io.InputStreamReader;

import java.io.Reader;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
}

public void json_read(View v){
    ArrayList<Person> list= jsonReader();
    for (int i=0;i<list.size();i++){
        System.out.println(list.get(i));
    }
}

private ArrayList<Person> jsonReader() {
    ArrayList<Person> list=new ArrayList<>();
    Reader r=new InputStreamReader(getResources().openRawResource(R.raw.test));
    JsonReader jr=new JsonReader(r);

    try {
        //開始解析對象
        jr.beginObject();
        if (jr.hasNext()) {
            if ("user".equals(jr.nextName())) {
                //開始解析數組
                jr.beginArray();
                //解析每一個對象
                while (jr.hasNext()){
                    //開始解析對象
                    Person p = new Person();
                    jr.beginObject();
                    while (jr.hasNext()){
                        //得到屬性名稱
                        String name = jr.nextName();
                        if("name".equals(name)){
                            //得到姓名
                            p.name=jr.nextString();
                        }else if("tel".equals(name)){
                            //電話
                            p.tel=jr.nextString();
                        }else if("Resume".equals(name)){
                            //簡介
                            p.Resume=jr.nextString();
                        }
                    }
                    //結束對象的解析
                    jr.endObject();
                    //添加到list
                    list.add(p);
                }
                //結束數組解析
                jr.endArray();
            }
        }
        //結束對象解析
        jr.endObject();
    } catch (IOException e) {
        e.printStackTrace();
    }

    return list;
}           

生成一組JSON資料

可以如圖代碼的思路實作

下面提供一段完整的Demo

準備一個Butoon

<Button
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:id="@+id/json_create"
    android:onClick="json_create"
    android:text="生成一組JSON資料"
    app:layout_constraintTop_toBottomOf="@id/json_read"/>           

     //使用JsonReader解析JSON資料注釋往下的部分為上一個Demo的代碼

import org.json.JSONArray;

import org.json.JSONException;

import org.json.JSONObject;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
}

//生成一組JSON資料
public void json_create(View v){
    ArrayList<Person> list=new ArrayList<>();
    Person p1=new Person();
    p1.name="生成的資料1";
    p1.tel="123";
    p1.Resume="測試1";
    Person p2=new Person();
    p2.name="生成的資料1";
    p2.tel="456";
    p2.Resume="測試2";
    //添加
    list.add(p1);
    list.add(p2);
    JSONObject json=new JSONObject();
    JSONArray array=new JSONArray();
    try {
        for (int i=0;i<list.size();i++){
            Person p=list.get(i);
            JSONObject obj=new JSONObject();
            obj.put("name",p.name);
            obj.put("tel",p.tel);
            obj.put("Resume",p.Resume);
            array.put(obj);
        }
        json.put("person",array);
    } catch (JSONException e) {
        e.printStackTrace();
    }
    System.out.println(json.toString());
}
           
//使用JsonReader解析JSON資料
public void json_read(View v){
    ArrayList<Person> list= jsonReader();
    for (int i=0;i<list.size();i++){
        System.out.println(list.get(i));
    }
}

private ArrayList<Person> jsonReader() {
    ArrayList<Person> list=new ArrayList<>();
    Reader r=new InputStreamReader(getResources().openRawResource(R.raw.test));
    JsonReader jr=new JsonReader(r);

    try {
        //開始解析對象
        jr.beginObject();
        if (jr.hasNext()) {
            if ("user".equals(jr.nextName())) {
                //開始解析數組
                jr.beginArray();
                //解析每一個對象
                while (jr.hasNext()){
                    //開始解析對象
                    Person p = new Person();
                    jr.beginObject();
                    while (jr.hasNext()){
                        //得到屬性名稱
                        String name = jr.nextName();
                        if("name".equals(name)){
                            //得到姓名
                            p.name=jr.nextString();
                        }else if("tel".equals(name)){
                            //電話
                            p.tel=jr.nextString();
                        }else if("Resume".equals(name)){
                            //簡介
                            p.Resume=jr.nextString();
                        }
                    }
                    //結束對象的解析
                    jr.endObject();
                    //添加到list
                    list.add(p);
                }
                //結束數組解析
                jr.endArray();
            }
        }
        //結束對象解析
        jr.endObject();
    } catch (IOException e) {
        e.printStackTrace();
    }

    return list;
}           

效果如下: 

GSON

GSON是Google提供的用來在Java對象和JSON資料之間進行映射的Java類庫。可以将一個Json字元轉成一個Java對象,或者将一個Java轉化為Json字元串。

GITHUB位址:

https://github.com/google/gson

方法 

 使用Gson直接把JSON資料轉換成Java對象

public Student parserJSON2(String data){

Gson gson = new Gson();

Student s = gson.fromJson(data, Student.class);

return s;           

使用Gson直接把JSON數組轉換成Java對象

public List Student> parserJSON3(String data){

Type type = new TypeToken<ArrayList <Student>>(){}.getType();
Gson gson = new Gson();
List<Student> list =gson.fromJson(data, type);
return list;
           

使用GSON解析和生成JSON

使用GSON前需要導入JAR包,JAR包可以在提供的GITHUB位址上下載下傳

下載下傳完畢後将jar包放在如下路徑

然後還需要點一下Add As Library

選擇OK    

規矩和之前差不多,不多叙述,直接放代碼。 

小改一下test.js的on代碼 重建立個test2.json

[{"name":"中國移動","tel":10086,"Resume":"測試1"},{"name":"中國電信","tel":10000,"Resume":"測試1"}]

最終代碼: 

<Button
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:id="@+id/GSON"
    android:onClick="GSON"
    android:text="使用GSON解析JSON"
    app:layout_constraintTop_toBottomOf="@id/json_read"/>

<Button
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:id="@+id/GSON_Create"
    android:onClick="GSON_Create"
    android:text="使用GSON生成JSON"
    app:layout_constraintTop_toBottomOf="@id/GSON"/>           

import com.google.gson.Gson;

import com.google.gson.reflect.TypeToken;

import java.lang.reflect.Type;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
}
//使用GSON解析JSON
public void GSON(View v){
    Gson gson=new Gson();
    Reader r=new InputStreamReader(getResources().openRawResource(R.raw.test2));
    //選Reflect包下的Type
    Type type=new TypeToken<ArrayList<Person>>(){}.getType();
    ArrayList<Person> list= gson.fromJson(r,type);
    for (int i=0;i<list.size();i++){
        System.out.println(list.get(i));
    }
}

//使用GSON生成JSON
public void GSON_Create(View v){
    ArrayList<Person> list=new ArrayList<>();
    Person p1=new Person();
    p1.name="測試資料1";
    p1.tel="123456";
    p1.Resume="使用GSON生成JSON的資料1";
    Person p2=new Person();
    p2.name="測試資料2";
    p2.tel="456789";
    p2.Resume="使用GSON生成JSON的資料2";
    list.add(p1);
    list.add(p2);
    Gson gson=new Gson();
    Type type=new TypeToken<ArrayList<Person>>(){}.getType();
    String json= gson.toJson(list,type);
    System.out.println(json);
}
           
//生成一組JSON資料
public void json_create(View v){
    ArrayList<Person> list=new ArrayList<>();
    Person p1=new Person();
    p1.name="生成的資料1";
    p1.tel="123";
    p1.Resume="測試1";
    Person p2=new Person();
    p2.name="生成的資料1";
    p2.tel="456";
    p2.Resume="測試2";
    //添加
    list.add(p1);
    list.add(p2);
    JSONObject json=new JSONObject();
    JSONArray array=new JSONArray();
    try {
        for (int i=0;i<list.size();i++){
            Person p=list.get(i);
            JSONObject obj=new JSONObject();
            obj.put("name",p.name);
            obj.put("tel",p.tel);
            obj.put("Resume",p.Resume);
            array.put(obj);
        }
        json.put("person",array);
    } catch (JSONException e) {
        e.printStackTrace();
    }
    System.out.println(json.toString());
}
           
//使用JsonReader解析JSON資料
public void json_read(View v){
    ArrayList<Person> list= jsonReader();
    for (int i=0;i<list.size();i++){
        System.out.println(list.get(i));
    }
}

private ArrayList<Person> jsonReader() {
    ArrayList<Person> list=new ArrayList<>();
    Reader r=new InputStreamReader(getResources().openRawResource(R.raw.test));
    JsonReader jr=new JsonReader(r);

    try {
        //開始解析對象
        jr.beginObject();
        if (jr.hasNext()) {
            if ("user".equals(jr.nextName())) {
                //開始解析數組
                jr.beginArray();
                //解析每一個對象
                while (jr.hasNext()){
                    //開始解析對象
                    Person p = new Person();
                    jr.beginObject();
                    while (jr.hasNext()){
                        //得到屬性名稱
                        String name = jr.nextName();
                        if("name".equals(name)){
                            //得到姓名
                            p.name=jr.nextString();
                        }else if("tel".equals(name)){
                            //電話
                            p.tel=jr.nextString();
                        }else if("Resume".equals(name)){
                            //簡介
                            p.Resume=jr.nextString();
                        }
                    }
                    //結束對象的解析
                    jr.endObject();
                    //添加到list
                    list.add(p);
                }
                //結束數組解析
                jr.endArray();
            }
        }
        //結束對象解析
        jr.endObject();
    } catch (IOException e) {
        e.printStackTrace();
    }

    return list;
}           

解析

生成

XML和JSON的對比

從以下6點比較JSON與XML :

JSON和XML的資料可讀性基本相同

JSON和XML同樣擁有豐富的解析手段

JSON相對于XML來講,資料的體積小

JSON與JavaScript的互動更加友善

JSON對資料的描述性比XML較差

JSON的速度要遠遠快于XML

作者:舊日燈塔

來源:CSDN

原文:

https://blog.csdn.net/nishigesb123/article/details/89190973

版權聲明:本文為部落客原創文章,轉載請附上博文連結!