一、SharedPreferences將數據文件保存在指定路徑上
SharedPreferences原則上是只能保存在當前應用程序私有的shared_prefs目錄中,不過也不是絕對的,我們可以用一些非常規的方法改變存儲目錄,反射技術是很好的選擇。
先上實現代碼:
~~~
private SharedPreferences share;
private SharedPreferences.Editor editor;
~~~
修改路徑關鍵代碼:
~~~
private void initSharedPreferences(String path,String name,int mode)
{
try {
Field field =ContextWrapper.class.getDeclaredField("mBase");
field.setAccessible(true);
Object obj = field.get(this);
field = obj.getClass().getDeclaredField("mPreferencesDir");
field.setAccessible(true);
File file = new File(path);
field.set(obj, file);
share = getSharedPreferences(name, mode);
editor = share.edit();
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
}
}
~~~
~~~
Field field =ContextWrapper.class.getDeclaredField("mBase");
~~~
獲取ContextWrapper對象中的mBase變量,該變量保存了ContextImpl對象,ContextImpl對象中的mPreferencesDir保存了數據文件的保存路徑。
~~~
share = getSharedPreferences(name, mode);
~~~
執行這句后會在指定目錄下創建文件用來保存數據。
PS:使用反射技術,要求仔細研究源碼,這樣才會知道要去修改哪個地方,哪個變量。
使用:
~~~
initSharedPreferences("/data/fly","config",Activity.MODE_PRIVATE);
editor.putString("AA", "AAaa");
editor.commit();
Toast.makeText(this, share.getString("AA", ""), 1000).show();
~~~
二、SharedPreferences保存圖片
SharedPreferences原則上只能將字符串以key-value的形式保存,但是我們可以采用編碼的方式將任何二進制數據轉化為字符串,從而將可以將二進制數據保存在SharedPreferences文件中,最常用的編碼格式是Base64.
~~~
private void saveDrawable(int id)
{
Bitmap bitmap = BitmapFactory.decodeResource(getResources(), id);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
bitmap.compress(CompressFormat.JPEG, 50, baos);
String imageBase64 = new String(Base64.encodeToString(baos.toByteArray(),Base64.DEFAULT));
editor.putString("P",imageBase64 );
editor.commit();
}
private Drawable loadDrawable()
{
String temp = share.getString("P", "");
ByteArrayInputStream bais = new ByteArrayInputStream(Base64.decode(temp.getBytes(), Base64.DEFAULT));
return Drawable.createFromStream(bais, "");
}
~~~
三、SharedPreferences保存對象
由于二進制數據經過編碼后可以用SharedPreferences以字符串的形式存儲,所以保存對象也稱為可能。
~~~
private void saveProduct(Product product)
{
ByteArrayOutputStream baos = new ByteArrayOutputStream();
try {
ObjectOutputStream oos = new ObjectOutputStream(baos);
oos.writeObject(product);
String temp = new String(Base64.encode(baos.toByteArray(), Base64.DEFAULT));
Log.i("AAA", temp);
editor.putString("product", temp);
editor.commit();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
private Product getProduct()
{
String temp = share.getString("product", "");
ByteArrayInputStream bais = new ByteArrayInputStream(Base64.decode(temp.getBytes(), Base64.DEFAULT));
Product product = null;
try {
ObjectInputStream ois = new ObjectInputStream(bais);
product = (Product) ois.readObject();
} catch (IOException e) {
// TODO Auto-generated catch block
Log.i("AAA", e.toString());
}catch(ClassNotFoundException e1)
{
Log.i("AAA", e1.toString());
}
return product;
}
~~~
對象可以被SharedPreferences存儲的前提是該對象被序列化了,也就是說要實現Serializable接口,實際上Serializable接口是個空接口,只是為了標記該對象是被序列化的。
~~~
public static class Product implements Serializable
{
String name;
String id;
int count;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public int getCount() {
return count;
}
public void setCount(int count) {
this.count = count;
}
public String toString()
{
return "name:"+name+" id:"+id+" count:"+count;
}
}
~~~
如果該類是內部類的話要寫成static 不然會出現java.io.NotSerializableException異常:[解決辦法點這里
](http://blog.csdn.net/tangnengwu/article/details/37901059)