How to implement offline caching in "Go" Android

Source: Internet
Author: User
Tags erro

Original address: http://www.jcodecraeer.com/a/anzhuokaifa/androidkaifa/2014/1209/2136.html

Offline caching is when the network is unblocked, the data received from the server is saved locally, and the data in the local file is read directly after the network is disconnected.

To save network data locally:

You can write your own way to save the data cost of the file, stored in any directory of the Android system (of course, have permission to do), but in this case the use of the context of the Openfileoutput method is the most convenient and most consistent with our scene, the following The Saveobject method demonstrates how to save data in a local file using Openfileoutput:

saveObject

1  Public Static Booleansaveobject (Serializable ser, String file) {2FileOutputStream fos =NULL;3ObjectOutputStream Oos =NULL;4     Try {5FOS =appcontext.getinstance (). Openfileoutput (file, Appcontext.getinstance (). Mode_private);6Oos =NewObjectOutputStream (FOS);7 Oos.writeobject (Ser);8 Oos.flush ();9         return true;Ten}Catch(Exception e) { One e.printstacktrace (); A         return false; -}finally { -         Try { the oos.close (); -}Catch(Exception e) { -         } -         Try { + fos.close (); -}Catch(Exception e) { +         } A     } at}

Openfileoutput can directly obtain a file path associated with the application (under/data/data/<package name>/files), and then use the ObjectOutputStream in Java io to The serialized object writes ( writeObject ) to the resulting file, you can see that the above implementation process has two key methods:openfileoutput, writeObject 以及调用它们的两个关键对象ContextObjectOutputStream . For serialization you can see this article:serialization and deserialization practices for Java objects

This is to save a serialized object locally, what does it have to do with our offline cache for storing network data?

, because most of the data obtained online can be converted to string types, and now the data returned by the server is typically a JSON-formatted string. Strings of type string are actually serializable objects. Here is an example of a server returning JSON data (in fact, Jcodecraeer):

1 {"url": "http://jcodecraeer.com/uploads/soft/android/CodeBox.apk", "Versioncode": "7", " Updatemessage ":" Increased offline cache, classification filtering feature Fixed version compatibility issue "}

Using the Saveobject method above we can save the data locally, in order to be able to remove the file we have to figure out how to name the saved file, if it is a simple article of data, we can directly name the file as the ID of this article, because the ID is unique , in order to not conflict with other data as far as possible, you can also add a prefix to this ID, such as this article is under the Java column we can arc_java_id. If it is a list of articles we can name: Article category _ page number, in short, the principle of naming is can and other offline data differences, there is uniqueness. Why not use URLs as file names? URLs are definitely unique, but URLs do not necessarily conform to the naming conventions of files.

Here's how to read the locally cached data

When we read the cache, we just need to know the file name, and the following ReadObject method is used to read the cached data according to the file name. In fact, a lot of things are corresponding to the data stored above.

readObject

1 /**2 * Read Object3  *4  * @paramfile5  * @return6  * @throwsIOException7  */8  Public StaticSerializable readobject (String file) {9FileInputStream FIS =NULL;TenObjectInputStream Ois =NULL; One     Try { AFIS =appcontext.getinstance (). openfileinput (file); -OIS =NewObjectInputStream (FIS); -         return(Serializable) ois.readobject (); the}Catch(FileNotFoundException e) { -}Catch(Exception e) { - e.printstacktrace (); -}finally { +         Try { - ois.close (); +}Catch(Exception e) { A         } at         Try { - fis.close (); -}Catch(Exception e) { -         } -     } -     return NULL; in}

Use

The following code demonstrates how to store and read network data using the above knowledge

1String key = "Codelist_" + mcategory.getvalue () + "_" + +page;2String result = "";3 //Cache4 if(httputil.isnetworkconnected ()) {5result =Httputil.http_get (appcontext.getinstance (), URL);6 httputil.saveobject (result, key);7result =(String) httputil.readobject (key);8}Else {9result =(String) httputil.readobject (key);Ten     if(Result = =NULL) Oneresult = "Erro"; A}

