Android解析XML有三種方式:DOM(document object model)、SAX(simple api XML)、PULL
1、DOM
DOM解析XML文件時,會將XML文件的所有內容讀取到內存中,然後允許您使用DOM API遍歷XML樹、檢索所需的數據。使用DOM操作XML的代碼看起來比較直觀,並且,在某些方面比基於SAX的實現更加簡單。但是,因爲DOM需要將 XML文件的所有內容讀取到內存中,所以內存的消耗比較大,特別對於運行Android的移動設備來說,因爲設備的資源比較寶貴,所以建議還是採用SAX 來解析XML文件,當然,如果XML文件的內容比較小採用DOM是可行的。
2、SAX
SAX是一個解析速度快並且佔用內存少的xml解析器,非常適合用於Android等移動設備。?SAX解析XML文件採用的是事件驅動,也就是說,它並不需要解析完整個文檔,在按內容順序解析文檔的過程中,SAX會判斷當前讀到的字符是否合法XML語法中的某部分,如果符合就會觸發事件。所謂事件,其實就是一些回調(callback)方法,這些方法(事件)定義在ContentHandler接口。
這種方式解析是一種基於事件驅動的api,有兩個部分,解析器和事件處理器:
- 解析器就是XMLReader接口,負責讀取XML文檔,和向事件處理器發送事件(也是事件源),
- 事件處理器ContentHandler接口,負責對發送的事件響應和進行XML文檔處理。
3、PULL
Pull解析器的運行方式與 SAX 解析器相似,都是輕量級的解析,在Android的內核中已經嵌入了Pull,所以我們不需要再添加第三方jar包來支持Pull。
Pull解析和Sax解析不一樣的地方有
- pull讀取xml文件後觸發相應的事件調用方法返回的是數字
- pull可以在程序中控制想解析到哪裏就可以停止解析。
DOME-smsBackup
public void click(View view) {
// TODO Auto-generated method stub
List<SmsInfo> smsInfos = new ArrayList<SmsInfo>();
Cursor cursor = getContentResolver().query(Uri.parse("content://sms/"),
new String[] { "address", "body", "date", "type" }, null, null,
null);
while (cursor.moveToNext()) {
String address = cursor.getString(0);
String body = cursor.getString(1);
long date = cursor.getLong(2);
int type = cursor.getInt(3);
SmsInfo smsInfo = new SmsInfo(address, body, date, type);
smsInfos.add(smsInfo);
}
SmsUtils.smsBackupXml(smsInfos, getApplicationContext());
cursor.close();
}
public static void smsBackupXml(List<SmsInfo> smsInfos, Context context) {
try {
FileOutputStream fos = new FileOutputStream(new File(
Environment.getExternalStorageDirectory(), "smsBackup.xml"));
XmlSerializer xSerializer = Xml.newSerializer();
xSerializer.setOutput(fos, "utf-8");
xSerializer.startDocument("utf-8", true);
xSerializer.startTag(null, "smss");
for (SmsInfo smsInfo : smsInfos) {
xSerializer.startTag(null, "sms");
xSerializer.attribute(null, "id", smsInfo.getId() + "");
xSerializer.startTag(null, "address");
xSerializer.text(smsInfo.getAddress());
xSerializer.endTag(null, "address");
xSerializer.startTag(null, "body");
xSerializer.text(smsInfo.getBody());
xSerializer.endTag(null, "body");
xSerializer.startTag(null, "date");
xSerializer.text(smsInfo.getDate() + "");
xSerializer.endTag(null, "date");
xSerializer.startTag(null, "type");
xSerializer.text(smsInfo.getType() + "");
xSerializer.endTag(null, "type");
xSerializer.endTag(null, "sms");
}
xSerializer.endTag(null, "smss");
xSerializer.endDocument();
fos.close();
Toast.makeText(context, "備份成功", 1).show();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
Toast.makeText(context, "備份失敗", 1).show();
}
}
這個demo是最簡版,如果要運用到較大數據上時需添加線程,否則會因主線程阻塞導致備份失敗