android开发学习(三)——sharedPreference,xml文件序列化和反序列

来源:互联网 发布:制作试卷的软件 编辑:程序博客网 时间:2024/06/05 15:37


今天谈两点:sharedPreference,xml文件序列化和反序列


一,sharedPreference:

SharedPreferences是一种轻型的数据存储方式,它的本质是基于XML文件存储key-value键值对数据,通常用来存储一些简单的配置信息。其存储位置在/data/data/<包名>/shared_prefs目录下。SharedPreferences对象本身只能获取数据而不支持存储和修改,存储修改是通过Editor对象实现。实现SharedPreferences存储的步骤如下:


  1、根据Context获取SharedPreferences对象:

        SharedPreferences sp = context.getSharedPreferences("config", Context.MODE_PRIVATE);


  2、利用edit()方法获取Editor对象:

        Editor editor = sp.edit();


  3、通过Editor对象存储key-value键值对数据:

        editor.putString("用户名", name);
        editor.putString("密码", password);


插入数据:
调用Editor.putxxxx方法,两个参数分别为键和值。
获取数据:
调用Editor.getxxxx方法,两个参数分别为键和不存在指定键时的默认值。
删除数据:
调用Editor.remove方法,参数为指定的键。
清空所有数据:
调用Editor.clear方法


  4、通过commit()方法提交数据:

        editor.commit();


例如一下的代码:

MainActivity

package com.example.login;import android.app.Activity;import android.content.Context;import android.content.SharedPreferences;import android.os.Bundle;import android.text.TextUtils;import android.util.Log;import android.view.View;import android.widget.CheckBox;import android.widget.EditText;import android.widget.Toast;import com.example.SharedPreference.R;import com.example.login.service.LoginService;public class MainActivity extends Activity {private static final String tag = "MainActivity";private EditText et_name;private EditText et_password;private CheckBox RemenberPassword;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);// 初始化et_name = (EditText) findViewById(R.id.et_name);et_password = (EditText) findViewById(R.id.et_password);RemenberPassword = (CheckBox) findViewById(R.id.cb_remenberpawd);/* * 信息回显 */// 获取SharedPreferences对象SharedPreferences sp = getSharedPreferences("config", Context.MODE_PRIVATE);String name = sp.getString("用户名", "");String password = sp.getString("密码", "");et_name.setText(name);et_password.setText(password);}/** * 登录 */public void login(View view) {String name = et_name.getText().toString().trim();String password = et_password.getText().toString();if (TextUtils.isEmpty(name) || TextUtils.isEmpty(password)) {Toast.makeText(this, "用户名或密码不能为空", Toast.LENGTH_SHORT).show();} else {// 判断是否保存用户名密码if (RemenberPassword.isChecked()) {// 保存密码Log.i(tag, "需要保存的用户名和密码。");LoginService.saveUserInfo(this, name, password);Toast.makeText(this, "保存用户信息成功", Toast.LENGTH_SHORT).show();}// 登录,发送消息到服务器,服务器验证正确性if ("123".equals(name) && "4038".equals(password)) {Toast.makeText(this, "登录成功", Toast.LENGTH_LONG).show();} else {Toast.makeText(this, "登录失败", Toast.LENGTH_LONG).show();}}}}

LoginService.java

