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

《Android 应用开发基础教程》——第十章:使用 Gson 实现网络 JSON 数据解析与对象映射

目录

第十章:使用 Gson 实现网络 JSON 数据解析与对象映射

🔹 10.1 什么是 Gson?

🔸 10.2 添加依赖

🔸 10.3 基础使用

✦ 示例 JSON 字符串:

✦ 定义对应的 Java 类:

✦ JSON ➜ 对象(反序列化):

✦ 对象 ➜ JSON(序列化):

🔸 10.4 解析 JSON 数组

✦ 示例 JSON 数组:

✦ Java 代码解析(使用 TypeToken):

🔸 10.5 配合 OkHttp 实战应用

✦ 示例:请求服务器返回 JSON,并转换成对象

✦ 示例实体类 Post:

✅ 小技巧与注意事项

🧪 实战练习建议

习题答案

项目结构

1. MainActivity.java

2. NewsAdapter.java

3. NewsItem.java

4. GsonUtils.java

5. activity_main.xml

6. item_news.xml

总结


第十章:使用 Gson 实现网络 JSON 数据解析与对象映射

        在进行网络请求时,服务器返回的数据大多是 JSON 格式。手动解析 JSON 字符串非常繁琐,因此我们通常使用第三方库如 Gson 来将 JSON 数据自动转为 Java 对象,方便开发与维护。


🔹 10.1 什么是 Gson?

Gson 是 Google 提供的 JSON 库,能轻松实现:

  • JSON ➜ Java 对象(反序列化)

  • Java 对象 ➜ JSON 字符串(序列化)


🔸 10.2 添加依赖

build.gradle 文件中添加:

implementation 'com.google.code.gson:gson:2.10.1'


🔸 10.3 基础使用

✦ 示例 JSON 字符串:

{"id": 1,"title": "Gson 教程","author": "Alice"
}


✦ 定义对应的 Java 类:

public class Article {private int id;private String title;private String author;// Getter/Setter 省略,可使用 Lombok 自动生成
}


✦ JSON ➜ 对象(反序列化):

String json = "{\"id\":1,\"title\":\"Gson 教程\",\"author\":\"Alice\"}";Gson gson = new Gson();
Article article = gson.fromJson(json, Article.class);Log.d("GSON", "标题:" + article.getTitle());


✦ 对象 ➜ JSON(序列化):

Article article = new Article();
article.setId(2);
article.setTitle("新文章");
article.setAuthor("Bob");String json = gson.toJson(article);
Log.d("GSON", "JSON字符串:" + json);


🔸 10.4 解析 JSON 数组

✦ 示例 JSON 数组:

[{"id": 1, "title": "A"},{"id": 2, "title": "B"}
]


✦ Java 代码解析(使用 TypeToken):

String jsonArray = "[{\"id\":1,\"title\":\"A\"},{\"id\":2,\"title\":\"B\"}]";Type listType = new TypeToken<List<Article>>(){}.getType();
List<Article> articles = new Gson().fromJson(jsonArray, listType);for (Article a : articles) {Log.d("GSON", a.getTitle());
}


🔸 10.5 配合 OkHttp 实战应用

✦ 示例:请求服务器返回 JSON,并转换成对象

