How to Implement offline caching in android

Source: Internet
Author: User

How to Implement offline caching in android

The offline cache stores the data received from the server to the local device when the network is smooth. When the network is disconnected, the data in the local file is directly read.

Save the network data to the local device:

You can write a method for saving local data files by yourself and store them in any directory of the android system (of course, you have the permission ), however, in this case, the openFileOutput method of Context is the easiest and most suitable for our scenario.SaveObjectThe method demonstrates how to use openFileOutput to save data to a local file:

saveObject

public static boolean saveObject(Serializable ser, String file) {    FileOutputStream fos = null;    ObjectOutputStream oos = null;    try {        fos = AppContext.getInstance().openFileOutput(file, AppContext.getInstance().MODE_PRIVATE);        oos = new ObjectOutputStream(fos);        oos.writeObject(ser);        oos.flush();        return true;    } catch (Exception e) {        e.printStackTrace();        return false;    } finally {        try {            oos.close();        } catch (Exception e) {        }        try {            fos.close();        } catch (Exception e) {        }    }}

 

OpenFileOutput can directly obtain a file path associated with the application (in/data/ /Files), and then use ObjectOutputStream in java io Serialized objectWrite ( writeObject) To the obtained file, you can see that the above implementation process has two key methods: OpenFileOutput, writeObject And two key objects that call them.ContextAndObjectOutputStream. For details about serialization, refer to this article: Java object serialization and deserialization practices.

This is to save a serialized object locally. What is the relationship with our offline cache to save network data?

Yes, because most of the data obtained on the Internet can be converted to strings of the String type. Currently, the data returned by the server is generally a String in json format. String is actually a serializable object. The following is an example of a server that returns json data (in fact, it is a mobile client upgrade interface of the jcodecraeer website ):

{Url: tags}

 

AboveSaveObjectWe can save the data locally. In order to retrieve the file, we must think about how to name the saved file. If it is a simple article data, we can name the file name as the id of this Article. Because the id is unique, you can add a prefix before this id to avoid conflict with other data as much as possible, for example, in this article, we can use arc_java_id in the java section. For the document list, we can name it like this: the document category _ page number. In short, the naming principle is that it can be different from other offline data and is unique. Why not use a url as a file name? The url must be unique, but the url does not necessarily comply with the file naming rules.

The following describes how to read locally cached data.

When reading the cache, we only need to know the file name. The following readObject method reads the cached data according to the file name. In fact, many things correspond to the data stored above.

readObject

/*** Read object ** @ param file * @ return * @ throws IOException */public static Serializable readObject (String file) {FileInputStream FS = null; ObjectInputStream ois = null; try {FCM = AppContext. getInstance (). openFileInput (file); ois = new ObjectInputStream (FS); return (Serializable) ois. readObject ();} catch (FileNotFoundException e) {} catch (Exception e) {e. printStackTrace ();} finally {try {ois. close () ;}catch (Exception e) {}try {FCM. close () ;}catch (Exception e) {}} return null ;}

Application

The following code demonstrates how to use the following knowledge to store and read network data.

String key = codelist_ +  mCategory.getValue()  + _ + + page ;String result = ;//cacheif (HttpUtil.isNetworkConnected()) {        result = HttpUtil.http_get(AppContext.getInstance(), url );        HttpUtil.saveObject(result, key);        result = (String) HttpUtil.readObject(key);} else {    result = (String) HttpUtil.readObject(key);    if (result == null)        result = erro;}

 

When the network is smooth, obtain data from the server ( HttpUtil.http_get(AppContext.getInstance(), url )), And save the data locally (HttpUtil.saveObjectWhen the network is unavailable, the cached data is directly read from the local machine without interaction with the server.

WhereHttpUtilIt is a tool class related to the network. Three methods are involved here:

IsNetworkConnected () is used to determine whether the Network is available. saveObject has been provided. readObject has been implemented. http_get has been provided to read server data of the specified url.

WhileAppContext.getInstance()I wrote it myself to facilitateHttpUtilTo obtain the Context object.

The key here is the file name.

 

Additional requirements

Sometimes we still have this requirement. When users read the same data source at a specified interval, they can get it from the local device. If the interval is exceeded, they can get it from the network, the purpose of this operation is to save user traffic and avoid the interface delay caused by each data acquisition from the network.

The following describes how to determine whether to refresh server data based on the time interval. true indicates no, and false indicates yes (it is awkward, right?isCacheDataFailure):

public static boolean isCacheDataFailure(String cachefile) {    boolean failure = false;    File data = AppContext.getInstance().getFileStreamPath(cachefile);    if (data.exists()            && (System.currentTimeMillis() - data.lastModified()) > CACHE_TIME)        failure = true;    else if (!data.exists())        failure = true;    return failure;}

Compare the current time with the file modification time. CACHE_TIME is a fixed value (in milliseconds). You can replace it with any int type.

Add the judgment condition and change the code above:

String key = codelist_ +  mCategory.getValue()  + _ + + page ;String result = ;//cacheif (HttpUtil.isNetworkConnected() && HttpUtil.isCacheDataFailure(key)) {        result = HttpUtil.http_get(AppContext.getInstance(), url );        HttpUtil.saveObject(result, key);        result = (String) HttpUtil.readObject(key);} else {    result = (String) HttpUtil.readObject(key);    if (result == null)        result = erro;}

Complete

The above steps are sufficient for general applications. However, when the requirements are high, we have to consider that as time passes, more and more data will be cached, therefore, we need to add the expired cache deletion function. The principle is to set a threshold value to determine whether the total amount of the current cache exceeds the threshold value when saving the cache, if yes, the earlier cache will be deleted.

This implementation is a bit complicated. You can consider a simpler solution to regularly check the total cache volume (or each time the user opens a program). When the cache volume exceeds the threshold value, the user is prompted to actively delete the cache. We will not talk about the specific implementation.

Note: The first parameter of the openFileOutput () method is used to specify the file name. It cannot contain the path separator "/". If the file does not exist, Android will automatically create it. The created file is stored in/data/ /Files directory, such as/data/cn. itcast. action/files/itcast.txt, click "Window"-"Show View"-"Other" in the Eclipse menu, expand the android folder in the dialog box, and select the File Explorer View below, expand/data/in the File Explorer view/ The/files directory shows the file.
The second parameter of the openFileOutput () method is used to specify the operation mode. There are four modes: Context. MODE_PRIVATE = 0
Context. MODE_APPEND = 32768
Context. MODE_WORLD_READABLE = 1
Context. MODE_WORLD_WRITEABLE = 2
Context. MODE_PRIVATE: the default operation mode. This mode indicates that the file is private data and can only be accessed by the application itself. In this mode, the written content will overwrite the content of the original file, if you want to append the newly written content to the original file. You can use Context. MODE_APPEND.
Context. MODE_APPEND: the mode checks whether the file exists and appends the content to the file if it exists. Otherwise, a new file is created.
Context. MODE_WORLD_READABLE and Context. MODE_WORLD_WRITEABLE are used to control whether other applications have the permission to read and write the file.
MODE_WORLD_READABLE: indicates that the current file can be read by other applications; MODE_WORLD_WRITEABLE: indicates that the current file can be written by other applications.
If you want the file to be read and written by other applications, you can pass in:
OpenFileOutput(“itcast.txt ", Context. MODE_WORLD_READABLE + Context. MODE_WORLD_WRITEABLE)

 


 

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.