Android JSON数据解析
Android 开发中 JSON 数据解析方法对比:原生 JSONObject/JSONArray 适合简单场景,Gson 提供自动映射简化代码,Moshi 在 Kotlin 项目中性能更优。三种方式均需添加网络权限,示例展示了从网络请求到解析的完整流程,开发者可根据项目需求选择合适方案。
在 Android 开发中,JSON(JavaScript Object Notation)是网络请求中最常见的数据格式,用于从服务器获取数据或解析本地 JSON 文件。Android 提供了多种方式解析 JSON 数据,包括原生的 JSONObject 和 JSONArray,以及第三方库如 Gson 和 Moshi。以下是 Android JSON 数据解析的详细学习指南,涵盖解析方法、代码示例、结合 HTTP 请求、注意事项和实践建议。
一、JSON 解析方法概述
Android 支持以下主要 JSON 解析方式:
-
JSONObject 和 JSONArray:
- 特点:Android 原生提供的 JSON 解析类,基于
org.json包。 - 优点:无需额外依赖,简单易用。
- 缺点:手动解析代码冗长,易出错,不支持复杂对象映射。
- 适用场景:简单 JSON 数据解析,快速原型开发。
- 特点:Android 原生提供的 JSON 解析类,基于
-
Gson:
- 特点:Google 提供的开源库,将 JSON 自动映射到 Java/Kotlin 对象。
- 优点:代码简洁,支持复杂对象、自定义序列化/反序列化。
- 缺点:需添加依赖,性能略低于 Moshi。
- 适用场景:大多数 Android 项目,适合复杂 JSON 结构。
-
Moshi:
- 特点:Square 提供的轻量级 JSON 解析库,类似 Gson 但更现代。
- 优点:性能高,支持 Kotlin(通过反射或代码生成),类型安全。
- 缺点:需添加依赖,学习曲线稍陡。
- 适用场景:Kotlin 项目,追求高性能或类型安全的场景。
-
Jackson(较少使用):
- 特点:功能强大的 JSON 解析库,支持流式解析。
- 优点:适合大型 JSON 文件或复杂场景。
- 缺点:配置复杂,依赖较重。
- 适用场景:特殊需求或跨平台项目。
二、准备工作
-
网络权限(如从网络获取 JSON 数据):
在AndroidManifest.xml中添加:<uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> -
示例 JSON 数据:
假设以下 JSON 数据用于解析:{ "users": [ { "id": 1, "name": "Alice", "age": 25 }, { "id": 2, "name": "Bob", "age": 30 } ] } -
数据来源:
- 网络请求:通过
HttpURLConnection、OkHttp 或 Retrofit 获取 JSON 数据。 - 本地文件:将 JSON 文件放入
res/raw或assets目录。 - 字符串:直接解析 JSON 字符串。
- 网络请求:通过
-
添加依赖(Gson 或 Moshi):
在build.gradle(app 模块)中添加:// Gson implementation 'com.google.code.gson:gson:2.10.1' // Moshi implementation 'com.squareup.moshi:moshi:1.15.0' // Moshi Kotlin 支持(可选) implementation 'com.squareup.moshi:moshi-kotlin:1.15.0'
三、JSON 解析方法详解与代码示例
以下是使用 JSONObject、Gson 和 Moshi 解析上述 JSON 的代码示例。
1. 使用 JSONObject 和 JSONArray
JSONObject 和 JSONArray 是 Android 原生的 JSON 解析工具。
-
代码示例:
import org.json.JSONArray; import org.json.JSONObject; import java.io.InputStream; import java.util.ArrayList; import java.util.List; public class JsonParser { public static class User { String id, name, age; @Override public String toString() { return "User{id='" + id + "', name='" + name + "', age='" + age + "'}"; } } public static List<User> parseJsonWithJsonObject(String jsonString) throws Exception { List<User> users = new ArrayList<>(); JSONObject jsonObject = new JSONObject(jsonString); JSONArray usersArray = jsonObject.getJSONArray("users"); for (int i = 0; i < usersArray.length(); i++) { JSONObject userObject = usersArray.getJSONObject(i); User user = new User(); user.id = userObject.getString("id"); user.name = userObject.getString("name"); user.age = userObject.getString("age"); users.add(user); } return users; } } -
使用示例(从网络获取 JSON):
new Thread(() -> { try { URL url = new URL("https://api.example.com/users.json"); HttpURLConnection conn = (HttpURLConnection) url.openConnection(); conn.setRequestMethod("GET"); conn.setRequestProperty("Accept", "application/json"); if (conn.getResponseCode() == HttpURLConnection.HTTP_OK) { InputStream inputStream = conn.getInputStream(); String jsonString = new BufferedReader(new InputStreamReader(inputStream)) .lines().collect(Collectors.joining("\n")); inputStream.close(); List<JsonParser.User> users = JsonParser.parseJsonWithJsonObject(jsonString); runOnUiThread(() -> { for (JsonParser.User user : users) { Log.d("JsonObject", user.toString()); } }); } conn.disconnect(); } catch (Exception e) { e.printStackTrace(); } }).start();
2. 使用 Gson
Gson 自动将 JSON 映射到 Java/Kotlin 对象,代码简洁。
-
定义模型类:
public class User { @SerializedName("id") String id; @SerializedName("name") String name; @SerializedName("age") String age; @Override public String toString() { return "User{id='" + id + "', name='" + name + "', age='" + age + "'}"; } } public class UserResponse { @SerializedName("users") List<User> users; } -
解析代码:
import com.google.gson.Gson; import java.io.InputStream; import java.util.List; public class GsonParser { public static List<User> parseJsonWithGson(String jsonString) { Gson gson = new Gson(); UserResponse response = gson.fromJson(jsonString, UserResponse.class); return response.users; } } -
使用示例(从本地 assets 文件解析):
new Thread(() -> { try { InputStream inputStream = getAssets().open("users.json"); String jsonString = new BufferedReader(new InputStreamReader(inputStream)) .lines().collect(Collectors.joining("\n")); inputStream.close(); List<User> users = GsonParser.parseJsonWithGson(jsonString); runOnUiThread(() -> { for (User user : users) { Log.d("Gson", user.toString()); } }); } catch (Exception e) { e.printStackTrace(); } }).start();
3. 使用 Moshi
Moshi 是现代化的 JSON 解析库,特别适合 Kotlin 项目。
-
定义模型类(Kotlin):
data class User( @Json(name = "id") val id: String, @Json(name = "name") val name: String, @Json(name = "age") val age: String ) data class UserResponse( @Json(name = "users") val users: List<User> ) -
解析代码(Kotlin):
import com.squareup.moshi.Moshi import com.squareup.moshi.kotlin.reflect.KotlinJsonAdapterFactory import java.io.InputStream object MoshiParser { fun parseJsonWithMoshi(jsonString: String): List<User> { val moshi = Moshi.Builder() .add(KotlinJsonAdapterFactory()) .build() val adapter = moshi.adapter(UserResponse::class.java) return adapter.fromJson(jsonString)?.users ?: emptyList() } } -
使用示例(从网络获取 JSON,Kotlin 协程):
suspend fun fetchAndParseJson(urlString: String): List<User> = withContext(Dispatchers.IO) { val url = URL(urlString) val conn = url.openConnection() as HttpURLConnection try { conn.requestMethod = "GET" conn.setRequestProperty("Accept", "application/json") if (conn.responseCode == HttpURLConnection.HTTP_OK) { val jsonString = conn.inputStream.bufferedReader().use { it.readText() } MoshiParser.parseJsonWithMoshi(jsonString) } else { emptyList() } } finally { conn.disconnect() } } // 调用 lifecycleScope.launch { try { val users = fetchAndParseJson("https://api.example.com/users.json") users.forEach { Log.d("Moshi", it.toString()) } } catch (e: Exception) { e.printStackTrace() } }
四、结合 HttpURLConnection 获取 JSON 数据
以下是使用 HttpURLConnection 获取 JSON 数据并用 Gson 解析的完整示例:
public void fetchAndParseJson(String urlString) {
new Thread(() -> {
HttpURLConnection conn = null;
try {
// 1. 获取 JSON 数据
URL url = new URL(urlString);
conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("GET");
conn.setConnectTimeout(5000);
conn.setRequestProperty("Accept", "application/json");
if (conn.getResponseCode() == HttpURLConnection.HTTP_OK) {
String jsonString = new BufferedReader(new InputStreamReader(conn.getInputStream()))
.lines().collect(Collectors.joining("\n"));
// 2. 解析 JSON
List<User> users = GsonParser.parseJsonWithGson(jsonString);
// 3. 更新 UI
runOnUiThread(() -> {
for (User user : users) {
Log.d("Gson", user.toString());
}
});
} else {
Log.e("Error", "Response Code: " + conn.getResponseCode());
}
} catch (Exception e) {
e.printStackTrace();
} finally {
if (conn != null) {
conn.disconnect();
}
}
}).start();
}
五、解析方法对比
| 解析方法 | 依赖 | 代码复杂性 | 性能 | 适用场景 |
|---|---|---|---|---|
| JSONObject | 无 | 高 | 中等 | 简单 JSON,快速原型开发 |
| Gson | 需要依赖 | 低 | 高 | 复杂 JSON,Java/Kotlin 项目 |
| Moshi | 需要依赖 | 低 | 更高 | Kotlin 项目,追求性能 |
| Jackson | 需要依赖 | 高 | 高 | 大型 JSON 或跨平台项目 |
- 推荐:Android 项目优先使用 Gson(Java/Kotlin)或 Moshi(Kotlin),简单场景可使用
JSONObject。 - 选择依据:
- 简单 JSON:使用
JSONObject。 - 复杂对象映射:使用 Gson 或 Moshi。
- Kotlin 项目:优先 Moshi。
- 简单 JSON:使用
六、注意事项
- 异步处理:
- JSON 解析通常与网络请求结合,必须在子线程执行,避免
NetworkOnMainThreadException。 - 使用 Thread、AsyncTask(已废弃)或 Kotlin 协程。
- JSON 解析通常与网络请求结合,必须在子线程执行,避免
- 错误处理:
- 处理
JSONException(JSONObject)、JsonParseException(Gson)或IOException(Moshi)。 - 检查 HTTP 状态码和 JSON 格式是否正确。
- 示例:
try { JSONObject jsonObject = new JSONObject(jsonString); } catch (JSONException e) { Log.e("Error", "Invalid JSON: " + e.getMessage()); }
- 处理
- 资源释放:
- 关闭
InputStream和HttpURLConnection。 - 示例:
inputStream.close(); conn.disconnect();
- 关闭
- 性能优化:
- 使用 Gson 或 Moshi 映射对象,减少手动解析代码。
- 缓存解析结果,减少重复解析。
- 对于大型 JSON,考虑流式解析(如 Jackson 的
JsonParser)。
- 安全性:
- 验证 JSON 数据来源,避免解析恶意数据。
- 使用
@SerializedName(Gson)或@Json(Moshi)确保字段映射正确。
- 编码处理:
- 确保 JSON 数据编码为 UTF-8:
String jsonString = new BufferedReader(new InputStreamReader(inputStream, "UTF-8")) .lines().collect(Collectors.joining("\n"));
- 确保 JSON 数据编码为 UTF-8:
七、学习建议与实践
- 学习路径:
- 了解 JSON 结构(对象、数组、嵌套)。
- 掌握
JSONObject和JSONArray的基本使用。 - 学习 Gson 自动映射对象,处理复杂 JSON。
- 在 Kotlin 项目中使用 Moshi,结合协程。
- 结合
HttpURLConnection或 OkHttp 获取 JSON 数据。
- 实践项目:
- 简单项目:调用公开 API(如 OpenWeatherMap),解析天气 JSON 数据。
- 进阶项目:实现用户列表应用,解析嵌套 JSON,显示在 RecyclerView。
- 本地文件:将 JSON 文件放入
res/raw或assets,练习解析。
- 调试工具:
- 使用 Postman 测试 JSON API,验证响应。
- 使用 Charles 抓包,分析 JSON 数据。
- 使用 Android Studio 的 Logcat 查看解析结果。
- 推荐资源:
- Gson 文档:https://github.com/google/gson
- Moshi 文档:https://github.com/square/moshi
- Android 官方文档:https://developer.android.com/reference/org/json/JSONObject
- 实践 API:https://api.github.com/users 或 https://openweathermap.org/api
八、Kotlin 协程与 Retrofit 示例
结合 Retrofit 和 Moshi,异步解析 JSON(Kotlin):
-
Retrofit 接口:
interface ApiService { @GET("users.json") suspend fun getUsers(): UserResponse } -
配置 Retrofit:
val moshi = Moshi.Builder() .add(KotlinJsonAdapterFactory()) .build() val retrofit = Retrofit.Builder() .baseUrl("https://api.example.com/") .addConverterFactory(MoshiConverterFactory.create(moshi)) .build() val apiService = retrofit.create(ApiService::class.java) -
调用和解析:
lifecycleScope.launch { try { val users = apiService.getUsers().users users.forEach { Log.d("Moshi", it.toString()) } } catch (e: Exception) { e.printStackTrace() } }
九、总结
- 解析方法:
- JSONObject/JSONArray:原生,适合简单 JSON。
- Gson:自动映射,适合复杂 JSON,Java/Kotlin 通用。
- Moshi:轻量高效,适合 Kotlin 项目。
- 结合网络:使用
HttpURLConnection、OkHttp 或 Retrofit 获取 JSON 数据,异步解析。 - 注意事项:异步处理、错误处理、资源释放、编码一致。
- 推荐:优先使用 Gson 或 Moshi,新项目结合 Retrofit 和协程。
- 实践:调用 JSON API 或解析本地文件,结合调试工具验证。
如果需要更详细的代码示例(如解析复杂嵌套 JSON、自定义 Gson 序列化)、第三方库对比或特定场景的讲解,请告诉我!
火山引擎开发者社区是火山引擎打造的AI技术生态平台,聚焦Agent与大模型开发,提供豆包系列模型(图像/视频/视觉)、智能分析与会话工具,并配套评测集、动手实验室及行业案例库。社区通过技术沙龙、挑战赛等活动促进开发者成长,新用户可领50万Tokens权益,助力构建智能应用。
更多推荐
所有评论(0)