When the network is unblocked, the data is fetched from the server (), and the HttpUtil.http_get(AppContext.getInstance(), url ) data is saved to local ( HttpUtil.saveObject ), and when the network is unavailable, the cached data is read directly from the local, not interacting with the server.

HttpUtilThis is a network-related tool class, which involves three methods:

1 isnetworkconnected () Determine if the network is available 2 Saveobject above has given the realization 3 ReadObject above has given the realization 4 http_get read server data for the specified URL

AppContext.getInstance()是我自己写的,是为了方便在HttpUtil的静态方法中获得Context对象。

这里的key就是文件名。

 

Additional requirements

Sometimes we have this requirement that when the user reads the same data source at a specified interval, it gets from the network more than the time interval, and this is done to save the user's traffic, and also avoids the interface delays caused by each fetch of data from the network.

The following implements how to determine whether the server data needs to be refreshed based on the time interval, true indicates no need, false indicates need (very awkward, it is isCacheDataFailure related to the name):

1  Public Static Booleaniscachedatafailure (String cachefile) {2     BooleanFailure =false;3File data =appcontext.getinstance (). Getfilestreampath (cachefile);4     if(data.exists ()5&& (System.currenttimemillis ()-data.lastmodified ()) >cache_time)6Failure =true;7     Else if(!data.exists ())8Failure =true;9     returnfailure;Ten}

Compare the current time to the modified time of the file, Cache_time is a fixed value (in milliseconds) and you can replace it with any int type.

Add this condition and the code above is changed to:

1String key = "Codelist_" + mcategory.getvalue () + "_" + +page;2String result = "";3 //Cache4 if(Httputil.isnetworkconnected () &&httputil.iscachedatafailure (Key)) {5result =Httputil.http_get (appcontext.getinstance (), URL);6 httputil.saveobject (result, key);7result =(String) httputil.readobject (key);8}Else {9result =(String) httputil.readobject (key);Ten     if(Result = =NULL) Oneresult = "Erro"; A}

Perfect

The above steps are sufficient for the general application, but in the case of higher requirements, we also have to consider that over time, the cache data will be more and more, so we need to increase the deletion of expired cache function, the principle is to set a threshold, when the cache is saved, the current cache is determined whether the total is greater than the threshold, If yes, the cache is deleted earlier.

This implementation is a bit complex, you can consider a simpler scenario, periodic check (or the user every time the program is opened) the total amount of cache, when greater than the threshold, prompting the user to actively delete. The concrete implementation is not much to say.

Note: Openfileoutput ()The first parameter of the method is used to specify the file name, cannot contain the path delimiter "/", and if the file does not exist, Android will automatically create it. The created file is saved in the/data/data/<package Name>/files directory, such as:/data/data/cn.itcast.action/files/itcast.txt, by clicking on the Eclipse menu " Window "-" Show View "-" other ", expand the Android folder in the Conversation window, select the File Explorer view below, and then expand/data/data/<package in the File Explorer view The file can be seen in the Name>/files directory.
The second parameter of the Openfileoutput () method is used to specify the mode of operation, with four modes: context.mode_private = 0
Context.mode_append = 32768
context.mode_world_readable = 1
Context.mode_world_writeable = 2
Context.mode_private: As the default mode of operation, which means that the file is private data and can only be accessed by the app itself, in which the content of the write overwrites the contents 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, appends content to the file, or creates a new file.
Context.mode_world_readable and context.mode_world_writeable are used to control whether other apps have permission to read and write to the file.
Mode_world_readable: Indicates that the current file can be read by another application; Mode_world_writeable: Indicates that the current file can be written by another application.
If you want the file to be read and written by another app, you can pass in:
Openfileoutput ("Itcast.txt", context.mode_world_readable + context.mode_world_writeable);

How to implement offline caching in "Go" Android

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.