【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 类的代码:
在存取数据之前,需要创建一个SharedPreferences对象。保存BmiPref对象之前,需要创建BmiPref对象,并将相应组件中的值赋给BmiPref类的相应属性。将BmiPref对象保存在XML文件中的代码如下:
保存图像的方法与保存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对象的代码如下:
装载图像的代码如下:
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保存尺寸很大的数据。
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保存尺寸很大的数据。
相关文章推荐
- 【android】使用SharedPreferences存取复杂数据
- 《Android/OPhone开发完全讲义》连载(7):使用SharedPreferences存取复杂数据
- 《Android/OPhone开发完全讲义》连载(7):使用SharedPreferences存取复杂数据
- 《Android/OPhone开发完全讲义》连载(7):使用SharedPreferences存取复杂数据
- 《Android/OPhone开发完全讲义》连载(7):使用SharedPreferences存取复杂数据
- Android---45---使用AIDL Service传递复杂数据
- Android应用开发之使用SharedPreferences存储复杂类型的数据
- 《Android/OPhone开发完全讲义》连载(7):使用SharedPreferences存取复杂数据
- 《Android/OPhone开发完全讲义》连载(7):使用SharedPreferences存取复杂数据
- 《Android/OPhone开发完全讲义》连载(7):使用SharedPreferences存取复杂数据
- 《Android/OPhone开发完全讲义》连载(7):使用SharedPreferences存取复杂数据
- 《Android/OPhone开发完全讲义》连载(7):使用SharedPreferences存取复杂数据
- 《Android/OPhone开发完全讲义》连载(7):使用SharedPreferences存取复杂数据
- 《Android/OPhone开发完全讲义》连载(7):使用SharedPreferences存取复杂数据
- 说说在 Android 中如何使用文件存取数据
- 《Android/OPhone开发完全讲义》连载(7):使用SharedPreferences存取复杂数据
- 《Android/OPhone开发完全讲义》连载(7):使用SharedPreferences存取复杂数据
- 《Android/OPhone开发完全讲义》连载(7):使用SharedPreferences存取复杂数据
- 《Android/OPhone开发完全讲义》连载(7):使用SharedPreferences存取复杂数据
- 【Android SharedPreference】 使用SharedPreferences存储复杂类型的数据