Android 漫游之路------SharedPreferences、Xml、Xml的pull解析

---------------------- 路漫漫其修远兮吾将上下而求索。学无止境!----------------------

 

微笑SharedPreferences

 

SharedPreferences对象本身只能获取数据而不支持存储和修改,存储修改是通过Editor对象实现。实现SharedPreferences存储的步骤如下:

  一、根据Context获取SharedPreferences对象

  二、利用edit()方法获取Editor对象。

  三、通过Editor对象存储key-value键值对数据。

  四、通过commit()方法提交数据。

 

关于SharedPreferences的读写操作,可以参看代码:

写操作

public static boolean saveInfo(Context context, String name, String password) {
		// 根据context得到sharedPreferences
		SharedPreferences sharedPreferences = context.getSharedPreferences(
				"config", Context.MODE_PRIVATE);
		Editor editor = sharedPreferences.edit();
		editor.putString("name", name);
		editor.putString("password", password);
		// 一定要commit
		editor.commit();
		return true;
	}

读操作

public static Map<String, String> getInfo(Context context) {
		// 根据context得到sharedPreferences
		SharedPreferences sharedPreferences = context.getSharedPreferences(
				"config", Context.MODE_PRIVATE);
		String name = sharedPreferences.getString("name", null);
		String password = sharedPreferences.getString("password", null);
		Map<String, String> map = new HashMap<String, String>();
		map.put("name", name);
		map.put("password", password);
		return map;
	}

其他位置的代码请参看:上一篇博文的第一个实例

 

模拟器运行如上程序之后,data/data路径下:

导出config.xml并打开:可以发现

 

 

微笑将数据以xml形式备份到SDCard

 

这里可以使用StringBiluder将信息以流的形式写入指定的文件,不过,StringBuilder在这里显得不是很灵活,特别是有很多需要用到转义字符的地方,而且添加属性极不方便。

为了解决这个问题,我们可以使用XmlSerializer serializer = Xml.newSerializer();来解决

 

代码:MyService.java

package com.example.xml.service;

import java.io.File;
import java.io.FileOutputStream;
import java.util.List;

import org.xmlpull.v1.XmlSerializer;
import com.example.xml.Info;

import android.content.Context;
import android.os.Environment;
import android.util.Xml;
import android.widget.Toast;

public class MyService {

	/**
	 * info的备份服务
	 * @param context 上下文
	 * @param infos info集合
	 */
	public static void backInfo(Context context, List<Info> infos) {

		XmlSerializer serializer = Xml.newSerializer();
		// 在sd创建一个文件夹
		File file = new File(Environment.getExternalStorageDirectory(),
				"backInfo.xml");
		try {
			// 向文件写入内容
			FileOutputStream fos = new FileOutputStream(file);
			serializer.setOutput(fos, "utf-8");

			serializer.startDocument("utf-8", true);
			serializer.startTag(null, "infos");

			for (Info info : infos) {
				serializer.startTag(null, "info");
				//info的属性
				serializer.attribute(null, "id", info.getId() + "");

				//以下是各个子节点
				serializer.startTag(null, "tel");
				serializer.text(info.getTel() + "");
				serializer.endTag(null, "tel");

				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, "body");
				serializer.text(info.getBody());
				serializer.endTag(null, "body");

				serializer.endTag(null, "info");
			}

			serializer.endTag(null, "infos");
			serializer.endDocument();
			//切记要关闭资源
			fos.close();
			System.out.println(infos.size());
			Toast.makeText(context, "备份成功", Toast.LENGTH_SHORT).show();

		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			Toast.makeText(context, "备份失败", Toast.LENGTH_SHORT).show();
		}
	}
}

MainActivity.java

package com.example.xml;

import java.util.ArrayList;
import java.util.List;
import java.util.Random;

import com.example.xml.service.MyService;

import android.os.Bundle;
import android.app.Activity;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;

public class MainActivity extends Activity {

	private Button button;
	private List<Info> infos;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		
		infos = new ArrayList<Info>();
		
		Random random = new Random();
		String num = "1876603000";
		//填充info集合infos
		for(int i=0 ;i<10;i++){
			infos.add(new Info(i, num+i, System.currentTimeMillis(), random.nextInt(2)+1, "信息内容"+i));
		}
		
		//定义button,并加点击事件
		button = (Button)this.findViewById(R.id.button);
		button.setOnClickListener(new OnClickListener() {
			
			@Override
			public void onClick(View v) {
				// TODO Auto-generated method stub
				MyService.backInfo(v.getContext(), infos);
			}
		});
	}

}


注,这里涉及向sdCard写数据,需要权限设置。在AndroidManifest.xml要设置权限

执行结果:


 

 微笑Xml的pull解析 

 

一般来说,解析Xml 有三种方法

分别是 DOM 和Pull 和 SAX

 

DOM

