SharePreference是如何实现的——序列化XML文件 还记得上一篇我们讲到了用SharePreference来存储数据,那么究竟它是如何实现的呢,今天我们就来仔细看看其实现的细节,我们给它一个准确的名字,叫做XML序列化器(XmlSerializer)。

  • 不同于上面一篇的保存用户的登录名以及密码,这次我们保存设备中的信息,但是由于现在知识有限,我还不能够实现对设备中信息的读取,那么我就在程序中自己生成若干条信息,对这些生成的信息进行读取,并保存到位于SD卡的backup.xml文件中。在这里我是用两种方法对其进行存储并比较两种方法的优缺点,当然作为开发,我更建议使用待会讲到的第二种方法。

 先来看看我们需要做到什么样的效果:

SharePreference是如何实现的——序列化XML文件
还记得上一篇我们讲到了用SharePreference来存储数据,那么究竟它是如何实现的呢,今天我们就来仔细看看其实现的细节,我们给它一个准确的名字,叫做XML序列化器(XmlSerializer)。

图一


  • 第一种方法:使用StringBuffer,将所有的内容逐一追加到该字符流中。

 1 public void backUpSms1(View view){
 2         StringBuffer sb=new StringBuffer();
 3         sb.append("<?xml version="1.0" encoding="UTF-8" ?>");
 4         sb.append("<smss>");
 5         for (SmsInfo smsinfo: smsInfo) {
 6             sb.append("<sms>");
 7             sb.append("<address>");
 8             sb.append(smsinfo.getAddress());
 9             sb.append("</address>");
10 
11             sb.append("<date>");
12             sb.append(smsinfo.getDate());
13             sb.append("</date>");
14 
15             sb.append("<content>");
16             sb.append(smsinfo.getContent());
17             sb.append("</content>");
18 
19             sb.append("<type>");
20             sb.append(smsinfo.getType());
21             sb.append("</type>");
22             sb.append("</sms>");
23         }
24         sb.append("</smss>");
25         try {
26             File file =new File(Environment.getExternalStorageDirectory(), "backUp1.xml");
27             FileOutputStream fos =new FileOutputStream(file);
28             fos.write(sb.toString().getBytes());
29             fos.close();
30             Toast.makeText( this, "备份成功",0).show();
31         } catch (Exception e) {
32             e.printStackTrace();
33             Toast.makeText( this, "备份失败",0).show();
34         }
35     }

第一种方法相当简单,只是用了一个字符流,将所有的内容逐一追加就行了,可是当我们的短信中出现了一些比较特殊的字符,例如:"<"或者是">"那么在读取并写入到xml文件的时候就会出错,这个时候打开该xml文件的时候将会报错;另外当我们需要在sms标签中加入一些属性,如图一所示,那么这个时候仅仅利用字符流来写就会变得冗杂,而且逻辑关系就不严谨了,所以这个时候我们就需要用到第二种方法了。

  • 第二种方法(推荐):XML序列化器(使用XmlSerializer编辑xml文件)

 1 public void backUpSms2(View view) {
 2         try {
 3             //初始化序列号器,指定xml写入到哪个文件并指定写入的编码格式
 4             XmlSerializer xmlSerializer =Xml.newSerializer();
 5             File file =new File(Environment.getExternalStorageDirectory(), "backUp2.xml");
 6             FileOutputStream fos=new FileOutputStream(file);
 7             xmlSerializer.setOutput(fos,"utf-8");
 8             
 9             xmlSerializer.startDocument("utf-8", true);//开始声明文件
10             xmlSerializer.startTag(null, "smss");//开始最外层标签
11             for (SmsInfo sms : smsInfo) {
12                 xmlSerializer.startTag(null, "sms");//写入第一个标签
13                 xmlSerializer.attribute(null, "id", sms.getId()+"");//第一个标签的属性
14 
15                 xmlSerializer.startTag(null, "address");//写入内一层的标签
16                 xmlSerializer.text(sms.getAddress());
17                 xmlSerializer.endTag(null, "address");
18 
19                 xmlSerializer.startTag(null, "date");//写入内一层的标签
20                 xmlSerializer.text(sms.getDate()+"");
21                 xmlSerializer.endTag(null, "date");
22 
23                 xmlSerializer.startTag(null, "content");//写入内一层的标签
24                 xmlSerializer.text(sms.getContent());
25                 xmlSerializer.endTag(null, "content");
26 
27                 xmlSerializer.startTag(null, "type");//写入内一层的标签
28                 xmlSerializer.text(sms.getType()+"");
29                 xmlSerializer.endTag(null, "type");
30 
31                 xmlSerializer.endTag(null, "sms");//结束标签
32 
33             }
34             xmlSerializer.endTag(null, "smss");//结束最外层标签
35             xmlSerializer.endDocument();//结束声明文件
36             fos.close();//记得一定要关闭输出流
37             Toast.makeText( this, "备份成功",0).show();
38         } catch (Exception e) {
39             e.printStackTrace();
40             Toast.makeText( this, "备份失败",0).show();
41         }
42     }

