前两天用SharedPreference实现了保存用户历史信息,当用户再次登录的时候在AutoCompleteTextView(仿google搜索自动提示框)中显示历史用户信息。
这次用户信息是通过XML保存的,其中比较中要的包括了XML数据的生成和XML数据的解析,以及生成apk私有数据。
XML数据生成:在将用户信息保存成XML数据前,我们应该先了解一个非常重要的类XmlSerializer,这个类帮助我们将需要保存成XML数据的信息进行序列化。
代码
public
String writeToString(List
<
UserInfo
>
users){
//
实现xml信息序列号的一个对象
XmlSerializer serializer
=
Xml.newSerializer(); StringWriter writer
=
new
StringWriter();
try
{
//
xml数据经过序列化后保存到String中,然后将字串通过OutputStream保存为xml文件
serializer.setOutput(writer);
//
文档开始
serializer.startDocument(
"
utf-8
"
,
true
);
//
开始一个节点
serializer.startTag(
""
,
"
users
"
);
//
开始一个子节点
for
(UserInfo user : users){ serializer.startTag(
""
,
"
user
"
); serializer.attribute(
""
,
"
id
"
, String.valueOf(user.getId())); serializer.startTag(
""
,
"
name
"
); serializer.text(user.getName()); serializer.endTag(
""
,
"
name
"
); serializer.startTag(
""
,
"
pwd
"
); serializer.text(user.getPwd()); serializer.endTag(
""
,
"
pwd
"
); serializer.startTag(
""
,
"
isremember
"
); serializer.text(String.valueOf(user.getIsRemember())); serializer.endTag(
""
,
"
isremember
"
); serializer.endTag(
""
,
"
user
"
); } serializer.endTag(
""
,
"
users
"
);
//
关闭文档
serializer.endDocument(); }
catch
(IllegalArgumentException e) {
//
TODO Auto-generated catch block
e.printStackTrace(); }
catch
(IllegalStateException e) {
//
TODO Auto-generated catch block
e.printStackTrace(); }
catch
(IOException e) {
//
TODO Auto-generated catch block
e.printStackTrace(); }
return
writer.toString(); }
将字串保存为apk的私有文件
代码
public
boolean
writeToXml(Context context,String str){
try
{ OutputStream out
=
context.openFileOutput(
"
users.xml
"
, Context.MODE_PRIVATE); OutputStreamWriter outw
=
new
OutputStreamWriter(out);
try
{ outw.write(str); outw.close(); out.close();
return
true
; }
catch
(IOException e) {
//
TODO Auto-generated catch block
return
false
; } }
catch
(FileNotFoundException e) {
//
TODO Auto-generated catch block
return
false
; } }
XML数据解析
由于使用DOM方法需要将整个XML文档加载内存中,对系统资源占用比较多,这对内存比较紧张的Android系统来说,使用DOM方法读取XML文档会有很大的限制。 所以使用SAX方法读取XML,以减少对内存资源的占用。
使用SAX解析xml数据其实很简单,无非就是几个过程,startDocument——startElement——character——endElement——endDocument
startDocument:开始解析xml数据,如果处理的数据很多,在这里实例化一个list对象。
startElement:节点元素数据的处理,获取节点元素的属性值,往往在这里对抽象化的对象进行实例化如一个用户的信息UserInfo user
character:获得杰点元素的内容,在这里专门获得没有属性节点的内容,如<name>cbin</name>
endElement:一个节点的结束,也就相当于一个用户信息的解析完毕,在这里将user添加到list中
endDocument:XML数据解析结束
代码
public
class
UsersHandler
extends
DefaultHandler {
private
List
<
UserInfo
>
list
=
null
;
private
UserInfo user
=
null
;
private
String tagname;
//
开始解析XML文档
@Override
public
void
startDocument()
throws
SAXException{ list
=
new
ArrayList
<
UserInfo
>
();
super
.startDocument(); }
//
开始处理节点,在这里获得节点属性值的(节点属性)
@Override
public
void
startElement(String uri, String localName, String qName, Attributes attributes)
throws
SAXException{
if
(localName.equals(
"
user
"
)){ user
=
new
UserInfo(); user.setId(Integer.parseInt(attributes.getValue(
"
id
"
))); }
this
.tagname
=
localName;
super
.startElement(uri, localName, qName, attributes); }
//
处理没有属性的节点(节点内容)
@Override
public
void
characters(
char
[] ch,
int
start,
int
length)
throws
SAXException{
if
(
this
.tagname
!=
""
){
if
(
this
.tagname.equals(
"
name
"
)){ String str
=
new
String(ch, start, length); user.setName(str); }
else
if
(
this
.tagname.equals(
"
pwd
"
)){ String str
=
new
String(ch, start, length); user.setPwd(str); }
else
if
(
this
.tagname.endsWith(
"
isremember
"
)){ String str
=
new
String(ch, start, length); user.setIsRemember(Integer.parseInt(str)); } }
super
.characters(ch, start, length); } @Override
public
void
endElement(String uri, String localName, String qName)
throws
SAXException{
if
(localName.equals(
"
user
"
)){ list.add(user); }
super
.endElement(uri, localName, qName); } @Override
public
void
endDocument()
throws
SAXException{
super
.endDocument(); }
public
List
<
UserInfo
>
getUserList(){
return
list; }}
表示层与SharedPreferences中实现用户登录大同小异,无非是一个登录的逻辑处理
1、加载页面时,加载xml中数据,将用户名列表绑定AutoCompleteTextView
2、假若从act中选定数据,根据用户名查找密码等信息绑定et、ck;
3、登录成功,是新用户直接添加,老用户删除原有记录,重新记录用户信息。