Android离线之文件缓存

前言

一款好的应用一定是缓存做的比较优秀。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);
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值