Android中JSON的4種解析方式使用和對比
1 Android SDK自帶的org.json解析
解析原理: 基于文檔驅(qū)動,需要把全部文件讀入到內(nèi)存中,然后遍歷所有數(shù)據(jù),根據(jù)需要檢索想要的數(shù)據(jù)。
相關(guān)類:
- JSONObject
- JSONArray
- JSONTokener
public Object nextValue() throws JSONException {
? ? int c = nextCleanInternal();
? ? switch (c) {
? ? ? ? case -1:
? ? ? ? ? ? throw syntaxError("End of input");
? ? ? ? ? ??
? ? ? ? case '{':
? ? ? ? ? ? return readObject();
? ? ? ? ? ??
? ? ? ? case '[':
? ? ? ? ? ? return readArray();
? ? ? ? ? ??
? ? ? ? case ''':
? ? ? ? case '"':
? ? ? ? ? ? return nextString((char) c);
? ? ? ? ? ??
? ? ? ? default:
? ? ? ? ? ? pos--;
? ? ? ? ? ? return readLiteral();
? ? }
}- JSONStringer
- JSONException
以下是Android SDK自帶Json解析方式的示例代碼:
/**
?* @Description: SDK org.json下自帶的Json解析方式
?* @CreateDate: 2022/3/22 10:30 上午
?*/
public class OrgJsonUtil {
? ? /**
? ? ?* 生成Json
? ? ?*/
? ? public static void createJson(Context context) {
? ? ? ? try {
? ? ? ? ? ? File file = new File(context.getFilesDir(), "orgjson.json");
? ? ? ? ? ? //實例化一個JSONObject
? ? ? ? ? ? JSONObject student = new JSONObject();
? ? ? ? ? ? //向?qū)ο笾刑砑訑?shù)據(jù)
? ? ? ? ? ? student.put("name", "Musk");
? ? ? ? ? ? student.put("sex", "男");
? ? ? ? ? ? student.put("age", 50);
? ? ? ? ? ? JSONObject course1 = new JSONObject();
? ? ? ? ? ? course1.put("name", "數(shù)學(xué)");
? ? ? ? ? ? course1.put("score", 98.2f);
? ? ? ? ? ? JSONObject course2 = new JSONObject();
? ? ? ? ? ? course2.put("name", "語文");
? ? ? ? ? ? course2.put("score", 99);
? ? ? ? ? ? //實例化一個JSONArray
? ? ? ? ? ? JSONArray courses = new JSONArray();
? ? ? ? ? ? courses.put(0, course1);
? ? ? ? ? ? courses.put(1, course2);
? ? ? ? ? ? student.put("courses", courses);
? ? ? ? ? ? //寫數(shù)據(jù)
? ? ? ? ? ? FileOutputStream fos = new FileOutputStream(file);
? ? ? ? ? ? fos.write(student.toString().getBytes());
? ? ? ? ? ? fos.close();
? ? ? ? ? ? Log.d("TAG", "createJson: " + student);
? ? ? ? ? ? Toast.makeText(context, "Json創(chuàng)建成功", Toast.LENGTH_SHORT).show();
? ? ? ? } catch (Exception e) {
? ? ? ? ? ? e.printStackTrace();
? ? ? ? }
? ? }
? ? /**
? ? ?* 解析Json
? ? ?*/
? ? public static void parseJson(Context context) {
? ? ? ? try {
? ? ? ? ? ? //讀數(shù)據(jù)
? ? ? ? ? ? File file = new File(context.getFilesDir(), "orgjson.json");
? ? ? ? ? ? FileInputStream fis = new FileInputStream(file);
? ? ? ? ? ? InputStreamReader isr = new InputStreamReader(fis);
? ? ? ? ? ? BufferedReader br = new BufferedReader(isr);
? ? ? ? ? ? String line;
? ? ? ? ? ? StringBuffer sb = new StringBuffer();
? ? ? ? ? ? while (null != (line = br.readLine())) {
? ? ? ? ? ? ? ? sb.append(line);
? ? ? ? ? ? }
? ? ? ? ? ? fis.close();
? ? ? ? ? ? isr.close();
? ? ? ? ? ? br.close();
? ? ? ? ? ? Student student = new Student();
? ? ? ? ? ? JSONObject studentJsonObject = new JSONObject(sb.toString());
? ? ? ? ? ? //獲取對象
? ? ? ? ? ? //使用optString在獲取不到對應(yīng)值的時候會返回空字符串"",而使用getString會異常
? ? ? ? ? ? String name = studentJsonObject.optString("name", "");
? ? ? ? ? ? String sex = studentJsonObject.optString("sex", "女");
? ? ? ? ? ? int age = studentJsonObject.optInt("age", 18);
? ? ? ? ? ? student.setName(name);
? ? ? ? ? ? student.setSex(sex);
? ? ? ? ? ? student.setAge(age);
? ? ? ? ? ? //獲取數(shù)組
? ? ? ? ? ? List<Course> courses = new ArrayList<>();
? ? ? ? ? ? JSONArray coursesJsonArray = studentJsonObject.optJSONArray("courses");
? ? ? ? ? ? if (coursesJsonArray != null && coursesJsonArray.length() > 0) {
? ? ? ? ? ? ? ? for (int i = 0; i < coursesJsonArray.length(); i++) {
? ? ? ? ? ? ? ? ? ? JSONObject courseJsonObject = coursesJsonArray.optJSONObject(i);
? ? ? ? ? ? ? ? ? ? Course course = new Course();
? ? ? ? ? ? ? ? ? ? String courseName = courseJsonObject.optString("name", "學(xué)科");
? ? ? ? ? ? ? ? ? ? float score = (float) courseJsonObject.optDouble("score", 0);
? ? ? ? ? ? ? ? ? ? course.setName(courseName);
? ? ? ? ? ? ? ? ? ? course.setScore(score);
? ? ? ? ? ? ? ? ? ? courses.add(course);
? ? ? ? ? ? ? ? }
? ? ? ? ? ? }
? ? ? ? ? ? student.setCourses(courses);
? ? ? ? ? ? Log.d("TAG", "parseJson: " + student);
? ? ? ? ? ? Toast.makeText(context, "Json解析成功", Toast.LENGTH_SHORT).show();
? ? ? ? } catch (Exception e) {
? ? ? ? ? ? e.printStackTrace();
? ? ? ? }
? ? }
}2 Gson解析
解析原理: 基于事件驅(qū)動。
優(yōu)勢:
- 快速,高效
- 代碼量少
- 面向?qū)ο?/li>
- 數(shù)據(jù)傳輸解析方便
- 可按需解析
解析流程: 根據(jù)所需取的數(shù)據(jù) 建立1個對應(yīng)于JSON數(shù)據(jù)的JavaBean類,即可通過簡單操作解析出所需數(shù)據(jù)。
Gson 不要求JavaBean類里面的屬性一定全部和JSON數(shù)據(jù)里的所有key相同,可以按需取數(shù)據(jù)。
使用:
JSON的大括號對應(yīng)一個對象
- 對象里面有key,value
- JavaBean的類屬性名 = key
JSON的中括號對應(yīng)一個數(shù)組
JavaBean里面對應(yīng)的也是數(shù)組
對象里可以有值/對象
若對象里面只有值,沒有key,則說明是純數(shù)組,對應(yīng)JavaBean里的數(shù)組類型
若對象里面有值和key,則說明是對象數(shù)組,對應(yīng)JavaBean里的內(nèi)部類
對象嵌套
- 建立內(nèi)部類 該內(nèi)部類對象的名字 = 父對象的key ,類似對象數(shù)組
{
? ? "key":"value",
? ? "simpleArray":[
? ? ? ? 1,
? ? ? ? 2,
? ? ? ? 3
? ? ],
? ? "arrays":[
? ? ? ? {
? ? ? ? ? ? "arrInnerClsKey":"arrInnerClsValue",
? ? ? ? ? ? "arrInnerClsKeyNub":1
? ? ? ? }
? ? ],
? ? "innerclass":{
? ? ? ? "name":"Musk",
? ? ? ? "age":50,
? ? ? ? "sex":"男"
? ? }
}與之對應(yīng)的JavaBean:
public class JsonJavaBean {
? ? private String key;
? ? private List<Integer> simpleArray;
? ? private List<ArraysBean> arrays;
? ? private InnerclassBean innerclass;
? ? public String getKey() {
? ? ? ? return key;
? ? }
? ? public void setKey(String key) {
? ? ? ? this.key = key;
? ? }
? ? public List<Integer> getSimpleArray() {
? ? ? ? return simpleArray;
? ? }
? ? public void setSimpleArray(List<Integer> simpleArray) {
? ? ? ? this.simpleArray = simpleArray;
? ? }
? ? public List<ArraysBean> getArrays() {
? ? ? ? return arrays;
? ? }
? ? public void setArrays(List<ArraysBean> arrays) {
? ? ? ? this.arrays = arrays;
? ? }
? ? public InnerclassBean getInnerclass() {
? ? ? ? return innerclass;
? ? }
? ? public void setInnerclass(InnerclassBean innerclass) {
? ? ? ? this.innerclass = innerclass;
? ? }
? ? private static class ArraysBean {
? ? ? ? private String arrInnerClsKey;
? ? ? ? private int arrInnerClsKeyNub;
? ? ? ? public String getArrInnerClsKey() {
? ? ? ? ? ? return arrInnerClsKey;
? ? ? ? }
? ? ? ? public void setArrInnerClsKey(String arrInnerClsKey) {
? ? ? ? ? ? this.arrInnerClsKey = arrInnerClsKey;
? ? ? ? }
? ? ? ? public int getArrInnerClsKeyNub() {
? ? ? ? ? ? return arrInnerClsKeyNub;
? ? ? ? }
? ? ? ? public void setArrInnerClsKeyNub(int arrInnerClsKeyNub) {
? ? ? ? ? ? this.arrInnerClsKeyNub = arrInnerClsKeyNub;
? ? ? ? }
? ? }
? ? private static class InnerclassBean {
? ? ? ? private String name;
? ? ? ? private int age;
? ? ? ? private String sex;
? ? ? ? public String getName() {
? ? ? ? ? ? return name;
? ? ? ? }
? ? ? ? public void setName(String name) {
? ? ? ? ? ? this.name = name;
? ? ? ? }
? ? ? ? public int getAge() {
? ? ? ? ? ? return age;
? ? ? ? }
? ? ? ? public void setAge(int age) {
? ? ? ? ? ? this.age = age;
? ? ? ? }
? ? ? ? public String getSex() {
? ? ? ? ? ? return sex;
? ? ? ? }
? ? ? ? public void setSex(String sex) {
? ? ? ? ? ? this.sex = sex;
? ? ? ? }
? ? }
}Gson解析示例代碼:
/**
?* @Description: Gson使用示例
?* @CreateDate: 2022/3/22 12:51 下午
?*/
public class GsonUse {
? ? public static void main(String[] args) throws Exception {
? ? ? ? Student student = new Student();
? ? ? ? student.setName("John");
? ? ? ? student.setAge(20);
? ? ? ? student.setSex("男");
? ? ? ? List<Course> courses = new ArrayList<>();
? ? ? ? courses.add(new Course("語文", 99));
? ? ? ? courses.add(new Course("地理", 59));
? ? ? ? student.setCourses(courses);
? ? ? ? Gson gson = new Gson();
? ? ? ? //在項目根目錄下的json文件夾下生成Jgsonjson.json文件
? ? ? ? File file = new File("json/gsonjson.json");
? ? ? ? FileOutputStream fos = new FileOutputStream(file);
? ? ? ? OutputStreamWriter osw = new OutputStreamWriter(fos, "utf-8");
? ? ? ? JsonWriter jw = new JsonWriter(osw);
? ? ? ? gson.toJson(student, new TypeToken<Student>() {
? ? ? ? }.getType(), jw);
? ? ? ? jw.flush();
? ? ? ? jw.close();
? ? ? ? //反序列化為JavaBean
? ? ? ? FileInputStream fis = new FileInputStream(file);
? ? ? ? InputStreamReader isr = new InputStreamReader(fis);
? ? ? ? JsonReader jr = new JsonReader(isr);
? ? ? ? Student student1 = gson.fromJson(jr, new TypeToken<Student>() {
? ? ? ? }.getType());
? ? ? ? System.out.println(student1);
? ? }
}3 Jackson解析
解析原理: 基于事件驅(qū)動。
優(yōu)勢: 解析效率最高;在數(shù)據(jù)量大的情況優(yōu)勢尤為明顯、占存少。
缺點: Json數(shù)據(jù)里面的所有key都有所對應(yīng),也就是必須完全解析文檔,如果要按需解析的話可以拆分Json來讀取,操作和解析方法復(fù)雜。
適用場景: 適用于需要處理超大型JSON文檔、不需要對JSON文檔進行按需解析、性能要求較高的場合。
解析過程:
- 類似Gson,先創(chuàng)建1個對應(yīng)于JSON數(shù)據(jù)的JavaBean類,再通過簡單操作即可解析。
- 與Gson解析不同的是:Gson可按需解析,即創(chuàng)建的JavaBean類不一定完全涵蓋所要解析的JSON數(shù)據(jù),按需創(chuàng)建屬性;但Jackson解析對應(yīng)的JavaBean必須把Json數(shù)據(jù)里面的所有key都有所對應(yīng),即必須把JSON內(nèi)的數(shù)據(jù)所有解析出來,無法按需解析。
使用:
引入依賴
//Jackson
implementation 'com.fasterxml.jackson.core:jackson-databind:2.13.1'
implementation 'com.fasterxml.jackson.core:jackson-core:2.13.1'
implementation 'com.fasterxml.jackson.core:jackson-annotations:2.13.1'
/**
?* @Description: Jackson使用示例
?* @CreateDate: 2022/3/22 1:47 下午
?*/
public class JacksonUse {
? ? public static void main(String[] args) throws Exception {
? ? ? ? Student student = new Student();
? ? ? ? student.setName("Lili");
? ? ? ? student.setSex("女");
? ? ? ? student.setAge(26);
? ? ? ? List<Course> courses = new ArrayList<>();
? ? ? ? courses.add(new Course("Art", 100));
? ? ? ? courses.add(new Course("Love", 99));
? ? ? ? student.setCourses(courses);
? ? ? ? ObjectMapper objectMapper = new ObjectMapper();
? ? ? ? //序列化 生成json文件
? ? ? ? File file = new File("json/jacksonjson.json");
? ? ? ? FileOutputStream fos = new FileOutputStream(file);
? ? ? ? objectMapper.writeValue(fos, student);
? ? ? ? //反序列化 json文件轉(zhuǎn)為JavaBean
? ? ? ? Student student1 = objectMapper.readValue(file, Student.class);
? ? ? ? System.out.println(student1);
? ? }
}注意:json里的key必須和JavaBean中的字段全部對應(yīng)。
如果沒對應(yīng),比如json中多了一個"hobby"字段,JavaBean中沒有,運行就會報錯:
Exception in thread "main" com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException: Unrecognized field "hobby" (class site.exciter.learn.json.Student), not marked as ignorable (4 known properties: "courses", "name", "sex", "age"])
at [Source: (File); line: 3, column: 13] (through reference chain: site.exciter.learn.json.Student["hobby"])
4 Fastjson解析
特點:
- 快速FAST(比任何一款都快)
- 面向?qū)ο?/li>
- 功能強大(支持普通JDK類任意java bean Class,Collection,Map,Date或者enum)
- 零依賴(只需要有JDK即可)
- 支持注解,全類型序列化
使用:
引入依賴
implementation 'com.alibaba:fastjson:1.2.76'
/**
?* @Description: Fastjson使用示例
?* @CreateDate: 2022/3/22 2:10 下午
?*/
public class FastjsonUse {
? ? public static void main(String[] args) throws Exception {
? ? ? ? Student student = new Student();
? ? ? ? student.setName("Lili");
? ? ? ? student.setSex("女");
? ? ? ? student.setAge(26);
? ? ? ? List<Course> courses = new ArrayList<>();
? ? ? ? courses.add(new Course("Art", 100));
? ? ? ? courses.add(new Course("Love", 99));
? ? ? ? student.setCourses(courses);
? ? ? ? //序列化 生成json
? ? ? ? File file = new File("json/fastjson.json");
? ? ? ? FileOutputStream fos = new FileOutputStream(file);
? ? ? ? JSONObject.writeJSONString(fos, student);
? ? ? ? //反序列化 json轉(zhuǎn)JavaBean
? ? ? ? FileInputStream fis = new FileInputStream(file);
? ? ? ? Student student1 = JSONObject.parseObject(fis, Student.class);
? ? ? ? System.out.println(student1);
? ? }
}以上就是幾種JSON解析方式的對比,目前來說還是Gson和FastJson用的相對來說比較多。更多相關(guān)Android JSON內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Android利用ObjectAnimator實現(xiàn)ArcMenu
這篇文章主要為大家詳細介紹了Android利用ObjectAnimator實現(xiàn)ArcMenu的相關(guān)資料,感興趣的小伙伴們可以參考一下2016-07-07
Android學(xué)習(xí)筆記--通過Application傳遞數(shù)據(jù)代碼示例
使用Application傳遞數(shù)據(jù)步驟如下:創(chuàng)建新class,取名MyApp,繼承android.app.Application父類,并在MyApp中定義需要保存的屬性2013-06-06
Android編程圖片加載類ImageLoader定義與用法實例分析
這篇文章主要介紹了Android編程圖片加載類ImageLoader定義與用法,結(jié)合實例形式分析了Android圖片加載類ImageLoader的功能、定義、使用方法及相關(guān)操作注意事項,代碼中備有較為詳盡的注釋便于理解,需要的朋友可以參考下2017-12-12
Android?ViewStub使用方法學(xué)習(xí)
這篇文章主要為大家介紹了Android?ViewStub使用方法學(xué)習(xí),有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2022-11-11
Android中創(chuàng)建快捷方式及刪除快捷方式實現(xiàn)方法
這篇文章主要介紹了Android中創(chuàng)建快捷方式及刪除快捷方式實現(xiàn)方法,本文直接給出實現(xiàn)代碼,需要的朋友可以參考下2015-06-06

