原文地址:android 使用SharedPreferences保存对象_sharedpreferences存储对象_暴走邻家的博客-CSDN博客
一.使用Gosn将对象转成String后存入SharedPreferences
下面是我封装改账本(Book)的Bean:
package beans;
/**
* Created by Chase on 2017/5/3.
*/
public class BookBean {
public String bookName;
public int bookBgSrc;
public BookBean(){
}
public BookBean(String bookName,int bookBgSrc){
this.bookName = bookName;
this.bookBgSrc =bookBgSrc;
}
public String getBookName(){
return bookName;
}
public int getBookBgSrc(){
return bookBgSrc;
}
public void setBookBgSrc(int bookBgSrc) {
this.bookBgSrc = bookBgSrc;
}
public void setBookName(String bookName) {
this.bookName = bookName;
}
}
下面编写两个方法用来存储和读取这个Bean:
public class SpUtils {
private static SharedPreferences sp;
/**
* 4.存储账本bookBean的list
*/
public static void putBookBean(Context ctx, List<BookBean> bookList) {
if (sp == null) {
sp = ctx.getSharedPreferences("config", MODE_PRIVATE);
}
SharedPreferences.Editor editor = sp.edit();
Gson gson = new Gson();
String json = gson.toJson(bookList);
editor.putString(ConstantValue.BOOK_BEAN, json);
editor.commit();
}
}
/**
* 读取账本bookBean的list
*/
public static List<BookBean> getBookBean(Context ctx) {
if (sp == null) {
sp = ctx.getSharedPreferences("config", MODE_PRIVATE);
}
Gson gson = new Gson();
String json = sp.getString(ConstantValue.BOOK_BEAN, null);
Type type = new TypeToken<List<BookBean>>() {
}.getType();
List<BookBean> arrayList = gson.fromJson(json, type);
return arrayList;
}
这个需要导入Gosn jar包,并且实体类需要满足gosn对于实体类的要求,具体的大家可以查找资料。
二.使用Base64将对象编码成String后存入SharedPreferences
由于二进制数据经过编码后可以用SharedPreferences以字符串的形式存储,所以保存对象也成为了可能,但是这个类必须是可序列化即implements Serializable(实际上Serializable接口是个空接口,只是为了标记该对象是被序列化的),然后可以通过ObjectOutputStream保存再转为二进制存储。
1、保存序列化的对象
/**
* @param user
*/
public static void saveUser(Context context, String preferenceName,String key,User user) throws Exception {
if(user instanceof Serializable) {
SharedPreferences sharedPreferences = context.getSharedPreferences(preferenceName, context.MODE_PRIVATE);
SharedPreferences.Editor editor = sharedPreferences.edit();
ByteArrayOutputStream baos = new ByteArrayOutputStream();
try {
ObjectOutputStream oos = new ObjectOutputStream(baos);
oos.writeObject(user);//把对象写到流里
String temp = new String(Base64.encode(baos.toByteArray(), Base64.DEFAULT));
editor.putString(key, temp);
editor.commit();
} catch (IOException e) {
e.printStackTrace();
}
}else {
throw new Exception("User must implements Serializable");
}
}
2、读取序列化的对象
public static User getUser(Context context, String preferenceName,String key) {
SharedPreferences sharedPreferences=context.getSharedPreferences(preferenceName,context.MODE_PRIVATE);
String temp = sharedPreferences.getString(key, "");
ByteArrayInputStream bais = new ByteArrayInputStream(Base64.decode(temp.getBytes(), Base64.DEFAULT));
User user = null;
try {
ObjectInputStream ois = new ObjectInputStream(bais);
user = (User) ois.readObject();
} catch (IOException e) {
}catch(ClassNotFoundException e1) {
}
return user;
}
当然Sharedpreferences也是可以存储各种集合类的比如说List,都可以通过转为ObjectOutputStream输出流进而编码存储:
public static String listToString(List<?> list)throws IOException {
// 实例化一个ByteArrayOutputStream对象,用来装载压缩后的字节文件。
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
// 然后将得到的字符数据装载到ObjectOutputStream
ObjectOutputStream objectOutputStream = new ObjectOutputStream(
byteArrayOutputStream);
// writeObject 方法负责写入特定类的对象的状态,以便相应的 readObject 方法可以还原它
objectOutputStream.writeObject(list);
// 最后,用Base64.encode将字节文件转换成Base64编码保存在String中
String listString = new String(Base64.encode(
byteArrayOutputStream.toByteArray(), Base64.DEFAULT));
// 关闭objectOutputStream
objectOutputStream.close();
return listString;
}
@SuppressWarnings("unchecked")
public static List<?> StringToList(String listString) throws StreamCorruptedException, IOException,
ClassNotFoundException {
byte[] mobileBytes = Base64.decode(listString.getBytes(),
Base64.DEFAULT);
ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(
mobileBytes);
ObjectInputStream objectInputStream = new ObjectInputStream(
byteArrayInputStream);
List<?> WeatherList = (List<?>) objectInputStream
.readObject();
objectInputStream.close();
return WeatherList;
}
这个我自己测试过,是可以正常使用的,不过实体类需要实现Serializable接口,而且效率可能比较低,这个大家可以去网上查找资料。