在Android开发中,XML文件经常被用来存储配置信息、传输结构化数据,Pull解析是Android系统原生支持的XML处理方式,具有解析速度快、内存占用低的优势,既可以生成XML文件,也可以解析已有的XML内容。

Pull解析核心原理
Pull解析采用事件驱动的模式,解析器会按照XML文档的顺序逐个触发事件,开发者可以通过调用next方法主动获取下一个事件类型,常见的事件类型包括文档开始、标签开始、标签文本、标签结束、文档结束等,不需要像SAX解析那样强制监听所有事件,控制逻辑更加灵活。
使用Pull方式创建XML文件
Android提供了XmlSerializer类来通过Pull方式生成XML文件,我们可以通过以下步骤完成XML的创建:
- 获取XmlSerializer实例,通过Xml.newSerializer方法得到
- 设置输出流,指定生成的XML文件保存的路径和编码格式
- 依次写入XML的声明、各个标签、属性以及文本内容
- 完成写入后关闭输出流
完整创建代码示例
以下代码演示在应用的内部存储目录下生成一个包含用户信息的XML文件:
import android.util.Xml;
import org.xmlpull.v1.XmlSerializer;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
public class XmlCreator {
public void createUserXml(File saveDir) throws IOException {
// 创建保存文件的路径
if (!saveDir.exists()) {
saveDir.mkdirs();
}
File xmlFile = new File(saveDir, "user_info.xml");
FileOutputStream fos = new FileOutputStream(xmlFile);
// 获取XmlSerializer实例
XmlSerializer serializer = Xml.newSerializer();
// 设置输出流和编码
serializer.setOutput(fos, "UTF-8");
// 写入XML声明
serializer.startDocument("UTF-8", true);
// 写入根标签
serializer.startTag(null, "users");
// 写入第一个用户标签
serializer.startTag(null, "user");
serializer.attribute(null, "id", "1");
serializer.startTag(null, "name");
serializer.text("张三");
serializer.endTag(null, "name");
serializer.startTag(null, "age");
serializer.text("25");
serializer.endTag(null, "age");
serializer.endTag(null, "user");
// 写入第二个用户标签
serializer.startTag(null, "user");
serializer.attribute(null, "id", "2");
serializer.startTag(null, "name");
serializer.text("李四");
serializer.endTag(null, "name");
serializer.startTag(null, "age");
serializer.text("28");
serializer.endTag(null, "age");
serializer.endTag(null, "user");
// 结束根标签
serializer.endTag(null, "users");
// 结束文档
serializer.endDocument();
// 关闭流
fos.close();
}
}使用Pull方式解析XML文件
解析XML需要使用XmlPullParser类,同样通过Xml.newPullParser方法获取实例,然后设置输入流,循环获取事件类型直到文档结束,根据事件类型做对应的处理逻辑。
完整解析代码示例
以下代码解析上面生成的user_info.xml文件,提取出每个用户的id、姓名和年龄信息:
import android.util.Xml;
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
public class XmlParser {
public List<User> parseUserXml(File xmlFile) throws IOException, XmlPullParserException {
List<User> userList = new ArrayList<>();
FileInputStream fis = new FileInputStream(xmlFile);
XmlPullParser parser = Xml.newPullParser();
// 设置输入流和编码
parser.setInput(fis, "UTF-8");
// 获取初始事件类型
int eventType = parser.getEventType();
User currentUser = null;
String currentTagName = null;
while (eventType != XmlPullParser.END_DOCUMENT) {
switch (eventType) {
case XmlPullParser.START_TAG:
currentTagName = parser.getName();
if ("user".equals(currentTagName)) {
// 遇到user标签,创建新用户对象
currentUser = new User();
// 获取id属性
String userId = parser.getAttributeValue(null, "id");
currentUser.setId(Integer.parseInt(userId));
}
break;
case XmlPullParser.TEXT:
// 处理标签内的文本内容
if (currentUser != null && currentTagName != null) {
String text = parser.getText();
if ("name".equals(currentTagName)) {
currentUser.setName(text);
} else if ("age".equals(currentTagName)) {
currentUser.setAge(Integer.parseInt(text));
}
}
break;
case XmlPullParser.END_TAG:
if ("user".equals(parser.getName())) {
// user标签结束,将用户加入列表
userList.add(currentUser);
currentUser = null;
}
currentTagName = null;
break;
}
// 获取下一个事件
eventType = parser.next();
}
fis.close();
return userList;
}
// 用户实体类
static class User {
private int id;
private String name;
private int age;
public void setId(int id) {
this.id = id;
}
public void setName(String name) {
this.name = name;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return "User{id=" + id + ", name='" + name + "', age=" + age + "}";
}
}
}注意事项
- 创建XML时,startTag和endTag必须成对出现,否则会生成格式错误的XML文件
- 解析XML时,需要正确处理文本事件,避免空白字符被误判为有效内容
- 所有的流操作都需要放在try-catch块中,或者抛出对应的异常,防止IO异常导致程序崩溃
- XmlSerializer和XmlPullParser都是线程不安全的,不要在多线程环境下共享同一个实例
Android_Pull解析XML创建XML解析Android开发修改时间:2026-06-03 15:12:41