我们知道SharedPreferences只能保存简单类型的数据,例如,String、int等。

如果想用SharedPreferences存取更复杂的数据类型(类、图像等),就需要对这些数据进行编码。

我们通常会将复杂类型的数据转换成Base64编码,然后将转换后的数据以字符串的形式保存在 XML文件中。

  1. public void saveOAuth(OAuthV1 oAuth_1) {
  2. SharedPreferences preferences = getSharedPreferences("base64",
  3. MODE_PRIVATE);
  4. // 创建字节输出流
  5. ByteArrayOutputStream baos = new ByteArrayOutputStream();
  6. try {
  7. // 创建对象输出流,并封装字节流
  8. ObjectOutputStream oos = new ObjectOutputStream(baos);
  9. // 将对象写入字节流
  10. oos.writeObject(oAuth_1);
  11. // 将字节流编码成base64的字符窜
  12. String oAuth_Base64 = new String(Base64.encodeBase64(baos
  13. .toByteArray()));
  14. Editor editor = preferences.edit();
  15. editor.putString("oAuth_1", oAuth_Base64);
  16. editor.commit();
  17. } catch (IOException e) {
  18. // TODO Auto-generated
  19. }
  20. Log.i("ok", "存储成功");
  21. }

之后将其解码:

  1. public OAuthV1 readOAuth() {
  2. OAuthV1 oAuth_1 = null;
  3. SharedPreferences preferences = getSharedPreferences("base64",
  4. MODE_PRIVATE);
  5. String productBase64 = preferences.getString("oAuth_1", "");
  6. //读取字节
  7. byte[] base64 = Base64.decodeBase64(productBase64.getBytes());
  8. //封装到字节流
  9. ByteArrayInputStream bais = new ByteArrayInputStream(base64);
  10. try {
  11. //再次封装
  12. ObjectInputStream bis = new ObjectInputStream(bais);
  13. try {
  14. //读取对象
  15. oAuth_1 = (OAuthV1) bis.readObject();
  16. } catch (ClassNotFoundException e) {
  17. // TODO Auto-generated catch block
  18. e.printStackTrace();
  19. }
  20. } catch (StreamCorruptedException e) {
  21. // TODO Auto-generated catch block
  22. e.printStackTrace();
  23. } catch (IOException e) {
  24. // TODO Auto-generated catch block
  25. e.printStackTrace();
  26. }
  27. return oAuth_1;
  28. }

需要导入一个包:commons-codec-1.4.jar

代码下载

本文为《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>

android SharedPreferences 存储对象的更多相关文章

  1. Android SharedPreferences存储

    原创文章,转载请注明出处:http://www.cnblogs.com/baipengzhan/p/Android_SharedPreferences.html 一 概念 SharedPreferen ...

  2. Android SharedPreferences存储数据

    SharedPreferences是Android中最容易理解的数据存储技术,实际上SharedPreferences处理的就是一个key-value(键值对)SharedPreferences常用来 ...

  3. Android SharedPreferences存储详解

    什么是SharedPreferences存储 一种轻量级的数据保存方式 类似于我们常用的ini文件,用来保存应用程序的一些属性设置.较简单的参数设置. 保存现场:保存用户所作的修改或者自定义参数设定, ...

  4. Android——SharedPreferences存储(作业)

    作业:制作一个登录界面,以SP方式存储用户名.用户下次登录时自动显示上次填写的用户名 layout文件: <?xml version="1.0" encoding=" ...

  5. Android -- SharedPreferences存储信息

    背景                                                                                             Share ...

  6. Android SharedPreferences存储map的方法

    在网上查了一些资料后,精简改写后得出自己想用的形式,记录一下 public static void putHashMapData(Context context, String key, Map< ...

  7. Android数据存储方式--SharedPreferences

    Android数据存储方式有如下四种:SharedPreferences.存储到文件.SQLite数据库.内容提供者(Content provider).存储到网络服务器. 本文主要介绍一下Share ...

  8. Android应用开发SharedPreferences存储数据的使用方法

    Android应用开发SharedPreferences存储数据的使用方法 SharedPreferences是Android中最容易理解的数据存储技术,实际上SharedPreferences处理的 ...

  9. Android入门(九)文件存储与SharedPreferences存储

    原文链接:http://www.orlion.ga/578/ Android系统中主要提供了三种方式用于简单地实现数据持久化功能,即文件存储.SharedPreference存储以及数据库存储.当然, ...

随机推荐

  1. RAC 某节点不可用时,对应VIP是否可用

    实验环境:RHEL 6.5 + GI 11.2.0.4 + Oracle 11.2.0.4 验证:RAC 某节点不可用时,其对应VIP是否可用?是否可用于连接数据库? [grid@jyrac2 ~]$ ...

  2. 强大的图片加载框架Fresco的使用

    前面在卓新科技有限公司实习的时候,在自己的爱吖头条APP中,在图片异步加载的时候和ListView的滑动中,总会出现卡顿,这是因为图片的缓存做的不是足够到位,在项目监理的帮助下,有使用Xutils框架 ...

  3. 使用java代码关闭指定端口的程序-windows

    转载请请在页首注明作者与出处 一:问题由史 今天遇到一个问题,就是在实现自动化灾备的时候,发现原有死掉的程序没有完全关闭,当然这都不是本文的重点,重点是这个时候,我得把它完全关闭,所以才有了这篇文章. ...

  4. jQuery-1.9.1源码分析系列完毕目录整理

    jQuery 1.9.1源码分析已经完毕.目录如下 jQuery-1.9.1源码分析系列(一)整体架构 jQuery-1.9.1源码分析系列(一)整体架构续 jQuery-1.9.1源码分析系列(二) ...

  5. php内核分析(五)-zval

    这里阅读的php版本为PHP-7.1.0 RC3,阅读代码的平台为linux 实际上,从这个函数开始,就已经进入到了zend引擎的范围了. zend_eval_string_ex(exec_direc ...

  6. angularjs和ajax的结合使用 (二)

    今天我们来继续丰富上次的例子.我们来搞些 稍微复杂点的应用. 首先我们来加一个全选 的功能. 上一篇的例子里我们看到 分页时载入的是我们通过linq 查询自定义列 然后构建的匿名类 .使用这种EF框架 ...

  7. Win10 UWP开发系列:使用VS2015 Update2+ionic开发第一个Cordova App

    安装VS2015 Update2的过程是非常曲折的.还好经过不懈的努力,终于折腾成功了. 如果开发Cordova项目的话,推荐大家用一下ionic这个框架,效果还不错.对于Cordova.PhoneG ...

  8. 【无私分享:ASP.NET CORE 项目实战(第四章)】Code First 创建数据库和数据表

    目录索引 [无私分享:ASP.NET CORE 项目实战]目录索引 简介 本章我们来介绍下Asp.net Core 使用 CodeFirst 创建数据库和表,通过 控制台 和 dotnet ef 两种 ...

  9. go-使用 unsafe 修改 struct 中的 field 的值

    以下是方法,不要纠结原理,等东西积累多了,你才有能力纠结原理: 首先,你需要有一个这样的函数,这是在 nsq 的源码里直接抄过来的: func unsafeValueOf(val reflect.Va ...

  10. 来玩Play框架05 数据库

    作者:Vamei 出处:http://www.cnblogs.com/vamei 欢迎转载,也请保留这段声明.谢谢! 数据库是整个站点的数据储藏室.用户提交的数据可以存储在数据库中,以便未来使用.Pl ...