您的位置:首页 > 移动开发 > Android开发

【android】使用SharedPreferences存取复杂数据

2010-12-20 17:15 369 查看
转自(http://www.blogjava.net/nokiaguy/category/43978.html),自己修改了一部分。

SharedPreferences只能保存简单类型的数据,例如,String、int等。一般会将复杂类型的数据转换成Base64编码,然后将转换后的数据以字符串的形式保存在 XML文件中,再用SharedPreferences保存。

Base64转码使用了Apache Commons组件集中的Codec组件进行Base64编码和解码。http://commons.apache.org/codec/download_codec.cgi

将一个BmiPref 类的对象实例和一个图像保存在XML文件中,并在程序重新运行后从XML文件装载Product对象和图像。下面是BmiPref 类的代码:

package com.xdy.demo.android.pojo;

import java.io.Serializable;

public class BmiPref implements Serializable {

private static final long serialVersionUID = 6699487519253726925L;

private int feet;
private int inch;
private String result;
private String suggest;

public BmiPref(){

}

public BmiPref(int feet,int inch,String result,String suggest){
this.feet = feet;
this.inch = inch;
this.result = result;
this.suggest = suggest;
}

public int getFeet() {
return feet;
}
public void setFeet(int feet) {
this.feet = feet;
}
public int getInch() {
return inch;
}
public void setInch(int inch) {
this.inch = inch;
}
public String getResult() {
return result;
}
public void setResult(String result) {
this.result = result;
}
public String getSuggest() {
return suggest;
}
public void setSuggest(String suggest) {
this.suggest = suggest;
}
@Override
public String toString() {
return "BmiPref [feet=" + feet + ", inch=" + inch + ", result="
+ result + ", suggest=" + suggest + "]";
}
}


在存取数据之前,需要创建一个SharedPreferences对象。保存BmiPref对象之前,需要创建BmiPref对象,并将相应组件中的值赋给BmiPref类的相应属性。将BmiPref对象保存在XML文件中的代码如下:

public static final String PREF = "BMI_PREF";
public static final String PREF_BASE64="base64";

@Override
protected void onPause() {
Log.v(TAG, "onPause....");
super.onPause();
BmiPref bp = new BmiPref();
bp.setFeet(field_feet.getSelectedItemPosition());
bp.setInch(field_inch.getSelectedItemPosition());
bp.setResult(view_result.getText().toString());
bp.setSuggest(view_suggest.getText().toString());

ByteArrayOutputStream baos;
try {
baos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(baos);
oos.writeObject(bp);
//Save user preferences. use Editor object to make changes.
SharedPreferences settings = getSharedPreferences(PREF_BASE64, Activity.MODE_PRIVATE);
String tmpSave = new String(Base64.encodeBase64(baos.toByteArray()));
settings.edit()
.putString(PREF, tmpSave)
.commit();
} catch (IOException e) {
Log.e(TAG, e.toString());
e.printStackTrace();
}
}


保存图像的方法与保存BmiPref对象的方法类似。由于在保存之前,需要选择一个图像,并将该图像显示在ImageView组件中,因此,从ImageView组件中可以直接获得要保存的图像。将图象保存在XML文件中的代码如下:

ByteArrayOutputStream baos = new ByteArrayOutputStream();

// 将ImageView组件中的图像压缩成JPEG格式,并将压缩结果保存在ByteArrayOutputStream对象中

((BitmapDrawable) imageView.getDrawable()).getBitmap().compress(CompressFormat.JPEG, 50, baos);

String imageBase64 = new String(Base64.encodeBase64(baos.toByteArray()));

// 保存由图像字节流转换成的Base64格式字符串

editor.putString("productImage", imageBase64);

editor.commit();

其中compress方法的第2个参数表示压缩质量,取值范围是0至100,0表示最高压缩比,但图像效果最差,100则恰恰相反。在本例中取了一个中间值50。

从XML文件中装载BmiPref对象和图像是保存的逆过程。也就是从XML文件中读取Base64格式的字符串,然后将其解码成字节数组,最后将字节数组转换成BmiPref和Drawable对象。装载BmiPref对象的代码如下:

private void restorePrefs(){
SharedPreferences settings = getSharedPreferences(PREF_BASE64, 0);
String tmpSaveBase64 = settings.getString(PREF, "");
// 对Base64格式的字符串进行解码
byte[] base64Bytes = Base64.decodeBase64(tmpSaveBase64.getBytes());
try {
ByteArrayInputStream bais = new ByteArrayInputStream(base64Bytes);
ObjectInputStream ois = new ObjectInputStream(bais);
// 从ObjectInputStream中读取Product对象
BmiPref bp = (BmiPref) ois.readObject();

Log.d(TAG, "BmiPref :"+bp.toString());
if (bp != null) {
field_feet.setSelection(bp.getFeet());
field_inch.requestFocus();

field_inch.setSelection(bp.getInch());
field_weight.requestFocus();

view_result.setText(bp.getResult());
view_suggest.setText(bp.getSuggest());
}
} catch (Exception e) {
Log.e(TAG, "restorePrefs : "+e.toString());
e.printStackTrace();
}
}


装载图像的代码如下:

String imageBase64 = mySharedPreferences.getString("productImage","");

base64Bytes = Base64.decodeBase64(imageBase64.getBytes());

bais = new ByteArrayInputStream(base64Bytes);

// 在ImageView组件上显示图像

imageView.setImageDrawable(Drawable.createFromStream(bais,"product_image"));

在上面的代码中使用了Drawable类的createFromStream方法直接从流创建了Drawable对象,并使用setImageDrawable方法将图像显示在ImageView组件上。

在这里需要提一下的是图像选择。在本例中使用了res\drawable目录中的除了icon.png外的其他图像。为了能列出这些图像,本例使用了 Java的反射技术来枚举这些图像的资源ID。基本原理是枚举R.drawable类中所有的Field,并获得这些Field的值。如果采用这个方法,再向drawable目录中添加新的图像,或删除以前的图像,并不需要修改代码,程序就可以显示最新的图像列表。枚举图像资源ID的代码如下:

// 获得R.drawable类中所有的Field

Field[] fields = R.drawable.class.getDeclaredFields();

for (Field field : fields)

{

if (!"icon".equals(field.getName()))

imageResIdList.add(field.getInt(R.drawable.class));

}

运行本例后,单击【选择产品图像】按钮,会显示一个图像选择对话框,如图1所示。选中一个图像后,关闭图像选择对话框,并单击【保存】按钮。如果保存成功,将显示如图2所示的提示对话框。当再次运行程序后,会显示上次成功保存的数据。





查看base64.xml文件,会看到如下的内容:

<?xml version='1.0' encoding='utf-8' standalone='yes' ?>

<map>

<string name="productImage">/9j/4AAQSkZJRgABAQAAAQABAAD/2wBDABDsyj7yK3



</string>

<string name="product">rO0ABXNyABtuZXQuYmxvZ2phdmEubW9iaWxlLlByb2



</string>

</map>

注意:虽然可以采用编码的方式通过SharedPreferences保存任何类型的数据,但作者并不建议使用SharedPreferences保存尺寸很大的数据。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