前两天用SharedPreference实现了保存用户历史信息,当用户再次登录的时候在AutoCompleteTextView(仿google搜索自动提示框)中显示历史用户信息。
这次用户信息是通过XML保存的,其中比较中要的包括了XML数据的生成和XML数据的解析,以及生成apk私有数据。
XML数据生成:在将用户信息保存成XML数据前,我们应该先了解一个非常重要的类XmlSerializer,这个类帮助我们将需要保存成XML数据的信息进行序列化。
// 实现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的私有文件
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:获得杰点元素的内容,在这里专门获得没有属性节点的内容,如
endElement:一个节点的结束,也就相当于一个用户信息的解析完毕,在这里将user添加到list中
endDocument:XML数据解析结束
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、登录成功,是新用户直接添加,老用户删除原有记录,重新记录用户信息。
贴个效果图:
参考:http://www.moandroid.com/?p=821 Android读写XML(中)