所谓序列化就是将内存数据写到文件中去,以序列化方式生成XML文件要比传统的方式要安全简单的多,至于传统的方式这里就不再多说,这里以模拟将短信备份到SD卡的方式为例:
先创建一个实体类,模拟短信数据
public class SmssInfo {
private long date;//时间
private int type;//类型,如发送、接收
private String body;//短信的内容
private String address;//电话号码
private int id;//每条短信的id
public SmssInfo(){
}
public SmssInfo(long date, int type, String body, String address, int id) {
super();
this.date = date;
this.type = type;
this.body = body;
this.address = address;
this.id = id;
}
public long getDate() {
return date;
}
public void setDate(long date) {
this.date = date;
}
public int getType() {
return type;
}
public void setType(int type) {
this.type = type;
}
public String getBody() {
return body;
}
public void setBody(String body) {
this.body = body;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
}
封装一个方法用于初始化短信数据
private void initSmsData()
{
//定义一集合模拟短信数据
smsdata = new ArrayList<SmssInfo>();
Random random = new Random();//随机数
long number = 13300000001L;
for(int i = 0; i < 10; i++){
smsdata.add(new SmssInfo(System.currentTimeMillis(), random.nextInt(2) + 1,
"短信内容" + i, Long.toString(number + i), i));
}
}
在Button按钮下实现如下代码,即将短信生成XML文件备份到SD卡中:
try {
//获得一个序列化器
XmlSerializer serializer = Xml.newSerializer();
//将生成的XML文件存储到SD卡
File file = new File(Environment.getExternalStorageDirectory(),"backup.xml");
FileOutputStream os = new FileOutputStream(file);
//第一个参数为要写入的输出流,第二个参数为编码方式
serializer.setOutput(os, "utf-8");
serializer.startDocument("utf-8", true);//开始文档编辑
//开始文档的标签,第一个参数为命名空间,第二个参数为标签名称,下同
serializer.startTag(null, "smss");
//开始编辑文档内容
for(SmssInfo info : smsdata){
//每一个对象的开始标签
serializer.startTag(null, "sms");
//编辑开始标签属性
serializer.attribute(null, "id", info.getId() + "");
//编辑对象内容
serializer.startTag(null, "body");
serializer.text(info.getBody());
serializer.endTag(null, "body");
serializer.startTag(null, "date");
serializer.text(info.getDate() + "");
serializer.endTag(null, "date");
serializer.startTag(null, "type");
serializer.text(info.getType() + "");
serializer.endTag(null, "type");
serializer.startTag(null, "address");
serializer.text(info.getAddress());
serializer.endTag(null, "address");
serializer.endTag(null, "sms");
}
serializer.endTag(null, "smss");
serializer.endDocument();//结束文档编辑
os.close();//关闭流
Toast.makeText(this, "备份成功", 0).show();
} catch (Exception e) {
e.printStackTrace();
}
执行之后会在mnt的sdcard目录下生成一个XML文件
即:
<?xml version='1.0' encoding='utf-8' standalone='yes' ?>
<smss>
<sms id="0">
<body>短信内容0</body>
<date>1444981925951</date>
<type>1</type>
<address>13300000001</address>
</sms>
<sms id="1">
<body>短信内容1</body>
<date>1444981925951</date>
<type>1</type>
<address>13300000002</address>
</sms>
<sms id="2">
<body>短信内容2</body>
<date>1444981925952</date>
<type>1</type>
<address>13300000003</address>
</sms>
<sms id="3">
<body>短信内容3</body>
<date>1444981925952</date>
<type>2</type>
<address>13300000004</address>
</sms>
<sms id="4">
<body>短信内容4</body>
<date>1444981925952</date>
<type>1</type>
<address>13300000005</address>
</sms>
<sms id="5">
<body>短信内容5</body>
<date>1444981925952</date>
<type>2</type>
<address>13300000006</address>
</sms>
<sms id="6">
<body>短信内容6</body>
<date>1444981925952</date>
<type>2</type>
<address>13300000007</address>
</sms>
<sms id="7">
<body>短信内容7</body>
<date>1444981925952</date>
<type>2</type>
<address>13300000008</address>
</sms>
<sms id="8">
<body>短信内容8</body>
<date>1444981925952</date>
<type>2</type>
<address>13300000009</address>
</sms>
<sms id="9">
<body>短信内容9</body>
<date>1444981925952</date>
<type>2</type>
<address>13300000010</address>
</sms>
</smss>
Pull解析:pull解析的特点是判断标签的类型,即判断是开始标签还是结束标签,解析到开始或结束标签时根据当前标签名称就可对相应的数据进行相应的操作,而sax解析则是从头读到尾依次解析
这里的解析文件就以上面生成的文件为例:
下面我以方法的形式展示,该方法的参数为文件地址,返回的是一个集合,其内实体类还是刚才创建的实体类,其中的异常我只做了简单的处理直接抛出去了
private ArrayList<SmssInfo> pullDemo(FileInputStream is) throws Exception
{
//获得一个解析器
XmlPullParser parser = Xml.newPullParser();
//初始化解析器,第一个参数为要解析的文件(输出流),第二个参数为该文件的编码方式
parser.setInput(is, "utf-8");
//定义集合存储解析的数据
ArrayList<SmssInfo> pullData = null;
//定义实体类存储对象信息
SmssInfo smsInfo = null;
//获得文档标签的类型,比如文档的开始结束标签、内容的开始结束tag
int type = parser.getEventType();
//没到文档结束的时候就继续解析
while(type != XmlPullParser.END_DOCUMENT)
{
switch (type) {
case XmlPullParser.START_TAG://如果是开始标签(标签中没带“/”的即为开始标签)
//如果当前标签(parser.getName())为相对应的标签则进行相应的操作
if("smss".equals(parser.getName()))
{
//开始解析文档时实例化集合
pullData = new ArrayList<SmssInfo>();
}else if("sms".equals(parser.getName())){
//解析到内容开始标签时实例化实体类对象
smsInfo = new SmssInfo();
//获取这个标签的属性,参数0为该属性所在的索引值
String idStr = parser.getAttributeValue(0);
//将值设置到对象中
smsInfo.setId(Integer.parseInt(idStr));
}else if("body".equals(parser.getName())){
//获取该标签下的值
String body = parser.nextText();
smsInfo.setBody(body);
}else if("date".equals(parser.getName())){
String date = parser.nextText();
smsInfo.setDate(Long.parseLong(date));
}else if("type".equals(parser.getName())){
String type1 = parser.nextText();
smsInfo.setType(Integer.parseInt(type1));
}else if("address".equals(parser.getName())){
String address = parser.nextText();
smsInfo.setAddress(address);
}
break;
case XmlPullParser.END_TAG://如果是结束标签
if("sms".equals(parser.getName())){
//这代表一个对象解析完成,然后就把该对象添加到集合中
pullData.add(smsInfo);
smsInfo = null;//节省内存,垃圾回收
}
break;
default:
break;
}
//获取下一个标签类型,这是循环的条件,很重要滴
type = parser.next();
}
return pullData;
}
然后在Button点击事件中调用该方法
File file = new File(Environment.getExternalStorageDirectory(),"backup.xml");
try {
FileInputStream pullStream = new FileInputStream(file);
ArrayList<SmssInfo> pullData = pullDemo(pullStream);
for(SmssInfo info : pullData)
{
Log.i("XMLSerializeAcy", "Address" + info.getAddress() + "Body" + info.getBody() + "Date"
+ info.getDate() + "Id" + info.getId() + "Type" + info.getType());
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}