The most commonly used cache in Android is the picture, which can improve the efficiency of the application and save the user's traffic.
The cache of pictures can be divided into SD card cache and memory cache, and can be used together.
the strategy for image caching in Android is to cache the image on the storage device (such as the SD card, which is what we call the SD card cache) The first time the picture is loaded from the network, and also cache a copy (memory cache) in memory. So when the next use or the network request the picture, go to the memory first (because reading from memory is faster than from the SD card, so we first read from memory, so that in saving traffic and also improve the performance of the program), if not in memory, then go to the SD card to get, If there is no SD card, then go to the network request.
Of course, due to the storage capacity of the device, we also need to cache the image resources of the SD card in a suitable time to delete. Of course, the right time how to define the benevolent see, the current commonly used is the LRU algorithm, so a complete cache policy includes adding, fetching, deleting three types of operations
LRU Cache algorithm
LRU (Least recently used), the least recently used algorithm, its core idea is that when the cache is full, priority elimination deletes the least recently used cache objects.
There are two types of caches that use the LRU algorithm:
- LruCache, used to implement memory caching
- Disklrucache, for implementing storage device caching (it is not part of the official SDK but is officially recommended)
- Other storage methods, such as file storage. Sqllite Storage, etc.
LruCache
LRUCache is provided by Android 3.1, and using the Support-4 Compatibility Pack LRUCache can be backwards compatible to 2.2.
LRUCache internally uses a linkedhashmap to store externally supplied cache objects in a strongly referenced manner, providing a put and get method to add and retrieve cache objects, and LRUCache is thread-safe.
1, the use of LRUCache
Runtime.getRuntime().maxMemory()
In Java, the Java Virtual machine (the process) can be used to construct the largest amount of memory dug in from the manipulation system, while in Android, the maximum available memory in the application is returned in bytes. can also be used
((ActivityManager)getSystemService(Context.ACTIVITY_SERVICE)).getMemoryClass()
, but the unit of return value is M.
Runtime.getRuntime().totalMemory()
What is returned in Java is the size of the memory that the Java Virtual machine has now dug up from the manipulation system, that is, all the memory that the Java virtual machine is taking up at that time, and what is returned in Android is that the application has acquired the memory, so TotalMemory () is slowly increasing.
Runtime.getRuntime().freeMemory()
In simple terms, memory that has been acquired but not yet used.
To create the LRUCache code:
//Create LRUCache ObjectintMaxSize = (int) Runtime.getruntime (). MaxMemory ();//returns byteintCacheSize = maxSize/1024x768/8;//Create LRUCache to provide maximum cache capacityMcache =NewLrucache<string, bitmap> (cacheSize) {@Override protected int sizeOf(String key, Bitmap value) {return Super. sizeOf (key, value); }@Override protected void entryremoved(BooleanEvicted, String key, Bitmap OldValue, Bitmap newvalue) {//When the call to put or remove triggers this method, you can complete some of the resource recycling operations here Super. entryremoved (evicted, Key, OldValue, NewValue); }};mcache.put (key, value);//Add Cache objectMcache.get (key);//Get Cached objectsMcache.remove (key);//Delete cache objectsMcache.resize (1024x768);//Reset the total capacity size of the cache
Disklrucache
As mentioned above, Disklrucache is not part of the Android SDK, but it has been officially recognized and recommended by Google, its source is here or here, in fact, GitHub is the production of serious ha. In the use of Disklrucache, the first to download from the Internet Disklrucache source code, and then put in their own project compiled to normal use.
1, the creation of Disklrucache
The
Disklrucache cannot be created by constructing a method that uses the open method to wear itself
public static Disklrucache open (File directory, int appversion, int Valuecount, long maxSize)
1. Directory indicates that the disk cache storage path
Cache directory has no specific limitations and can be defined according to the requirements. In general, you can select the /sdcard/android/data/<application package>/cache
directory on the SD card, which is the application cache directory specified by the Android system. When the app unloads, the cache is also purged by the system, and of course the other directories on the SD card can be selected, or the current app directory under Data can be selected. Of course, a strictly forbidden procedure should also consider whether the SD card exists and so on.
2. appversion indicates the version number of the app
when appversion changes, the previous cache is cleared, so if it is not necessary, we specify a 1 for it, and no longer can be changed
3. Valuecount represents the number of data for a single node, That is, the same key can correspond to how many cache files, generally we choose 1.
4. MaxSize The total size of the cache.
privatevoidcreateDiskLruCache() { try { File cacheDir = getDiskCacheDir(DiskLruCacheActivity.this"bitmapsCache"); if (!cacheDir.exists()) { cacheDir.mkdirs(); } 11, MAX_DISK_CACHE); catch (IOException e) { Log.i("disk cache""createDiskLruCache e: " + e.toString()); } }
2. Disklrucache Add Cache
The cache additions for Disklrucache are done through the editor, with the following code:
//Add a picture to the hard disk cache Private void Exeadd2diskcache(Disklrucache.editor Editor) {if(Editor! =NULL) {Try{//Create Disklrucache when you set a node with only one data, so here the index is set directly to 0OutputStream OutputStream = Editor.newoutputstream (0);if(Downloadurltostream (IMAGEURL, OutputStream)) {Editor.commit ();//Commit write operationsLOG.I ("Disk Cache","OnCreate editor.commit ()"); }Else{Editor.abort ();//Rewind the entire operationLOG.I ("Disk Cache","OnCreate editor.abort ()"); } disklrucache.flush (); }Catch(IOException e) {LOG.I ("Disk Cache","OnCreate e:"+ e.tostring ()); } } }//Establish an HTTP request and get the bitmap object. PrivateBooleanDownloadurltostream(String urlstring, OutputStream outputstream) {HttpURLConnection URLConnection =NULL; Bufferedoutputstream out=NULL; Bufferedinputstreaminch=NULL;Try{Final URL url =NewURL (urlstring); URLConnection = (httpurlconnection) url.openconnection ();inch=NewBufferedinputstream (Urlconnection.getinputstream (),8*1024x768); out=NewBufferedoutputstream (OutputStream,8*1024x768);intb while((b =inch. read ())! =-1) { out. write (b); }return true; }Catch(Final IOException E) {E.printstacktrace (); }finally{if(URLConnection! =NULL) {urlconnection.disconnect (); }Try{if( out!=NULL) { out. Close (); }if(inch!=NULL) {inch. Close (); } }Catch(Final IOException E) {E.printstacktrace (); } }return false; }
Of course, the above is only to demonstrate the use of Disklrucache, in the actual project and the project needs to combine, consider the actual situation, such as Caused by: android.os.NetworkOnMainThreadException
anomalies.
3, Disklrucache from the cache to find
First, you need to convert the URL into a key, and then through the Disklrucache get method to get a snapshot object, in the snapshot object to get the input stream of the cache file, and then convert the input flow to Bitamp object.
//Get the bitmap object from the cache PrivateBitmapGetcachebitmap() {String key = Hashkeyfordisk (IMAGEURL);//Convert URL to key Try{Disklrucache.snapshot Snapshot = Disklrucache.Get(key);//Get Snapshot object by key if(SnapShot! =NULL) {InputStream is= Snapshot.getinputstream (0);//Get the input stream of the cache file through the Snapshot objectBitmap Bitmap = Bitmapfactory.decodestream ( is);//Convert input flow to bitmap object returnBitmap } }Catch(IOException e) {E.printstacktrace (); }return NULL; }
For more information about Bitmapfactory.decodestream (IS) click here to view
4. Disklrucache Cache Deletion
privatevoiddeleteCacheBitmap(String url){ try { String key = hashKeyForDisk(imageUrl); diskLruCache.remove(key); catch (IOException e) { e.printStackTrace(); } }
This remove method, if not necessary, we try not to call, because we have set the maximum cache capacity, when the capacity is exceeded, the system will automatically delete the deleted cache file according to the LRU algorithm.
5. Disklrucache several other important and common methods
- Disklrucache.delete () Delete all cached data
- Disklrucache.delete () returns the size, in bytes, of all cached data under the current cache path
- Editor.abort () Picture download When an exception occurs, the entire operation can be rolled back by this method
- Editor.commit () commits the write operation, which is always called when writing to the cache data.
- Disklrucache.flush () This method is used to synchronize the in-memory operation record to the log file (that is, the journal file, the system LRU algorithm relies on this file, because this file is stored in the data operation record) , but not every write cache to call the Flush () method, frequent calls do not bring any benefits, only add extra time to synchronize the journal file. The standard practice is to call the flush () method in the activity's OnPause () method.
- Disklrucache.close () This method is used to close the Disklrucache and is a method corresponding to the open () method. The close () method should be called only in the OnDestroy () method of the activity when it is closed and no longer can invoke any method of caching data in Disklrucache.
6. Journal File
After performing the write operation, let's look at what files are in the corresponding directory (/sdcard/android/data//cache)?
After opening the cache directory, I found that there is only one Bitmapscache folder in it, where does this file come from? This is actually the above in the creation of Disklrucache instances in the URL of the incoming (see Getdiskcachedir method), why do you want to specify such a directory? In fact, it is similar to the concept of classification, such as you can put the cached bitmap in a folder, file or other format of the data into another folder.
Open the Bitmapscache folder, and what are its subdirectories? First, there is a file, the file name is very long and no rules, completely do not understand what it means; There is also a journal file below. In fact, a long file name is a cached picture, each file corresponds to a picture, if we cache a lot of images, there will be a bunch of such files, and the journal file is a disklrucache log file, As I said above: This file holds a record of the operation of the data. Such as:
Open Journal this file and find it grows so neatly:
The first line of string "Libcore.io.DiskLruCache" means that we are using disklrucache technology, then there are three rows, and each row has only one "1", where the first row of "1" represents the version number of Disklrucache, This value is constant 1, the 2nd line of "1" indicates the version number of the application, the version number we passed in the open () method, what is shown here, and the third "1" represents Valuecount, which represents the number of data for a single node, and this value is also passed in the open () method. , typically 1. The next is a blank line that marks the beginning of the record of the recording of the data.
Next, there will be a row of data beginning with dirty, dirty followed by the key,dirty of the file to start writing data to the cache, but what the result is unknown. The commit () method is then called to indicate the success of the write cache, when a clean record is written to the journal indicating that the data was written successfully, and if the data write fails, the Abort () method is called to roll back the entire operation, and a remove record is written to journal. When the Get () method is called to read a cached data, a read record is written to the journal file, and some rows are followed by a number (20090, 6602), which is the size of the cached picture, in bytes.
===============================================
Previous: The use of bitmap
For more information please follow my topic
Reprint please specify the original link:
Http://www.jianshu.com/p/635fceca82d3
===============================================
This day, in Jane's book to see a post, inside there are a few pictures feel pretty good, send out, together look:)
Android Bitmap Cache Policy