OkHttpClient client = new OkHttpClient();
Request request = new Request.Builder().url("https://jsonplaceholder.typicode.com/posts/1").build();client.newCall(request).enqueue(new Callback() {@Overridepublic void onFailure(Call call, IOException e) {e.printStackTrace();}@Overridepublic void onResponse(Call call, Response response) throws IOException {String json = response.body().string();// 解析 JSON 到 Java 对象Gson gson = new Gson();Post post = gson.fromJson(json, Post.class);Log.d("GSON", "标题:" + post.getTitle());}
});


✦ 示例实体类 Post

public class Post {private int userId;private int id;private String title;private String body;// Getter 和 Setter
}


✅ 小技巧与注意事项

问题建议
字段名不一致@SerializedName("json字段") 标注
多层嵌套 JSON创建多个内部类解析
忽略某些字段使用 transient@Expose 注解

🧪 实战练习建议

  1. 请求网络中的新闻 JSON,并展示在 RecyclerView

  2. 把用户输入保存为对象,用 Gson 写入本地文件或 SharedPreferences

  3. 写一个工具类封装 GsonUtils,实现常规解析函数


📢 下一章预告:

第十一章:Android 中的图片加载与缓存(Glide 使用详解)


习题答案

项目结构

MainActivity.java
NewsAdapter.java
GsonUtils.java
activity_main.xml
item_news.xml

1. MainActivity.java

package com.example.demo;import android.os.Bundle;
import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
import org.json.JSONArray;
import org.json.JSONObject;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;public class MainActivity extends AppCompatActivity {private RecyclerView recyclerView;private NewsAdapter adapter;private List<NewsItem> newsList;private OkHttpClient client;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);recyclerView = findViewById(R.id.recyclerView);recyclerView.setLayoutManager(new LinearLayoutManager(this));newsList = new ArrayList<>();adapter = new NewsAdapter(newsList);recyclerView.setAdapter(adapter);client = new OkHttpClient();fetchNewsData();}private void fetchNewsData() {String url = "https://newsapi.org/v2/top-headlines?country=us&apiKey=YOUR_API_KEY"; // 替换为你的 API 密钥Request request = new Request.Builder().url(url).build();client.newCall(request).enqueue(new Callback() {@Overridepublic void onFailure(Call call, IOException e) {runOnUiThread(() -> adapter.updateData(new ArrayList<>()));}@Overridepublic void onResponse(Call call, Response response) throws IOException {if (response.isSuccessful()) {try {String responseData = response.body().string();JSONObject jsonObject = new JSONObject(responseData);JSONArray articles = jsonObject.getJSONArray("articles");List<NewsItem> newsItems = new ArrayList<>();for (int i = 0; i < articles.length(); i++) {JSONObject article = articles.getJSONObject(i);String title = article.getString("title");String description = article.getString("description");newsItems.add(new NewsItem(title, description));}runOnUiThread(() -> adapter.updateData(newsItems));} catch (Exception e) {e.printStackTrace();runOnUiThread(() -> adapter.updateData(new ArrayList<>()));}} else {runOnUiThread(() -> adapter.updateData(new ArrayList<>()));}}});}
}

2. NewsAdapter.java

package com.example.demo;import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import java.util.List;public class NewsAdapter extends RecyclerView.Adapter<NewsAdapter.ViewHolder> {private List<NewsItem> newsList;public NewsAdapter(List<NewsItem> newsList) {this.newsList = newsList;}@NonNull@Overridepublic ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_news, parent, false);return new ViewHolder(view);}@Overridepublic void onBindViewHolder(@NonNull ViewHolder holder, int position) {NewsItem item = newsList.get(position);holder.textViewTitle.setText(item.getTitle());holder.textViewDescription.setText(item.getDescription());}@Overridepublic int getItemCount() {return newsList.size();}public void updateData(List<NewsItem> newData) {newsList.clear();newsList.addAll(newData);notifyDataSetChanged();}public static class ViewHolder extends RecyclerView.ViewHolder {TextView textViewTitle;TextView textViewDescription;public ViewHolder(@NonNull View itemView) {super(itemView);textViewTitle = itemView.findViewById(R.id.textViewTitle);textViewDescription = itemView.findViewById(R.id.textViewDescription);}}
}

3. NewsItem.java

package com.example.demo;public class NewsItem {private String title;private String description;public NewsItem(String title, String description) {this.title = title;this.description = description;}public String getTitle() {return title;}public String getDescription() {return description;}
}

4. GsonUtils.java

