当前位置: 首页 > news >正文

【Android】JSONObject和Gson的使用

在这里插入图片描述

三三要成为安卓糕手

一:JSONObject介绍

JSON常见格式

{
"name": "Alice",
"age": 30,
"isStudent": false,
"address": {
"city": "New York",
"zip": "10001"
},
"courses": ["Math", "Science", "History"],
"grades": [85, 90, 92],
"graduated": null
}

1:利用创建Json数据

/*** 使用JSONObject完成json数据的创建** {*   "name": "Alice",*   "age": 30,*   "isStudent": false,*   "address": {*     "city": "New York",*     "zip": "10001"*   },*   "courses": ["Math", "Science", "History"],*   "grades": [85, 90, 92],*   "graduated": null* }*/private void createJSON(){JSONObject jsonObject = new JSONObject();try {//放一些常规的key_value值jsonObject.put("name","Alice");jsonObject.put("age",30);jsonObject.put("isStudent", false);//嵌套一个JSON对象JSONObject addressJSON = new JSONObject();addressJSON.put("city","New York");addressJSON.put("zip" , "10001");jsonObject.put("address" , addressJSON);//放一个json数组,类型为stringJSONArray course = new JSONArray();course.put("Math");course.put("Science");course.put("History");jsonObject.put("courses",course);//放一个json数组,类型为intJSONArray grades = new JSONArray();grades.put(85);grades.put(90);grades.put(92);jsonObject.put("grades",grades);jsonObject.put("graduated",null);//把得到的JSON转化为字符串,打印日志查看效果String string = jsonObject.toString();Log.i(TAG, "createJSON: " + string);} catch (JSONException e) {throw new RuntimeException(e);}}
  • put方法放键值对:Json本来就是键值对的形式,所以这里对类型没有要求

  • 放一个对象:其实就是一个Json嵌套一个Json

  • 放Json数组:这里实例化的对象是JSONArray(),然后put方法往里面放就行了

  • 转化为字符串:用toString()方法即可

2:获取JSON中的属性

    private void getJSON(){String json = "{\"name\":\"Alice\",\"age\":30,\"isStudent\":false,\"address\":{\"city\":\"New York\",\"zip\":\"10001\"},\"courses\":[\"Math\",\"Science\",\"History\"],\"grades\":[85,90,92]}";//try {JSONObject jsonObject = new JSONObject(json);//想获取key对应的value,就要用对应类型的get方法String name = jsonObject.getString("name");Log.i(TAG, "getJSON: name =" + name);int age = jsonObject.getInt("age");Log.i(TAG, "getJSON: age = " + age);boolean isStudent = jsonObject.getBoolean("isStudent");Log.i(TAG, "getJSON: isStudent = " + isStudent);JSONObject addressObject = jsonObject.getJSONObject("address");String city = addressObject.getString("city");Log.i(TAG, "getJSON: city = " + city);JSONArray coursesArray = jsonObject.getJSONArray("courses");String course0 = coursesArray.getString(0);Log.i(TAG, "getJSON: 第一个课程是"+course0);//            String string = jsonObject.getString("graduated");
//            Log.i(TAG, "getJSON: "+string);} catch (JSONException e) {throw new RuntimeException(e);}}
  • 实例化JSONObject的时候需要传入JSON字符串
  • 想获取key对应的value,就要用对应类型的get方法

二:Gson介绍

1:依赖

implementation ("com.google.code.gson:gson:2.11.0")

Gson 是 Google 开发的一个 Java 库,主要用于在 Java 对象和 JSON 数据之间进行相互转换,它提供了简单易用的 API 来处理 JSON 序列化(将 Java 对象转为 JSON 字符串)和反序列化(将 JSON 字符串转为 Java 对象)操作。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

2:利用Gson创建JSON字符串

 private void gsonCreateJSON(){//创建Student对象Student student = new Student();student.setName("老龙");student.setAge(19);student.setStudent(true);Student.Address address = new Student.Address();address.setCity("新疆");address.setZip("798");student.setAddress(address);student.setCourses(new String[]{"数学","计算机与科学"});student.setGrades(new Integer[]{100,120});//转化为JSON字符串Gson gson = new Gson();String json = gson.toJson(student);Log.i(TAG, "gsonCreateJSON: " + json);}

效果如下:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

3:利用Gson获取JSON中的属性

private void gsonGetJSON(){String json = "{\"address\":{\"city\":\"新疆\",\"zip\":\"798\"},\"age\":19,\"courses\":[\"数学\",\"计算机与科学\"],\"grades\":[100,120],\"isStudent\":true,\"name\":\"老龙\"}";//相当于把这个JSON字符串解析java对象,在通过get方法获取内部的数据Gson gson = new Gson();Student student = gson.fromJson(json, Student.class);String name = student.getName();Integer[] grades = student.getGrades();Log.i(TAG, "gsonCreateJSON: name = " + name);Log.i(TAG, "gsonCreateJSON: grades[1] = " + grades[1])}

优化:之前在http,封装json请求体时就可以创建一个实体类,解析成一个json字符串

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

注意:解析字符串的时候不要带多余的东西

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

三:安卓网络通信总结

对比维度JSONObjectHttpUrlConnectionOkHttpRetrofit2
核心功能定位Android 原生 JSON 解析 / 构建工具,仅处理 JSON 数据(无 HTTP 能力)Java 原生 HTTP 通信工具,用于发起 HTTP 请求 / 接收响应,需手动处理 JSON 和线程第三方 HTTP 客户端(Square 开发),封装 HttpUrlConnection,简化 HTTP 操作基于 OkHttp 的 RESTful API 框架,通过注解 + 接口化方式封装 HTTP 请求,自动处理 JSON 序列化 / 反序列化
JSON 处理能力
- 解析 JSON(从字符串到对象)需手动调用getXXX()方法(如getString("name")getJSONObject("address")),嵌套结构需逐层解析(见getJSON()方法),无类型安全仅接收 HTTP 响应的 JSON 字符串,需依赖第三方库(如 Gson)手动解析(代码中未体现,需额外处理)仅接收 HTTP 响应的 JSON 字符串,需依赖 Gson 手动调用fromJson()解析(见sendPostRequest()ResLogin resLogin = new Gson().fromJson(json, ResLogin.class)集成GsonConverterFactory后,自动将 JSON 响应解析为指定 JavaBean(如UserInfoQuery),无需手动调用 Gson(见sendGetRequest()中直接获取response.body().getData().getUser().getNickname()
- 构建 JSON(从对象到字符串)需手动调用put()方法(如jsonObject.put("name","Alice")),嵌套对象 / 数组需手动创建JSONObject/JSONArray(见createJSON()方法)需手动拼接 JSON 字符串(如"{ \"account\": \"" + account + "\",\"password\": \"" + password + "\" }"),易出错依赖 Gson 调用toJson()将 JavaBean(如ReqLogin)转为 JSON 字符串(见sendPostRequest()new Gson().toJson(new ReqLogin(account, password))自动将 JavaBean(如ReqLogin)序列化为 JSON 请求体,无需手动处理(仅需在接口方法中传入 JavaBean 参数)
- 类型安全无,需手动判断数据类型(如getInt("age")若字段为字符串会抛异常)无,JSON 字符串解析需手动保证类型匹配依赖 Gson 实现类型安全,但需手动指定目标类完全类型安全,接口方法返回值直接指定响应 JavaBean 类型(如Call<UserInfoQuery>
GET 请求实现
- 核心步骤无 HTTP 能力,无法发起 GET 请求1. 手动创建URL对象;
2. 调用openConnection()获取HttpURLConnection
3. 手动设置请求方法(setRequestMethod("GET"))、超时时间;
4. 手动获取InputStream,通过BufferedReader读取响应;
5. 手动关闭连接(见sendGetRequest()方法)
1. 构建OkHttpClient(可配置超时);
2. 构建Request对象(指定 URL 和GET方法);
3. 调用okHttpClient.newCall(request)获取Call
4. 调用enqueue()异步执行,在Callback中处理响应(见sendGetRequest()方法)
1. 构建Retrofit(指定 BaseURL 和转换器);
2. 定义接口(如ApiServicegetUserInfo(String userId, String type)),用@GET注解指定接口路径和参数;
3. 调用接口方法获取Call
4. 调用enqueue()处理响应(见sendGetRequest()方法)
- 线程处理需手动创建子线程(new Thread(new Runnable() { ... })),更新 UI 需手动调用runOnUiThread()自动在子线程执行请求,Callback回调在子线程,更新 UI 需手动调用runOnUiThread()自动在子线程执行请求,Callback回调在子线程,更新 UI 需手动调用runOnUiThread()(代码中Toast直接调用,因onResponse已在主线程?实际 Retrofit 默认回调在子线程,代码中可能简化处理)
- 参数拼接需手动拼接 URL 参数(如"http://...?user_id=" + id + "&type=archives"需手动拼接 URL 参数(同 HttpUrlConnection)或通过HttpUrl.Builder构建 URL自动拼接参数:通过@Query注解(如getUserInfo(@Query("user_id") String userId, @Query("type") String type)),无需手动拼接
POST 请求实现
- 核心步骤无 HTTP 能力,无法发起 POST 请求1. 同 GET 步骤 1-3,额外设置setDoOutput(true)允许输出请求体;
2. 手动设置请求头(Content-Type: application/json);
3. 手动获取OutputStream,写入 JSON 字符串;
4. 同 GET 步骤 4-5(见SendPostRequest()方法)
1. 同 GET 步骤 1;
2. 构建RequestBody(指定 JSON 媒体类型和 JSON 字符串);
3. 构建Request对象(指定 URL 和post(requestBody));
4. 同 GET 步骤 3-4(见sendPostRequest()方法)
1. 同 GET 步骤 1;
2. 定义接口(如ApiServicelogin(@Body ReqLogin reqLogin)),用@POST注解指定路径,@Body指定请求体;
3. 同 GET 步骤 3-4(见sendPostRequest()方法)
- 请求体处理需手动拼接 JSON 字符串并转为字节流写入(易出错,如引号转义)需手动将 JavaBean 转为 JSON 字符串,再封装为RequestBody自动将@Body注解的 JavaBean(如ReqLogin)转为 JSON 请求体,无需手动处理
- 响应处理手动读取响应流,需手动解析 JSON 字符串Callback中读取response.body().string(),再手动用 Gson 解析Callback中直接获取response.body()(已自动解析为 JavaBean)
优缺点
- 优点1. 原生 API,无需依赖第三方库;
2. 轻量,仅处理 JSON 时性能开销小
1. 原生 API,无需依赖第三方库;
2. 完全可控,可自定义所有 HTTP 细节
1. 封装完善,简化 HTTP 操作(如自动处理连接池、重定向);
2. 支持同步 / 异步请求;
3. 内置超时、拦截器等实用功能
1. 接口化编程,代码结构清晰(分离 API 定义和实现);
2. 自动处理 JSON 序列化 / 反序列化;
3. 支持多种转换器(Gson、Jackson 等);
4. 支持 RxJava、协程等异步框架
- 缺点1. 无 HTTP 能力,需配合其他工具使用;
2. 手动解析 / 构建 JSON 代码繁琐,易出错;
3. 无类型安全
1. 代码冗余(手动处理流、线程、参数拼接);
2. 无默认 JSON 处理,需额外集成;
3. 不支持连接池,性能较差
1. 仍需手动处理 JSON 序列化 / 反序列化(依赖 Gson);
2. 多接口场景下代码仍需重复构建RequestCallback
1. 依赖 Retrofit+OkHttp + 转换器,包体积较大;
2. 简单请求场景下配置稍复杂;
3. 灵活性较低(复杂 HTTP 场景需自定义拦截器)
适用场景1. 仅需单独处理 JSON 数据(如本地 JSON 字符串解析 / 构建);
2. 轻量级场景,不依赖第三方库
1. 学习 HTTP 原理(理解底层流程);
2. 极简场景,不允许引入第三方库;
3. 对 HTTP 细节有高度自定义需求
1. 需简化 HTTP 操作,但无需接口化封装的场景;
2. 需灵活处理 HTTP 细节(如自定义拦截器、请求头);
3. 中小型项目的网络请求
1. 大型项目,需统一管理 API 接口;
2. RESTful API 场景,需规范请求格式;
3. 需集成 RxJava / 协程实现复杂异步逻辑;
4. 追求代码可维护性和类型安全
http://www.dtcms.com/a/358764.html

相关文章:

  • 数据结构青铜到王者第十三话---优先级队列(堆)(2)
  • 中级函数三
  • 如何使用 DeepSeek 帮助自己的工作?—— 从效率工具到能力延伸的实战指南
  • BGP路由协议(四):工作原理
  • Redis 持久化配置
  • 使用python格式化nginx配置文件
  • 【系统分析师】高分论文:论系统测试技术及应用
  • xAI发布全新编码模型 grok‑code‑fast‑1!
  • SpringBoot防止重复提交(2)
  • day44-Ansible变量
  • 联合体和枚举——嵌入式学习笔记
  • 每日算法题【二叉树】:二叉树的最大深度、翻转二叉树、平衡二叉树
  • 【系统分析师】高分论文:论软件的系统测试及应用
  • 栈溢出问题
  • Redis-数据类型的常用操作命令
  • uart学习
  • Jdk动态代理 Cglib动态代理
  • MYSQL表结构优化场景
  • 解构机器学习:如何从零开始设计一个学习系统?
  • folium地图不显示加载不出来空白问题解决
  • SAP PP模块的MPS
  • 福彩双色球第2025100期篮球号码分析
  • git在push和clone等操作时显示‘: Invalid argument
  • 优选算法:二分查找
  • #5:Nginx核心使用技术
  • Java 学习笔记(基础篇12)
  • 小狼毫输入法中让数字键盘上的数字键不再选择候选词而是与原始输入一起直接上屏
  • 计算机视觉与深度学习 | 基于深度学习的图像特征提取与匹配算法综述及MATLAB实现
  • 互联网大厂大模型应用开发岗位面试:技术点详解与业务场景演练
  • nacos3端口漂移问题