本文为《Android/OPhone开发完全讲义》一书的内容连载。转载请注明出处

我们知道SharedPreferences只能保存简单类型的数据,例如,String、int等。如果想用SharedPreferences存取更 复杂的数据类型(类、图像等),就需要对这些数据进行编码。我们通常会将复杂类型的数据转换成Base64编码,然后将转换后的数据以字符串的形式保存在 XML文件中。

Android SDK中并未提供Base64编码和解码库。因此,需要使用第三方的jar包。在本例中使用了Apache Commons组件集中的Codec组件进行Base64编码和解码。读者可以从如下的地址下载Codec组件的安装包。

http://commons.apache.org/codec/download_codec.cgi

在Android工程目录的lib子目录中已经包含了Codec组件的jar包(commons-codec-1.4.jar),因此,读者可以在该工程中直接使用Codec组件。

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

package net.blogjava.mobile;
import java.io.Serializable;
// 需要序列化的类必须实现Serializable接口
public class Product implements Serializable
{
private String id;
private String name;
private float price;
// 此处省略了属性的getter和setter方法
 

在存取数据之前,需要使用下面的代码创建一个SharedPreferences对象。

mySharedPreferences = getSharedPreferences("base64",Activity.MODE_PRIVATE);

其中mySharedPreferences是在类中定义的SharedPreferences类型变量。

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

Product product = new Product();
product.setId(etProductID.getText().toString());
product.setName(etProductName.getText().toString());
product.setPrice(Float.parseFloat(etProductPrice.getText().toString()));
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(baos);
// 将Product对象放到OutputStream中
oos.writeObject(product);
mySharedPreferences = getSharedPreferences("base64", Activity.MODE_PRIVATE);
// 将Product对象转换成byte数组,并将其进行base64编码
String productBase64 = new String(Base64.encodeBase64(baos.toByteArray()));
SharedPreferences.Editor editor = mySharedPreferences.edit();
// 将编码后的字符串写到base64.xml文件中
editor.putString("product", productBase64);
editor.commit();

保存图像的方法与保存Product对象的方法类似。由于在保存之前,需要选择一个图像,并将该图像显示在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文件中装载Product对象和图像是保存的逆过程。也就是从XML文件中读取Base64格式的字符串,然后将其解码成字节数组,最后将字节数组转换成Product和Drawable对象。装载Product对象的代码如下:

String productBase64 = mySharedPreferences.getString("product", "");
// 对Base64格式的字符串进行解码
byte[] base64Bytes = Base64.decodeBase64(productBase64.getBytes());
ByteArrayInputStream bais = new ByteArrayInputStream(base64Bytes);
ObjectInputStream ois = new ObjectInputStream(bais);
// 从ObjectInputStream中读取Product对象
Product product = (Product) ois.readObject();

装载图像的代码如下:

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/OPhone开发完全讲义》连载(7):使用SharedPreferences存取复杂数据相关推荐

  1. 《Android/OPhone 开发完全讲义》样章和目录下载

    <Android/OPhone 开发完全讲义>一书已经出版,现提供3个样章(第1.8和14章)试读,欢迎提出宝贵意见. 购买:互动网(china-pub) 内容简介 本书近500页,共25 ...

  2. Android/OPhone开发完全讲义

    Android/OPhone开发完全讲义 基本信息 作者: 李宁    出版社:中国水利水电出版社 ISBN:9787508475271 上架时间:2010-7-1 出版日期:2010 年6月 开本: ...

  3. 《Android/OPhone 开发完全讲义》已出版,现提供源代码下载

    <Android/OPhone 开发完全讲义>已出版. 购买: 互动网(China-pub) 样章下载 现将本书源代码完全公开   Android-OPhone-src.zip 目录 前言 ...

  4. 《Android/OPhone 开发完全讲义》目录

    目录 前言 第1章 Android入门 1 1.1 Android的基本概念 1 1.1.1 Android简介 1 1.1.2 Android的系统构架 3 1.2 Android开发环境的搭建 4 ...

  5. android ophone开发...,(OPhone、android讲义.doc

    Android-OPhone-src.zip <Android/OPhone开发完全讲义>源代码下载次数: 8 2?小时前 目录前言第1章 Android入门 11.1 Android的基 ...

  6. Android 音频开发(四) 如何播放一帧音频数据下

    再看这一篇文章前,如果你是小白,我建议你先看一下Android 音频开发(一) 基础入门篇这一篇.今天继续讲解如何通过Android SDK自带API实现播放一帧音频数据. 我们都知道,Android ...

  7. android 串口开发_详细分析Esp8266上电信息打印的数据,如何做到串口通讯上电不乱码打印...

    01 写在前面: 上篇关于如何在内置仅1M的Esp8285做到 OTA 升级的同步到微信公众号,竟然被安信可的某些运维人员看到了,想要转载,我很欣慰,竟然自己的笔记可以被这么大型的公司员工认可! 我是 ...

  8. Android 音频开发(三) 如何播放一帧音频数据上

    上一篇只要介绍了如何采集一帧音频,本篇就讲述如何播放一帧音频数据,这一篇我将分倆篇来详细介绍. Android SDK 提供了3套音频播放的API,分别是:MediaPlayer,SoundPool, ...

  9. Android应用开发基础篇(9)-----SharedPreferences

    链接地址:http://www.cnblogs.com/lknlfy/archive/2012/02/27/2370319.html 一.概述 对于SharedPreferences,我吧它理解为一种 ...

最新文章

  1. 脑电信号预处理--去趋势化(Detrended fluctuation analysis)
  2. 【PC工具】数学公式编辑器MathType v7.4.4.516你懂的版本
  3. 【学习笔记】高等数据基础
  4. python定时下载链接_python定时下载FTP指定文件
  5. 【Android】两种动画介绍(Tween动画、Frame动画)
  6. Android 爆发病毒,华米 OV 均受影响;微信宣战百度搜索;抖音遭约谈 | CSDN极客头条...
  7. HouseMD v0.2.1 发布,比Btrace更实用运行时诊断工具
  8. 高等数学学习笔记——第十讲——子数列与聚点原理(1. 数列收敛的归并性)
  9. sql取上个月年月_sql 查询本年、本月、本日记录的语句,附SQL日期函数
  10. 6 个清除 Linux 终端的命令
  11. PTA-1016——Phone Bills
  12. 谈谈你对Spring 的理解
  13. 【cookie】cookie是什么,如何使用cookie?
  14. unicode汉字内码表(转)
  15. 恶习为什么难戒?因为你在HALT状态
  16. PDF转Word文字可编辑的软件有哪些?
  17. 【大数据分析】k-cores,一种基于图数据结构的分解方法
  18. java字符集与字符编码 Unicode字符集
  19. 前端JavaScript AES解密 AES加密 ECB模式
  20. 2023美赛赛题思路分析

热门文章

  1. SpringBoot @CachePut注解的使用原理
  2. Redis的三种集群原理
  3. gradle5.6.3软件安装
  4. docker搭建replication集群
  5. Maven -- 未完待续
  6. 谁说程序员不懂爱情【Her】
  7. ahjesus Axure RP 7.0注册码
  8. 只要你上网,哪能不中毒?
  9. 一步一步学Silverlight 2系列(8):使用样式封装控件观感
  10. 在windows上搭建redis集群(主从复制)