Android中JSON的4種解析方式使用和對(duì)比
1 Android SDK自帶的org.json解析
解析原理: 基于文檔驅(qū)動(dòng),需要把全部文件讀入到內(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"); ? ? ? ? ? ? //實(shí)例化一個(gè)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", "語(yǔ)文"); ? ? ? ? ? ? course2.put("score", 99); ? ? ? ? ? ? //實(shí)例化一個(gè)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()); ? ? ? ? ? ? //獲取對(duì)象 ? ? ? ? ? ? //使用optString在獲取不到對(duì)應(yīng)值的時(shí)候會(huì)返回空字符串"",而使用getString會(huì)異常 ? ? ? ? ? ? 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ū)動(dòng)。
優(yōu)勢(shì):
- 快速,高效
- 代碼量少
- 面向?qū)ο?/li>
- 數(shù)據(jù)傳輸解析方便
- 可按需解析
解析流程: 根據(jù)所需取的數(shù)據(jù) 建立1個(gè)對(duì)應(yīng)于JSON數(shù)據(jù)的JavaBean類,即可通過簡(jiǎn)單操作解析出所需數(shù)據(jù)。
Gson 不要求JavaBean類里面的屬性一定全部和JSON數(shù)據(jù)里的所有key相同,可以按需取數(shù)據(jù)。
使用:
JSON的大括號(hào)對(duì)應(yīng)一個(gè)對(duì)象
- 對(duì)象里面有key,value
- JavaBean的類屬性名 = key
JSON的中括號(hào)對(duì)應(yīng)一個(gè)數(shù)組
JavaBean里面對(duì)應(yīng)的也是數(shù)組
對(duì)象里可以有值/對(duì)象
若對(duì)象里面只有值,沒有key,則說明是純數(shù)組,對(duì)應(yīng)JavaBean里的數(shù)組類型
若對(duì)象里面有值和key,則說明是對(duì)象數(shù)組,對(duì)應(yīng)JavaBean里的內(nèi)部類
對(duì)象嵌套
- 建立內(nèi)部類 該內(nèi)部類對(duì)象的名字 = 父對(duì)象的key ,類似對(duì)象數(shù)組
{ ? ? "key":"value", ? ? "simpleArray":[ ? ? ? ? 1, ? ? ? ? 2, ? ? ? ? 3 ? ? ], ? ? "arrays":[ ? ? ? ? { ? ? ? ? ? ? "arrInnerClsKey":"arrInnerClsValue", ? ? ? ? ? ? "arrInnerClsKeyNub":1 ? ? ? ? } ? ? ], ? ? "innerclass":{ ? ? ? ? "name":"Musk", ? ? ? ? "age":50, ? ? ? ? "sex":"男" ? ? } }
與之對(duì)應(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("語(yǔ)文", 99)); ? ? ? ? courses.add(new Course("地理", 59)); ? ? ? ? student.setCourses(courses); ? ? ? ? Gson gson = new Gson(); ? ? ? ? //在項(xiàng)目根目錄下的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ū)動(dòng)。
優(yōu)勢(shì): 解析效率最高;在數(shù)據(jù)量大的情況優(yōu)勢(shì)尤為明顯、占存少。
缺點(diǎn): Json數(shù)據(jù)里面的所有key都有所對(duì)應(yīng),也就是必須完全解析文檔,如果要按需解析的話可以拆分Json來讀取,操作和解析方法復(fù)雜。
適用場(chǎng)景: 適用于需要處理超大型JSON文檔、不需要對(duì)JSON文檔進(jìn)行按需解析、性能要求較高的場(chǎng)合。
解析過程:
- 類似Gson,先創(chuàng)建1個(gè)對(duì)應(yīng)于JSON數(shù)據(jù)的JavaBean類,再通過簡(jiǎn)單操作即可解析。
- 與Gson解析不同的是:Gson可按需解析,即創(chuàng)建的JavaBean類不一定完全涵蓋所要解析的JSON數(shù)據(jù),按需創(chuàng)建屬性;但Jackson解析對(duì)應(yīng)的JavaBean必須把Json數(shù)據(jù)里面的所有key都有所對(duì)應(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中的字段全部對(duì)應(yīng)。
如果沒對(duì)應(yīng),比如json中多了一個(gè)"hobby"字段,JavaBean中沒有,運(yùn)行就會(huì)報(bào)錯(cuò):
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解析
特點(diǎn):
- 快速FAST(比任何一款都快)
- 面向?qū)ο?/li>
- 功能強(qiáng)大(支持普通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解析方式的對(duì)比,目前來說還是Gson和FastJson用的相對(duì)來說比較多。更多相關(guān)Android JSON內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
微信小程序 實(shí)現(xiàn)列表刷新的實(shí)例詳解
這篇文章主要介紹了微信小程序 實(shí)現(xiàn)列表刷新的實(shí)例詳解的相關(guān)資料,這里提供了實(shí)現(xiàn)代碼及實(shí)現(xiàn)效果圖,需要的朋友可以參考下2016-11-11Android利用ObjectAnimator實(shí)現(xiàn)ArcMenu
這篇文章主要為大家詳細(xì)介紹了Android利用ObjectAnimator實(shí)現(xiàn)ArcMenu的相關(guān)資料,感興趣的小伙伴們可以參考一下2016-07-07Android 自定義AlertDialog對(duì)話框樣式
實(shí)際的項(xiàng)目開發(fā)當(dāng)中,經(jīng)常需要根據(jù)實(shí)際的需求來自定義AlertDialog。最近在開發(fā)一個(gè)WIFI連接的功能,點(diǎn)擊WIFI需要彈出自定義密碼輸入框,具體代碼大家參考下本文2017-09-09Android學(xué)習(xí)筆記--通過Application傳遞數(shù)據(jù)代碼示例
使用Application傳遞數(shù)據(jù)步驟如下:創(chuàng)建新class,取名MyApp,繼承android.app.Application父類,并在MyApp中定義需要保存的屬性2013-06-06Android gradle打包并自動(dòng)上傳的方法
本篇文章主要介紹了Android gradle打包并自動(dòng)上傳的方法,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2017-09-09Android編程圖片加載類ImageLoader定義與用法實(shí)例分析
這篇文章主要介紹了Android編程圖片加載類ImageLoader定義與用法,結(jié)合實(shí)例形式分析了Android圖片加載類ImageLoader的功能、定義、使用方法及相關(guān)操作注意事項(xiàng),代碼中備有較為詳盡的注釋便于理解,需要的朋友可以參考下2017-12-12Android?ViewStub使用方法學(xué)習(xí)
這篇文章主要為大家介紹了Android?ViewStub使用方法學(xué)習(xí),有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-11-11Android adb.exe程序啟動(dòng)不起來 具體解決方法
這篇文章主要介紹了Android adb.exe程序啟動(dòng)不起來 具體解決方法,有需要的朋友可以參考一下2013-12-12Android中創(chuàng)建快捷方式及刪除快捷方式實(shí)現(xiàn)方法
這篇文章主要介紹了Android中創(chuàng)建快捷方式及刪除快捷方式實(shí)現(xiàn)方法,本文直接給出實(shí)現(xiàn)代碼,需要的朋友可以參考下2015-06-06