前言
一款好的应用一定是缓存做的比较优秀。android离线状态下保存数据可以保存到文件里面,也可以保存到sqlite里面。今天笔者在这里分享一下文件保存的方式。比如新闻app,在离线状态下也可以显示之前浏览过的新闻信息,想象一下如果没有网络或者网路获取失败,如果没有缓存的化用户进入app显示空数据是一件不好的用户体验。
申请sd卡权限
既然要写文件就要在manifest文件里面申请权限,6.0以后要动态申请,这里不再叙述
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
代码示例
1,以建立对象的方式保存数据,创建一个Person 类
public class Person implements Serializable {
String name;
String sex;
int age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
2,编写保存object对象到文件,和读取缓存
public class CacheManager {
//保存对象到缓存文件
public static boolean saveToJson(Context context, String fileName, Object object) {
if (context == null || fileName == null || object == null) {
return false;
}
//gson解析对象,转化为字符串
String json = new Gson().toJson(object);
//获取sd卡应用包名下的文件路径,Android/data/应用包名/files/fileName
String path = context.getExternalCacheDir() + "/" + fileName;
File file = new File(path);
FileOutputStream os = null;
try {
if (!file.exists() && !file.createNewFile())
return false;
os = new FileOutputStream(file);
os.write(json.getBytes("utf-8"));
return true;
} catch (Exception e) {
e.printStackTrace();
} finally {
StreamUtil.close(os);
}
return false;
}
//从缓存里读取出保存的缓存对象,直接gson解析为Object
public static <T> T readJson(Context context, String fileName, Type clx) {
if (clx == null || context == null) return null;
String path = context.getExternalCacheDir() + "/" + fileName;
File file = new File(path);
if (!file.exists())
return null;
Reader reader = null;
try {
reader = new FileReader(file);
return AppOperator.getGson().fromJson(reader, clx);
} catch (Exception e) {
e.printStackTrace();
} finally {
StreamUtil.close(reader);
}
return null;
}
}
AppOperator类是一个gson帮助类
public class AppOperator {
private static Gson GSON_INSTANCE;
public static Gson createGson() {
GsonBuilder gsonBuilder = new GsonBuilder();
//gsonBuilder.setExclusionStrategies(new SpecificClassExclusionStrategy(null, Model.class));
gsonBuilder.setDateFormat("yyyy-MM-dd HH:mm:ss");
JsonDeserializer deserializer = new IntegerJsonDeserializer();
gsonBuilder.registerTypeAdapter(int.class, deserializer);
gsonBuilder.registerTypeAdapter(Integer.class, deserializer);
deserializer = new FloatJsonDeserializer();
gsonBuilder.registerTypeAdapter(float.class, deserializer);
gsonBuilder.registerTypeAdapter(Float.class, deserializer);
deserializer = new DoubleJsonDeserializer();
gsonBuilder.registerTypeAdapter(double.class, deserializer);
gsonBuilder.registerTypeAdapter(Double.class, deserializer);
deserializer = new StringJsonDeserializer();
gsonBuilder.registerTypeAdapter(String.class, deserializer);
// gsonBuilder.registerTypeAdapter(Tweet.Image.class, new ImageJsonDeserializer());
return gsonBuilder.create();
}
public synchronized static Gson getGson() {
if (GSON_INSTANCE == null)
GSON_INSTANCE = createGson();
return GSON_INSTANCE;
}
}
使用示例
1,保存缓存对象示例
...
实例化一个News对象(实际使用场景应该是从服务器上获取到的数据经过封装后得到);
Person person= new Person ();
person.setName("小明");
person.setSex("男");
person.setAge(18);
//调用缓存工具类的保存方法,注意第二个参数为文件名,要不后面读取时保持一致这里用personObject
CacheManager.saveToJson(getActivity(), "personObject", person);
2,读取缓存对象示例
Type type = new TypeToken<Person>(){}.getType();
Person person = (Person)CacheManager.readJson(getActivity(), "personObject", type);
//person就获取到了可以用来展示缓存效果
应用场景缓存集合list
在CacheManager里面增加保存
private static <T> boolean saveList(Context context,String fileName, List<T> list) {
Writer writer = null;
try {
String path = context.getExternalCacheDir() + "/" + fileName;
File file = new File(path);
if (!file.exists())
return null;
writer = new FileWriter(file);
AppOperator.getGson().toJson(list, writer);
return true;
} catch (Exception e) {
e.printStackTrace();
} finally {
StreamUtil.close(writer);
}
return false;
}
读取方法
private static Type getListType(Class clx) {
return $Gson$Types.canonicalize((new ParameterizedTypeImpl(null, List.class, clx)));
}
public static <T> T readListJson(Context context, String fileName, Class clx) {
if (clx == null || TextUtils.isEmpty(fileName)) return null;
Type type = getListType(clx);
return readJson(context, fileName, type);
}
保存Person集合List
List<Person> persons = new ArrayList<Person>();
persons.add(person1);
persons.add(person2);
persons.add(person3);
CacheManager.saveList(context,"persons",persons);
获取缓存Person
List<Person> persons = CacheManager.readListJson(context,"persons",Person.class);