移动应用中的解析:本质、数据格式与过程

作者: IT Sectr 发布日期: 2026-03-08 阅读时间: 8 分钟

Parsing — 是对结构化数据进行语法分析的过程,从 JSON、XML、CSV 或 Protobuf 中提取信息供应用程序使用。根据 Square Engineering (2025) 的数据,解析策略的选择直接影响移动应用的性能。流式解析 可以在不将整个文档加载到内存的情况下处理兆字节的数据。

要点

  • 解析 — 将结构化文本分解为词法单元以提取数据,无需强制类型化。
  • JSON — 在 iOS 和 Android 移动应用中 REST API 最流行的格式。
  • 流式解析 在处理大文件和 RSS 订阅时节省内存。
  • 代码生成 — 在编译阶段生成解析器,将运行时速度提高 2-4 倍。
  • Protobuf — 二进制格式,比 JSON 紧凑 3-6 倍,解析速度更快。

什么是解析?

解析(语法分析)— 是将字符序列转换为适合程序处理的结构化表示的过程。在移动开发的背景下,解析指的是分析服务器响应、配置文件、本地缓存和资源文件。每种格式都需要自己的方法:JSON — 轻量级且内置于 SDK 中,XML — 严格且带有 XSD 模式验证,CSV — 用于表格数据的最小化格式,Protobuf — 具有严格模式的二进制格式。

语法分析的阶段

任何解析器,无论格式如何,都经历三个阶段。词法分析 将原始文本分解为词法单元:键、字符串、数字、分隔符和注释。语法分析 检查语法的正确性 — JSON 中的括号平衡、XML 中标签的正确嵌套。输出结构的构建 形成对象表示:JSONObject、Map 或用于进一步处理的令牌流。根据 Apple (2026) 的数据,iOS 上的内置 Foundation 解析器使用惰性解析 — 仅验证 JSON 的开头以节省资源。

手动解析与自动库

手动解析(JSONSerialization、XmlPullParser)可以完全控制过程,适用于非标准格式或需要对每个字段进行自定义验证的情况。自动库(JSONDecoder、Moshi、kotlinx.serialization)加速开发,但隐藏了错误处理的细节。选择取决于需求:如果数据结构是动态的或事先未知 — 手动解析更可取。如果模式是固定的 — 自动反序列化可将代码减少 60-70%。

解析与反序列化的区别

解析 — 更广泛的操作:可以流式执行,不一定要创建类型化对象。反序列化 — 解析的特例,其结果始终是预先已知类的实例,具有特定类型的属性。JSON 解析器将文档解析为 Map 或 JsonElement,而反序列化器将相同的 JSON 转换为具有已知字段和类型的特定 User、Order 或 Product 对象。

特性解析反序列化
结果JsonElement、Map、令牌流类型化对象(User、Order)
流式模式是(SAX、JsonReader)否(整个对象在内存中)
类型化可选,动态类型必需,静态类型
示例XmlPullParser.next()、SAX eventsjson.decodeFromString<User>()

流式解析 — 解析相对于反序列化的主要优势。Android 上的 XmlPullParser 在读取时解析 XML,无需将整个文档加载到 RAM 中。这对于大型 API 响应、包含数百个元素的 RSS 订阅解析或处理来自服务器转储的数千个 JSON 对象数组至关重要。流式解析器逐个读取令牌,消耗恒定量的内存,与文档大小无关。

移动应用中的 JSON 解析

JSON — 主导的数据交换格式。在 iOS 上,内置的 JSONSerialization 将 JSON 解析为 Any,而 JSONDecoder 直接解析为 Codable 结构。在 Android 上,标准的 org.json 提供 JSONObject 和 JSONArray 用于手动解析。Gson 和 Moshi 添加了自动转换。手动和自动方法之间的选择是网络层的第一个架构决策。

kotlin
val jsonString = """{"users":[{"id":1,"name":"Alice"}]}"""
val jsonObject = JSONObject(jsonString)
val usersArray = jsonObject.getJSONArray("users")

for (i in 0 until usersArray.length()) {
    val item = usersArray.getJSONObject(i)
    val id = item.getInt("id")
    val name = item.getString("name")
    // 用户处理
}

通过 org.json 手动解析 在响应结构事先未知或变化很大时很有用。这种方法可以完全控制错误处理和可空字段,但与自动反序列化相比需要更多的样板代码。对于小型项目或原型来说这是可以接受的,但在生产环境中更推荐 Moshi 或 kotlinx.serialization。

用于流式解析的 JSONReader

JsonReader 来自 Moshi 库 — 是流式解析 JSON 的强大工具。它逐个令牌读取文档,使用 beginObject、nextName、nextString、nextInt 和 endObject 方法。这种方法允许处理任何大小的文档,内存消耗恒定。根据 Google (2026) 的数据,通过 JsonReader 进行流式解析比将整个文档加载到 JsonObject 中快 2-3 倍,内存消耗减少高达 80%。

kotlin
val reader = JsonReader(StringReader(json))
reader.beginObject()
while (reader.hasNext()) {
    val name = reader.nextName()
    when (name) {
        "id" -> val id = reader.nextInt()
        "name" -> val name = reader.nextString()
        "email" -> val email = reader.nextString()
        else -> reader.skipValue()
    }
}
reader.endObject()

示例展示了 JsonReader 流式解析 JSON。每次调用 nextName() 和 nextInt() 都会将光标前进到下一个令牌。skipValue() 跳过不需要的字段而不解析它们 — 这在 JSON 包含 50 个字段但只需要 3 个时特别有用。结果是 — 最小的内存消耗和最大的速度。

XML 和 CSV 解析

