Offline File Cache for Android

Posted by beemzet on Fri, 24 May 2019 18:09:47 +0200

Preface

A good application must be a better cache.android can save data offline either in a file or in sqlite.Today, the author is here to share how to save the file.For example, a news app can also display previously viewed news information while offline. Imagine if there is no network or network acquisition fails, and if there is no cached user entering the app to display empty data, it is a bad user experience.

Apply for sd card permissions

Since you have to apply for permission in the manifest file to write a file, you will apply dynamically after 6.0, which is not described here.
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

Code Samples

1, save data as an object, create a Person class

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, Write save object to file, and read cache

public class CacheManager {
    //Save Object to Cache File
   public static boolean saveToJson(Context context, String fileName, Object object) {
        if (context == null || fileName == null || object == null) {
            return false;
        }
        //gson parses objects and converts them to strings
        String json = new Gson().toJson(object);
        //Get the file path under the sd card application package name, Android/data/application package name/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;
    }

//Reads the saved cache object from the cache and resolves directly gson to 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;
    }
}

The AppOperator class is a gson help class

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;
    }

}

Use examples

1, Save Cache Object Example

...
Instantiate a News object (the actual usage scenario should be encapsulated data obtained from the server);
Person person= new Person ();
Person.setName (Xiaoming);
person.setSex("man");
person.setAge(18);

//Call the save method of the caching tool class, note that the second parameter is the file name, otherwise personObject will be used here if read later is not consistent
CacheManager.saveToJson(getActivity(), "personObject", person);


2, Read Cache Object Example

Type type = new TypeToken<Person>(){}.getType();
Person person = (Person)CacheManager.readJson(getActivity(), "personObject", type);
//person gets what it can do to show the caching effect

Application Scene Cache Collection list

Add Save to 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;
    }

Read Method

    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);
    }

Save Person Collection List

List<Person> persons = new ArrayList<Person>();
persons.add(person1);
persons.add(person2);
persons.add(person3);
CacheManager.saveList(context,"persons",persons);

Get Cached Person

List<Person> persons = CacheManager.readListJson(context,"persons",Person.class);

Topics: Android network JSON SQLite