
文章目录Android JSON解析总结概述语法使用Android的org.json处理生成JSON解析JSONAndroid JSON解析总结概述JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式语法JSON有2种结构对象ObjectJSON中的对象表示为花括号{}中的键值对集合。键和值之间用冒号:连接键值对之间用逗号,连接。数组ArrayJSON中的数组表示为方括号[]中的值列表。数组元素之间用逗号,连接。语法上的硬性约束写手写 JSON 时最容易踩键必须用双引号包裹不能用单引号最后一个元素不能有尾随逗号标准 JSON不支持注释值只能是string / number / boolean / null / object / array六种不支持undefined、不支持NaN、Infinity。使用Android的org.json处理数据类publicclassStudent{Stringname;intage;Stringsex;publicStudent(Stringname,intage,Stringsex){this.namename;this.ageage;this.sexsex;}}publicclassSchool{Stringteacher;intschoolRanking;ListStudentstudents;publicSchool(Stringteacher,intschoolRanking,ListStudentstudents){this.teacherteacher;this.schoolRankingschoolRanking;this.studentsstudents;}}生成JSONprivatevoidtoJson()throwsJSONException,IOException{JSONObjectschoolObjectnewJSONObject();// 坑1put(String, Object) 传入 null 时等价于删除该 key字段会直接消失// 要显式写 null 必须用 JSONObject.NULLschoolObject.put(teacher,school.teacher!null?school.teacher:JSONObject.NULL);schoolObject.put(schoolRanking,school.schoolRanking);JSONArraystudentArraynewJSONArray();// 坑2集合为 null 时直接 foreach 会 NPEif(school.students!null){for(Studentstudent:school.students){JSONObjectstudentObjectnewJSONObject();studentObject.put(name,student.name!null?student.name:JSONObject.NULL);studentObject.put(age,student.age);studentObject.put(sex,student.sex!null?student.sex:JSONObject.NULL);studentArray.put(studentObject);}}schoolObject.put(students,studentArray);// 坑3getBytes() 不带字符集依赖平台默认编码必须显式指定 UTF-8// 坑4原写法未用 try-with-resources / finally异常时流不会关闭try(OutputStreamoutputStreamnewBufferedOutputStream(newFileOutputStream(newFile(getCacheDir(),test.json)))){outputStream.write(schoolObject.toString().getBytes(StandardCharsets.UTF_8));}}解析JSONprivateSchoolparseJson()throwsJSONException,IOException{FilefilenewFile(getCacheDir(),test.json);JSONObjectjsonObjectnewJSONObject(readText(file));// 坑5getString / getInt 在字段缺失或类型不符时直接抛 JSONException// 字段不确定的场景优先用 optXxx(key, 默认值)StringteacherjsonObject.optString(teacher,);intschoolRankingjsonObject.optInt(schoolRanking,-1);JSONArraystudentsArrayjsonObject.optJSONArray(students);ListStudentstudentsnewArrayList();if(studentsArray!null){for(inti0;istudentsArray.length();i){JSONObjectstudentObjectstudentsArray.optJSONObject(i);if(studentObjectnull)continue;StringnamestudentObject.optString(name,);intagestudentObject.optInt(age,0);StringsexstudentObject.optString(sex,);students.add(newStudent(name,age,sex));}}returnnewSchool(teacher,schoolRanking,students);}privatestaticStringreadText(Filefile)throwsIOException{StringBuilderbuildernewStringBuilder();// 坑6FileReader 无法指定字符集必须换成 InputStreamReader UTF-8try(ReaderreadernewBufferedReader(newInputStreamReader(newFileInputStream(file),StandardCharsets.UTF_8))){// 坑7原示例缓冲区只有 3 个字符会产生大量无谓的 IO用 8KBchar[]buffernewchar[8*1024];intlen;while((lenreader.read(buffer))!-1){builder.append(buffer,0,len);}}Stringjsonbuilder.toString();// 坑8带 UTF-8 BOM 的文件会让 new JSONObject(json) 直接抛 JSONException先去掉 BOMif(!json.isEmpty()json.charAt(0)\uFEFF){jsonjson.substring(1);}returnjson;}