使用XmlSerializer的时候有几个步骤:1、首先需要找到输出流,即通过setOutput方法将输出流以及编码格式传入;2、接着需要声明文件以及结束声明,这是通过startDocument以及endDocument这两个方法来实现的;3、接着就可以通过startTag以及startTag方法来声明标签以及结束标签,要声明标签的内容的时候可以通过text方法,当然这个方法只能允许传入String类型,所以对于其他数据类型,需要先对其进行转换;4、最后一点就是上面讲到的——要在标签中添加属性,那就需要通过attribute方法声明id属性。

通过以上的讲解,我们可以得到以下的xml文件:

  1 <?xml version="1.0" encoding="UTF-8" standalone="true"?>
  2 
  3 -<smss>
  4 
  5 
  6 -<sms id="0">
  7 
  8 <address>135000000000</address>
  9 
 10 <date>1461845202224</date>
 11 
 12 <content>内容为:0</content>
 13 
 14 <type>1</type>
 15 
 16 </sms>
 17 
 18 
 19 -<sms id="1">
 20 
 21 <address>135000000001</address>
 22 
 23 <date>1461845202225</date>
 24 
 25 <content>内容为:1</content>
 26 
 27 <type>2</type>
 28 
 29 </sms>
 30 
 31 
 32 -<sms id="2">
 33 
 34 <address>135000000002</address>
 35 
 36 <date>1461845202225</date>
 37 
 38 <content>内容为:2</content>
 39 
 40 <type>1</type>
 41 
 42 </sms>
 43 
 44 
 45 -<sms id="3">
 46 
 47 <address>135000000003</address>
 48 
 49 <date>1461845202225</date>
 50 
 51 <content>内容为:3</content>
 52 
 53 <type>2</type>
 54 
 55 </sms>
 56 
 57 
 58 -<sms id="4">
 59 
 60 <address>135000000004</address>
 61 
 62 <date>1461845202225</date>
 63 
 64 <content>内容为:4</content>
 65 
 66 <type>2</type>
 67 
 68 </sms>
 69 
 70 
 71 -<sms id="5">
 72 
 73 <address>135000000005</address>
 74 
 75 <date>1461845202225</date>
 76 
 77 <content>内容为:5</content>
 78 
 79 <type>2</type>
 80 
 81 </sms>
 82 
 83 
 84 -<sms id="6">
 85 
 86 <address>135000000006</address>
 87 
 88 <date>1461845202225</date>
 89 
 90 <content>内容为:6</content>
 91 
 92 <type>2</type>
 93 
 94 </sms>
 95 
 96 
 97 -<sms id="7">
 98 
 99 <address>135000000007</address>
100 
101 <date>1461845202225</date>
102 
103 <content>内容为:7</content>
104 
105 <type>2</type>
106 
107 </sms>
108 
109 
110 -<sms id="8">
111 
112 <address>135000000008</address>
113 
114 <date>1461845202225</date>
115 
116 <content>内容为:8</content>
117 
118 <type>1</type>
119 
120 </sms>
121 
122 
123 -<sms id="9">
124 
125 <address>135000000009</address>
126 
127 <date>1461845202225</date>
128 
129 <content>内容为:9</content>
130 
131 <type>2</type>
132 
133 </sms>
134 
135 
136 -<sms id="10">
137 
138 <address>135000000010</address>
139 
140 <date>1461845202225</date>
141 
142 <content>内容为:10</content>
143 
144 <type>1</type>
145 
146 </sms>
147 
148 
149 -<sms id="11">
150 
151 <address>135000000011</address>
152 
153 <date>1461845202225</date>
154 
155 <content>内容为:11</content>
156 
157 <type>2</type>
158 
159 </sms>
160 
161 
162 -<sms id="12">
163 
164 <address>135000000012</address>
165 
166 <date>1461845202225</date>
167 
168 <content>内容为:12</content>
169 
170 <type>2</type>
171 
172 </sms>
173 
174 
175 -<sms id="13">
176 
177 <address>135000000013</address>
178 
179 <date>1461845202225</date>
180 
181 <content>内容为:13</content>
182 
183 <type>2</type>
184 
185 </sms>
186 
187 
188 -<sms id="14">
189 
190 <address>135000000014</address>
191 
192 <date>1461845202225</date>
193 
194 <content>内容为:14</content>
195 
196 <type>2</type>
197 
198 </sms>
199 
200 
201 -<sms id="15">
202 
203 <address>135000000015</address>
204 
205 <date>1461845202225</date>
206 
207 <content>内容为:15</content>
208 
209 <type>1</type>
210 
211 </sms>
212 
213 
214 -<sms id="16">
215 
216 <address>135000000016</address>
217 
218 <date>1461845202225</date>
219 
220 <content>内容为:16</content>
221 
222 <type>1</type>
223 
224 </sms>
225 
226 
227 -<sms id="17">
228 
229 <address>135000000017</address>
230 
231 <date>1461845202225</date>
232 
233 <content>内容为:17</content>
234 
235 <type>1</type>
236 
237 </sms>
238 
239 
240 -<sms id="18">
241 
242 <address>135000000018</address>
243 
244 <date>1461845202225</date>
245 
246 <content>内容为:18</content>
247 
248 <type>2</type>
249 
250 </sms>
251 
252 
253 -<sms id="19">
254 
255 <address>135000000019</address>
256 
257 <date>1461845202225</date>
258 
259 <content>内容为:19</content>
260 
261 <type>1</type>
262 
263 </sms>
264 
265 </smss>

2016-04-29

BOB

--开始忙碌的五一