package com.example.demo;import android.content.Context;
import android.content.SharedPreferences;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStreamReader;
import java.lang.reflect.Type;
import java.util.List;public class GsonUtils {private static final Gson gson = new Gson();// 将对象写入 SharedPreferencespublic static void saveObjectToSharedPreferences(Context context, String key, Object object) {SharedPreferences sharedPreferences = context.getSharedPreferences("app_prefs", Context.MODE_PRIVATE);String json = gson.toJson(object);sharedPreferences.edit().putString(key, json).apply();}// 从 SharedPreferences 读取对象public static <T> T getObjectFromSharedPreferences(Context context, String key, Class<T> classOfT) {SharedPreferences sharedPreferences = context.getSharedPreferences("app_prefs", Context.MODE_PRIVATE);String json = sharedPreferences.getString(key, null);return json == null ? null : gson.fromJson(json, classOfT);}// 将对象写入本地文件public static void saveObjectToFile(Context context, String fileName, Object object) {try (FileOutputStream fos = context.openFileOutput(fileName, Context.MODE_PRIVATE)) {String json = gson.toJson(object);fos.write(json.getBytes());} catch (Exception e) {e.printStackTrace();}}// 从本地文件读取对象public static <T> T getObjectFromFile(Context context, String fileName, Class<T> classOfT) {try (FileInputStream fis = context.openFileInput(fileName);BufferedReader reader = new BufferedReader(new InputStreamReader(fis))) {StringBuilder json = new StringBuilder();String line;while ((line = reader.readLine()) != null) {json.append(line);}return gson.fromJson(json.toString(), classOfT);} catch (Exception e) {e.printStackTrace();return null;}}// 将列表写入本地文件public static <T> void saveListToFile(Context context, String fileName, List<T> list) {Type type = new TypeToken<List<T>>() {}.getType();try (FileOutputStream fos = context.openFileOutput(fileName, Context.MODE_PRIVATE)) {String json = gson.toJson(list, type);fos.write(json.getBytes());} catch (Exception e) {e.printStackTrace();}}// 从本地文件读取列表public static <T> List<T> getListFromFile(Context context, String fileName, Type type) {try (FileInputStream fis = context.openFileInput(fileName);BufferedReader reader = new BufferedReader(new InputStreamReader(fis))) {StringBuilder json = new StringBuilder();String line;while ((line = reader.readLine()) != null) {json.append(line);}return gson.fromJson(json.toString(), type);} catch (Exception e) {e.printStackTrace();return null;}}
}

5. activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="match_parent"android:layout_height="match_parent"android:orientation="vertical"><androidx.recyclerview.widget.RecyclerViewandroid:id="@+id/recyclerView"android:layout_width="match_parent"android:layout_height="match_parent"android:padding="8dp" />
</LinearLayout>

6. item_news.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="match_parent"android:layout_height="wrap_content"android:orientation="vertical"android:padding="8dp"><TextViewandroid:id="@+id/textViewTitle"android:layout_width="match_parent"android:layout_height="wrap_content"android:text="Title"android:textSize="18sp"android:textStyle="bold" /><TextViewandroid:id="@+id/textViewDescription"android:layout_width="match_parent"android:layout_height="wrap_content"android:text="Description"android:textSize="14sp" />
</LinearLayout>

总结

  1. 网络请求:通过 OkHttp 获取新闻 JSON 数据并展示在 RecyclerView 中。
  2. 数据存储
    • 使用 GsonUtils 将用户输入的对象保存到本地文件或 SharedPreferences
    • 提供了多种存储和解析方法(如单个对象、列表等)。
  3. 工具类:封装了 GsonUtils,方便复用。

http://www.xdnf.cn/news/3412.html

相关文章:

  • STM32移植U8G2
  • 【Java面试笔记:安全】31.你了解Java应用开发中的注入攻击吗?
  • 21.2Linux中的LCD驱动实验(驱动)_csdn
  • 【大模型】图像生成:ESRGAN:增强型超分辨率生成对抗网络的革命性突破
  • 二叉树删除结点详细代码
  • 计算机视觉(CV)技术的优势和挑战(本片为InsCode)
  • OpenGL-ES 学习(9) ---- OpenGL-ES 简介和基本 Pipeline
  • 如何通过日志在本地调试LangChain编写的程序?
  • 《跨越边界:探索跨端框架中通用状态管理方案设计》
  • Android面试总结之GC算法篇
  • 如何将 VS Code 与 Linux 系统高效连接:从入门到进阶
  • 学习笔记:Qlib 量化投资平台框架 — MAIN COMPONENTS Part Ⅳ
  • 【HarmonyOS】作业三 UI
  • CMake管理外部依赖的模块
  • 普通 html 项目也可以支持 scss_sass
  • 一个linux系统电脑,一个windows电脑,怎么实现某一个文件夹共享
  • 使用Delphi 和 CrossVcl 开发基于VCL的 macOS 和 Linux 应用程序简介
  • C++11新的特性
  • 基本功能学习
  • 从 Python 基础到 Django 实战 —— 数据类型驱动的 Web 开发之旅
  • 系统思考:企业效率提升关键
  • Unity动态列表+UniTask异步数据请求
  • 如何测试调用RagFlow的API功能
  • 《社交类应用开发:React Native与Flutter的抉择》
  • 【Java】HashMap
  • JGA811Ⅱ大气污染治理实训平台实验装置
  • Python学习笔记(第三部分)
  • (007)Excel 公式的使用
  • 【Machine Learning Q and AI 读书笔记】- 04 彩票假设
  • Linux系统中升级GNU Make构建工具版本至4.4.1