XML 继续在 Android 项目中用于资源和企业应用程序的 SOAP 服务。在 Android 上,内置的 XmlPullParser 提供流式解析,内存消耗最小 — 它不加载 DOM 树,而是生成 START_TAG、TEXT、END_TAG 事件。iOS 使用 XMLParser 采用委托方法:parser(didStartElement:) 和 parser(foundCharacters:) 方法顺序处理元素。

移动开发中的 CSV

CSV — 用于导出和导入表格数据的最简单格式。在移动应用中,CSV 用于导出报告、加载参考手册(国家、货币、代码列表)和同步离线数据。流式库适用于 CSV 解析:Apache Commons CSVOpenCSV 逐行处理文件,转义值内的引号和逗号。在 iOS 上,CSV 解析可以通过分隔符 NSString.components(separatedBy:) 实现,并处理边缘情况。

swift
class CSVParser: NSObject, XMLParserDelegate {
    private var currentItem: [String: String] = [:]
    private var currentElement: String = ""

    func parser(
        _ parser: XMLParser,
        didStartElement elementName: String,
        namespaceURI: String?,
        qualifiedName qName: String?,
        attributes attributeDict: [String: String]
    ) {
        currentElement = elementName
        if elementName == "item" {
            currentItem = [:]
        }
    }

    func parser(_ parser: XMLParser,
                foundCharacters string: String) {
        currentItem[currentElement] = string
    }
}

iOS 上 XMLParser 委托解析 RSS 订阅的示例。didStartElement 方法在每个开始标签时调用,foundCharacters 返回标签之间的文本内容,didEndElement 完成元素。这种事件驱动的架构允许处理任何大小的 XML,无需将 DOM 树加载到内存中 — 这对资源受限的移动设备至关重要。

Android CSV 库比较

在 Android 上,CSV 解析器的选择取决于数据量。OpenCSV 支持流式 API、用于映射到 POJO 的注解和自定义分隔符。Apache Commons CSV — 更低级别,但在大文件上更快。对于简单情况(1-2 列),通过 String.split(",") 手动解析并处理转义就足够了。对于具有大型 CSV 文件的生产项目,建议使用 OpenCSV。

Protobuf 和流式解析

Protocol Buffers 来自 Google — 二进制序列化格式,在速度和紧凑性方面优于 JSON。Protobuf 消息占用的空间比等效 JSON 少 3-6 倍,由于二进制格式和严格模式,解析速度快 4-10 倍。主要缺点:缺乏人类可读性和需要通过 protoc 编译器从 .proto 文件生成代码。

Protobuf 流式解析 通过 CodedInputStream 实现 — 客户端在消息到达时逐个读取字段,无需加载整个消息。每个字段都有 tag(编号 + 类型),解析器可以跳过未知字段。根据 Google (2026) 的数据,流式 Protobuf 解析在处理 1 MB 及以上的消息时可减少高达 90% 的内存消耗,这对于 RAM 有限的移动设备至关重要。Protobuf-lite — 专为 Android 优化的版本,在生成的代码大小方面进行了优化。

常见问题

JSONSerialization 和 JSONDecoder 有什么区别?

JSONSerialization — 手动解析,返回 Any(Dictionary、Array)无需类型化。JSONDecoder — 自动反序列化为 Codable 类型。JSONSerialisation 为动态结构提供灵活性,JSONDecoder — 为已知模式提供速度和类型安全。在生产环境中建议使用 JSONDecoder。

什么时候应该使用流式解析而不是加载整个文档?

流式解析在以下情况下是 必需的:响应超过 500 KB、解析 RSS/Atom 订阅以及在内存有限的设备上处理文件。对于不超过 100 KB 的典型 API 响应,通过 JSONDecoder 或 Moshi 进行自动反序列化更可取 — 代码更简洁,开发更快。

Android SDK 默认支持哪些数据格式?

Android SDK 包含 org.json(JSONObject、JSONArray)、XmlPullParser(XML)和 android.util.JsonReader。对于 CSV、YAML 和 Protobuf,需要额外的库:OpenCSV 用于 CSV、SnakeYAML 用于 YAML、protobuf-javalite 用于 Protobuf。

如果服务器返回无效的 JSON 怎么办?

在 kotlinx.serialization 中使用 lenient 模式,或在 Moshi 中使用 JsonReader.setLenient(true) — 它容忍多余的逗号、未转义的引号和单行注释。要进行完整验证,请通过 Pact 或 Spring Cloud Contract 实施契约测试。

什么是 SAX 解析,它在哪里使用?

SAX(Simple API for XML)— 流式 XML 解析器,在遍历文档时生成 startElement、characters、endElement 事件。通过 Android 上的 XmlPullParser 和 iOS 上的 XMLParser 实现。用于 RSS 阅读器、离线数据同步和 SVG 文件处理。

总结

  • 解析 — 结构化数据分析的基本操作,比反序列化更广泛:可以是流式的,不需要类型化。
  • JSON — 移动开发中 REST API 的主要格式;受 JSONSerialization(iOS)和 org.json(Android)支持。
  • 流式解析 通过 JsonReader、XmlPullParser 和 SAX 节省内存,对大文档至关重要。
  • Protobuf — 最快、最紧凑的格式,推荐用于高负载和多平台系统。
  • Android 上的 XmlPullParser 和 iOS 上的 XMLParser — 具有事件模型的流式 XML 解析标准工具。
  • CSV 解析器(OpenCSV、Apache Commons CSV)用于导出报告和加载参考数据。
  • 手动解析和自动解析之间的选择取决于数据的 大小、模式的 可变性 和设备的 内存要求

我们将开发一款交钥匙移动应用程序

IT Sectr自2017年以来为初创企业和企业打造iOS和Android应用程序。我们将为您提供咨询并提出最佳解决方案。

讨论项目

另请阅读