package com.example.login.service;import android.content.Context;import android.content.SharedPreferences;import android.content.SharedPreferences.Editor;/** * 保存用户名和密码的业务方法 * @author Administrator */public class LoginService {public static void saveUserInfo(Context context, String name, String password) {// 获取SharedPreferences对象SharedPreferences sp = context.getSharedPreferences("config", Context.MODE_PRIVATE);// 获取Editor对象Editor editor = sp.edit();editor.putString("用户名", name);editor.putString("密码", password);// 提交:类似于数据库的事务,保证数据同时提交成功editor.commit();}}

文件会shared_prefs目录下生成:

文件会以键值对的方式存储:

二,xml文件序列化和反序列

1、XML文件序列化:

这里我们引用短信备份的案例,即将短信备份成XML文件输出到内存卡上保存起来。

XML文件序列化有两种方式,以下代码都写出来了,按照如图的格式输出XML文本:


代码如下:

package com.example.WriteXML;import java.io.File;import java.io.FileOutputStream;import java.util.ArrayList;import java.util.List;import java.util.Random;import org.xmlpull.v1.XmlSerializer;import android.app.Activity;import android.os.Bundle;import android.os.Environment;import android.util.Xml;import android.view.View;import android.widget.Toast;import com.example.WriteXML.domain.smsInfo;public class MainActivity extends Activity {private List<smsInfo> smsInfos;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);smsInfos = new ArrayList<smsInfo>();Random random = new Random();long number = 1350000001;// 创建10条短信for (int i = 0; i < 10; i++) {smsInfos.add(new smsInfo(System.currentTimeMillis(), random.nextInt(2) + 1, "短信内容" + i, Long.toString(number + i), i));}}// 短信的备份方式1public void BackSMS1(View view) {// 假设我已经获得了所有的短信StringBuffer sb = new StringBuffer();sb.append("<?xml version=\"1.0\" encoding=\"utf-8\"?>");sb.append("<smss>");for (smsInfo info : smsInfos) {sb.append("<date>");sb.append(info.getDate());sb.append("</date>");sb.append("<type>");sb.append(info.getType());sb.append("</type>");sb.append("<body>");sb.append(info.getBody());sb.append("</v>");sb.append("<address>");sb.append(info.getAddress());sb.append("</address>");}sb.append("</smss>");if (Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState())) {try {File file = new File(Environment.getExternalStorageDirectory(),"BackSMS.xml");FileOutputStream fos = new FileOutputStream(file);fos.write(sb.toString().getBytes());fos.close();Toast.makeText(this, "短信备份成功", 0).show();} catch (Exception e) {e.printStackTrace();Toast.makeText(this, "短信备份失败", 0).show();}} else {Toast.makeText(this, "SD卡未挂载", 0).show();}}/** * private long date; private int type; private String body; private String * address; *  * @param view */// 短信备份方式2public void BackSMS2(View view) {XmlSerializer serializer = Xml.newSerializer();// 创建一个序列器try {File file = new File(Environment.getExternalStorageDirectory(),"BackSMS2.xml");FileOutputStream fos = new FileOutputStream(file);//初始化序列号器,指定xml数据写入到哪个文件,并指定文件的编码方式serializer.setOutput(fos, "utf-8");serializer.startDocument("utf-8", true);serializer.startTag(null, "smss");for (smsInfo info : smsInfos) {serializer.startTag(null, "sms");serializer.attribute(null, "id", info.getId()+"");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.startTag(null, "address");serializer.text(info.getAddress());serializer.endTag(null, "address");serializer.endTag(null, "sms");}serializer.endTag(null, "smss");serializer.endDocument();fos.close();Toast.makeText(this, "短信备份成功", 0).show();} catch (Exception e) {e.printStackTrace();Toast.makeText(this, "短信备份失败", 0).show();}}}

在这里,假设使用第一种方式,就会出现一些意外情况,比如,在短信内容里面多一个“<”符号,备份时会出错:

结果:

所以,我们通常用方式二。


2、XML文件反序列化(XML文件解析)

这里我们引用天气显示的案例,一般提供的天气API都是XML文件,我们需要把XML文件解析出来,然后显示在app上。

首先,我们先模仿制作一个包涵天气资讯的XML文件:

然后我们定义一个getWeatherInfos的方法,采用pull解析器来解析xml文件,实现解析的业务:

package com.example.weather.service;import java.io.InputStream;import java.util.ArrayList;import java.util.List;import org.xmlpull.v1.XmlPullParser;import android.util.Xml;import com.example.weather.domain.weatherInfo;public class WeatherService {public static List<weatherInfo> getWeatherInfos(InputStream is) throws Exception {// creating a pull parserXmlPullParser pullParser = Xml.newPullParser();// initialize the pull parserpullParser.setInput(is, "UTF-8");// creating a weatherInfos list, using to memory a piece of dataList<weatherInfo> weatherInfos = null;// creating a weather element, using to set the value of itweatherInfo weathers = null;// When the parser to a location, returns the type of the current event// (START_TAG, END_TAG, TEXT, etc.)// 当解析器解析到的某个位置时,返回当前位置的事件类型( START_TAG , END_TAG ,文本等)int type = pullParser.getEventType();while (type != XmlPullParser.END_DOCUMENT) {// 检测XML文件是否解析完switch (type) {case XmlPullParser.START_TAG:if ("infos".equals(pullParser.getName())) {// 解析到全局开始的标签weatherInfos = new ArrayList<weatherInfo>();} else if ("city".equals(pullParser.getName())) {// 解析到城市开始的标签weathers = new weatherInfo();} else if ("temp".equals(pullParser.getName())) {/* * If current event is START_TAG then if next element is * TEXT then element content is returned or if next event is * END_TAG then empty string is returned. */String temp = pullParser.nextText();weathers.setTemp(temp);} else if ("wind".equals(pullParser.getName())) {String wind = pullParser.nextText();weathers.setWind(wind);} else if ("weather".equals(pullParser.getName())) {String weather = pullParser.nextText();weathers.setWeather(weather);} else if ("name".equals(pullParser.getName())) {String name = pullParser.nextText();weathers.setName(name);} else if ("pm".equals(pullParser.getName())) {String pm = pullParser.nextText();weathers.setPm(pm);}break;case XmlPullParser.END_TAG:if ("city".equals(pullParser.getName())) {// a city has finishedweatherInfos.add(weathers);weathers = null;}break;}type = pullParser.next();}return weatherInfos;}}

显示结果:




0 0
原创粉丝点击