我正在为我的 android 应用程序开发一项新功能,以启用数据备份和恢复。我正在使用 XML 文件来备份数据。这是为输出文件设置编码的一段代码:
XmlSerializer serializer = Xml.newSerializer();
FileWriter fileWriter = new FileWriter(file, false);
serializer.setOutput(fileWriter);
serializer.startDocument("UTF-8", true);
[... Write data to the file....]
这就是我尝试从 XML 文件导入数据的方式。首先,我检查编码是否正确:
XmlPullParser parser = Xml.newPullParser();
FileReader reader = new FileReader(file);
parser.setFeature(XmlPullParser.FEATURE_PROCESS_NAMESPACES, false);
parser.setInput(reader);
if(!"UTF-8".equals(parser.getInputEncoding())) {
throw new IOException("Incorrect file encoding");
}
[... Read data from the file....]
在这里我遇到了一个问题。此代码在 Android 2.3.3(设备和模拟器)上运行良好,编码被正确检测为“UTF-8”。但是在 API11+ 版本(Honeycomb、ICS、JB)上会抛出异常。当我在调试模式下运行它时,我可以看到 parser.getInputEncoding() 返回null
。我检查了在 2.3.3 及更高版本上生成的实际 XML 文件,它们具有完全相同的标题:<?xml version='1.0' encoding='UTF-8' standalone='yes' ?>
. 为什么 getInputEncoding() 在 API11+ 上返回 null?
其他发现:
我发现有一种方法可以正确检测 API11+ 设备上的文件编码,FileInputStream
而不是FileReader
像这样:
XmlPullParser parser = Xml.newPullParser();
FileInputStream stream = new FileInputStream(file);
parser.setFeature(XmlPullParser.FEATURE_PROCESS_NAMESPACES, false);
parser.setInput(stream, null);
if(!"UTF-8".equals(parser.getInputEncoding())) {
throw new IOException("Incorrect file encoding");
}
[... Read data from the file....]
在这种情况下,getInputEncoding() 可以正确检测 API11+ 模拟器和设备上的 UTF-8 编码,但它在 2.3.3 上返回 null。所以现在我可以在代码中插入一个 fork 来使用 API11+ 上的 FileReader 和 pre-API11 上的 FileInputStream:
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
parser.setInput(stream, null);
} else {
parser.setInput(reader);
}
但是使用 XmlPullParser.getInputEncoding() 检查编码的正确方法是什么?为什么不同版本的 Android 行为会有所不同,具体取决于我使用哪一个:FileInputStream 还是 FileReader?