在Dom解析的过程中,是先把dom全部文件读入到内存中,然后使用dom的api遍历所有数据,检索想要的数据,这种方式显然是一种比较消耗内存的方式,对于像手机这样的移动设备来讲,内存是非常有限的,所以对于比较大的XML文件,不推荐使用这种方式,但是Dom也有它的优点,它比较直观,在一些方面比SAX方式比较简单。在xml文档比较小的情况下也可以考虑使用dom方式。SAX,听说是一种事件驱动型的轻量级的解析器,用DOM来解析,比较节省内存。

SAX

这种方式解析是一种基于事件驱动的api,有两个部分,解析器和事件处理器,解析器就是XMLReader接口,负责读取XML文档,和向事件处理器发送事件(也是事件源),事件处理器ContentHandler接口,负责对发送的事件响应和进行XML文档处理。

Pull

在android系统中,很多资源文件中,很多都是xml格式,在android系统中解析这些xml的方式,是使用pul解析器进行解析的,它和sax解析一样(个人感觉要比sax简单点),也是采用事件驱动进行解析的,当pull解析器,开始解析之后,我们可以调用它的next()方法,来获取下一个解析事件(就是开始文档,结束文档,开始标签,结束标签),当处于某个元素时可以调用XmlPullParser的getAttributte()方法来获取属性的值,也可调用它的nextText()获取本节点的值。

 

这里看一下Pull解析:

步骤:

1.初始化pull解析器:XmlPullParser pullParser = Xml.newPullParser();
2.管理解析器与流对象  pullParser.setInput(iStream, "utf-8");

3.进行解析。我们可以调用它的next()方法,来获取下一个解析事件(就是开始文档,结束文档,开始标签,结束标签),当处于某个元素时可以调用XmlPullParser的getAttributte()方法来获取属性的值,也可调用它的nextText()获取本节点的值。

 

MyService.java

package com.lee.service;

import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;

import org.xmlpull.v1.XmlPullParser;

import android.util.Xml;

import com.lee.recodexml.WeatherInfo;

public class MyService {

	public static List<WeatherInfo> getInfos() throws Exception{

		// 得到xml文件的流对象
		InputStream iStream = MyService.class.getClassLoader()
				.getResourceAsStream("weather.xml");

		// 得到xml的解析工具对象XmlPullParser,并关联xml流(初始化解析器)
		XmlPullParser pullParser = Xml.newPullParser();
		pullParser.setInput(iStream, "utf-8");
		List<WeatherInfo> infos = null;
		WeatherInfo info = null;
		//得到节点的类型
		int type = pullParser.getEventType();
		//对节点进行遍历
		while (type != XmlPullParser.END_DOCUMENT) {
			switch (type) {
			case XmlPullParser.START_TAG:
				if ("infos".equals(pullParser.getName())) {
					//在infos节点开始时,建立一个集合
					infos = new ArrayList<WeatherInfo>();
				} else if ("city".equals(pullParser.getName())) {
					//在city节点时,建立一个对象,得到id,并设置到这个对象
					int id = Integer.parseInt(pullParser.getAttributeValue(
							null, "id"));
					info = new WeatherInfo();
					info.setId(id);
				} else if ("temp".equals(pullParser.getName())) {
					String temp = pullParser.nextText();
					info.setTemp(temp);
				} else if ("weather".equals(pullParser.getName())) {
					String weather = pullParser.nextText();
					info.setWeather(weather);
				} else if ("wind".equals(pullParser.getName())) {
					String wind = pullParser.nextText();
					info.setWind(wind);
				} else if ("name".equals(pullParser.getName())) {
					String name = pullParser.nextText();
					info.setName(name);
				} else if ("pm".equals(pullParser.getName())) {
					int pm = Integer.parseInt(pullParser.nextText());
					info.setPm(pm);
				}
				break;

			case XmlPullParser.END_TAG:
				if ("city".equals(pullParser.getName())) {
					//city节点中的内容变量以后,将这个对象放到集合中
					infos.add(info);
					info = null;
				}
				break;
			}
			type = pullParser.next();
		}
		return infos;
	}
}

MainActivity.java

package com.lee.recodexml;

import java.util.List;

import com.lee.service.MyService;

import android.os.Bundle;
import android.widget.TextView;
import android.app.Activity;

public class MainActivity extends Activity {

	private TextView textView;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);

		textView = (TextView) this.findViewById(R.id.tv);
		List<WeatherInfo> infos;
		//定义StringBiluder,得到期望的字符串
		StringBuilder sb = new StringBuilder();
		try {
			infos = MyService.getInfos();
			for (WeatherInfo info : infos) {
				sb.append(info.toString());
				sb.append("\n\n");
			}
			//设置textView的内容
			textView.setText(sb);
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

	}

}

wether.xml文件及运行结果


 

---------------------- 路漫漫其修远兮吾将上下而求索。学无止境!---------------------- 

我的博客:http://blog.csdn.net/helloxiaobi

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值