android SharedPreferences 存儲對象

咱們知道SharedPreferences只能保存簡單類型的數據,例如,String、int等。java

若是想用SharedPreferences存取更復雜的數據類型(類、圖像等),就須要對這些數據進行編碼。apache

咱們一般會將複雜類型的數據轉換成Base64編碼,而後將轉換後的數據以字符串的形式保存在 XML文件中。數組

 

[java] view plain copy
 
  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.   
  17.         editor.commit();  
  18.     } catch (IOException e) {  
  19.         // TODO Auto-generated  
  20.     }  
  21.     Log.i("ok", "存儲成功");  
  22. }  


以後將其解碼:編碼

 

 

[java] view plain copy
 
  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.     //讀取字節  
  8.     byte[] base64 = Base64.decodeBase64(productBase64.getBytes());  
  9.       
  10.     //封裝到字節流  
  11.     ByteArrayInputStream bais = new ByteArrayInputStream(base64);  
  12.     try {  
  13.         //再次封裝  
  14.         ObjectInputStream bis = new ObjectInputStream(bais);  
  15.         try {  
  16.             //讀取對象  
  17.             oAuth_1 = (OAuthV1) bis.readObject();  
  18.         } catch (ClassNotFoundException e) {  
  19.             // TODO Auto-generated catch block  
  20.             e.printStackTrace();  
  21.         }  
  22.     } catch (StreamCorruptedException e) {  
  23.         // TODO Auto-generated catch block  
  24.         e.printStackTrace();  
  25.     } catch (IOException e) {  
  26.         // TODO Auto-generated catch block  
  27.         e.printStackTrace();  
  28.     }  
  29.     return oAuth_1;  
  30. }  

 須要導入一個包:commons-codec-1.4.jarspa

 

 

代碼下載

本文爲《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類的代碼:

.net

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文件中的代碼以下:
code

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文件中的代碼以下:
orm

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對象的代碼以下:
xml

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>
相關文章
相關標籤/搜索