Hard disk caching Technology Disklrucache Technology < notes >

Source: Internet
Author: User

The core solution to prevent multi-image oom is to use LRUCache technology, but LRUCache only manages the storage and release of images in memory, and if the images are removed from memory, it is obviously time-consuming to reload them from the network. So Google offers a solution for hard disk caching: Disklrucache (not officially written by Google, but officially certified). In general, news apps are stored in the local cache after they get the data from the network, so even if the phone is not networked, it can still load the previously browsed news. The caching technique used is naturally disklrucache. Take NetEase news As an example, its Android app package name is com.netease.newsreader.activity, so the data cache address should be/sdcard/android/data/ Com.netease.newsreader.activity/cache, this article Allison under the journal file is a log file Disklrucache, the program for each picture of the operation of the record is stored in this file, Seeing journal This document marks the program's use of Disklrucache technology.

Location of 1.DiskLruCache cache data:

Generally in the/sdcard/android/data/<application package>/cache this path, the choice in this position has two points of benefit: First, this is stored on the SD card, As a result, even more data is cached without any impact on the phone's built-in storage space. Second, the path is identified by the Android system as the application's cache path, and when the program is uninstalled, the data will be erased together, so there will be no more residual data on the phone after the removal process.

Usage of 2.DiskLruCache:

Since Disklrucache is not written by Google, the class is not included in the Android API, and we need to download the class from the web and add it to the project manually. Disklrucache Source in Google Source address:

Android.googlesource.com/platform/libcore/+/jb-mr2-release/luni/src/main/java/libcore/io/disklrucache.java

Disklrucache is not new to the instance, if we are going to create an instance of Disklrucache, we need to call its open () method:

 Public Static int int Long maxSize)  

The first parameter of the open () method refers to the cached address of the data, the second parameter refers to the version number of the current application, and the third parameter refers to how many cache files the same key can correspond to, basically 1, and the fourth parameter refers to the maximum cache value. The cache is usually stored under the/sdcard/android/data/<application package>/cache path, but it needs to be considered if there is no SD card, or the SD is just being removed, so write a method to Get Cache Address:

 public   File Getdiskcachedir (Context      Context, String uniqueName) {string CachePath;  if   (Environment.MEDIA_MOUNTED.equals ( Environment.getexternalstoragestate ())  | | ! environment.isexternalstorageremovable ())      {CachePath  = Context.getexternalcachedir (). GetPath ();  else   {CachePath  = Context.getcachedir (). GetPath ();  return  new  file (CachePath + file  . separator + UniqueName); }  

When the SD card is present or the SD card is not removable, the Getexternalcachedir () method is called to get the cache path, otherwise the Getcachedir () method is called to get the cache path. The former obtains the/sdcard/android/data/<application Package>/cache this path, the latter obtains is the/data/data/<application package >/cache this path. The acquired path is then spliced with a uniquename, which is returned as the final cache path. UniqueName is a unique value that is set to differentiate between different types of data, such as Bitmap, object, and other folders that are seen under the NetEase News cache path.

It is important to note that whenever the version number changes, all the data stored in the cache path is erased because Disklrucache believes that when the application has a version update, all the data should be retrieved from the Web. The maximum cache size is generally set to 10M.

Get version number:

 Public int getappversion (Context context) {      try  {          = Context.getpackagemanager (). Getpackageinfo (Context.getpackagename (), 0);           return Info.versioncode;       Catch (namenotfoundexception e) {          e.printstacktrace ();      }       return 1;  }  

The standard Open () method:

NULL ;   Try {      = Getdiskcachedir (Context, "bitmap");       if (! cachedir.exists ()) {          cachedir.mkdirs ();      }       = Disklrucache.open (Cachedir, getappversion (context), 1, ten * 1024x768);   Catch (IOException e) {      e.printstacktrace ();  }  

First call the Getdiskcachedir () method to get the path to the cache address, and then determine if the path exists and create it if it does not exist. Then call Disklrucache's Open () method to create the instance, with the Disklrucache instance, we can manipulate the cached data, mainly including writing, access, removal, etc.

3. Operations on cached data:

3.1 Write Cache:

For example, now there is a picture, the address is http://img.my.csdn.net/uploads/201309/01/1378037235_7476.jpg, to download this picture:

Private BooleanDownloadurltostream (String urlstring, OutputStream outputstream) {httpurlconnection URLConnection=NULL; Bufferedoutputstream out=NULL; Bufferedinputstream in=NULL; Try {          FinalURL url =NewURL (urlstring); URLConnection=(HttpURLConnection) url.openconnection (); Inch=NewBufferedinputstream (Urlconnection.getinputstream (), 8 * 1024); out=NewBufferedoutputstream (OutputStream, 8 * 1024); intb;  while((b = In.read ())! =-1) {out.write (b); }          return true; } Catch(FinalIOException E)      {E.printstacktrace (); } finally {          if(URLConnection! =NULL) {urlconnection.disconnect (); }          Try {              if(Out! =NULL) {out.close (); }              if(In! =NULL) {in.close (); }          } Catch(FinalIOException E)          {E.printstacktrace (); }      }      return false; }  

With this method, you can use Disklrucache to write, and the write operation is done using the Disklrucache.editor class. This class also cannot be new out of the instance, you need to call Disklrucache's edit () method to get the instance:

 Public throws IOException  

The edit () method receives a parameter key, which will be the file name of the cache file and must correspond to the URL of the image one by one. So how to make the key and the image URL can be one by one corresponding? The simplest way is to encode the URL of the image MD5, the encoded string must be unique, and will only contain characters such as 0-f, fully conform to the naming rules of the file.

 Publicstring Hashkeyfordisk (String key) {string CacheKey; Try {          FinalMessageDigest mdigest = messagedigest.getinstance ("MD5");          Mdigest.update (Key.getbytes ()); CacheKey=bytestohexstring (Mdigest.digest ()); } Catch(nosuchalgorithmexception e) {CacheKey=string.valueof (Key.hashcode ()); }      returnCacheKey; }    PrivateString bytestohexstring (byte[] bytes) {StringBuilder SB=NewStringBuilder ();  for(inti = 0; i < bytes.length; i++) {String hex= Integer.tohexstring (0xFF &Bytes[i]); if(hex.length () = = 1) {sb.append (' 0 ');      } sb.append (hex); }      returnsb.tostring (); }  

Now just call the Hashkeyfordisk () method and pass the URL of the image into this method, you can get the corresponding key.

Therefore, it is now possible to write this to get an example of a disklrucache.editor:

String imageUrl = "Http://img.my.csdn.net/uploads/201309/01/1378037235_7476.jpg";   = Hashkeyfordisk (IMAGEURL);   = Mdisklrucache.edit (key);  

With an instance of Disklrucache.editor, we can call its Newoutputstream () method to create an output stream and then pass it into Downloadurltostream () to download and write to the cache. Note that the Newoutputstream () method receives an index parameter, because the previous specified at the time of setting the Valuecount is 1, so here Index 0 can be. After the write operation is done, we also need to call the commit () method to commit for the write to take effect, and the Abort () method to abort the write.

code for a full write operation:

NewThread (NewRunnable () {@Override Public voidrun () {Try{String ImageUrl= "Http://img.my.csdn.net/uploads/201309/01/1378037235_7476.jpg"; String Key=Hashkeyfordisk (IMAGEURL); Disklrucache.editor Editor=Mdisklrucache.edit (key); if(Editor! =NULL) {OutputStream OutputStream= Editor.newoutputstream (0); if(Downloadurltostream (IMAGEURL, OutputStream)) {editor.commit (); } Else{editor.abort ();          }} mdisklrucache.flush (); } Catch(IOException e) {e.printstacktrace ();  }}). Start (); 

The cache should have been successfully written after the above steps.

3.2 Read cache:

The Read method is simpler than writing, mainly by means of the get () method of the Disklrucache, the interface is as follows:

 Public synchronized throws IOException  

The Get () method requires that a key be passed in to fetch the corresponding cached data, and this key is undoubtedly the MD5 encoded value of the image URL, so the code that reads the cached data can write:

String imageUrl = "Http://img.my.csdn.net/uploads/201309/01/1378037235_7476.jpg";   = Hashkeyfordisk (IMAGEURL);   = Mdisklrucache.get (key);  

Oddly enough, this gets a Disklrucache.snapshot object, in fact the input stream of the cached file can be obtained only by invoking its getInputStream () method. Similarly, the getInputStream () method also needs to pass an index parameter, where 0 is allowed. With the input stream of the file, it is easy to display the cached image to the interface. So, a complete read cache, and the code that loads the picture into the interface is as follows:

(The Bitmapfactory Decodestream () method is used to parse the file stream into a bitmap object and then set it to ImageView)

Try {      = "Http://img.my.csdn.net/uploads/201309/01/1378037235_7476.jpg";       = Hashkeyfordisk (IMAGEURL);       = Mdisklrucache.get (key);       if NULL ) {          = snapshot.getinputstream (0);           = Bitmapfactory.decodestream (is);          Mimage.setimagebitmap (bitmap);      }   Catch (IOException e) {      e.printstacktrace ();  }  

This is a picture loaded from the local cache instead of being loaded from the network, so even if your phone is not networked, this image can still be displayed.

3.3: Remove the cache:

The removal of the cache is primarily implemented with the Disklrucache remove () method, with the following interfaces:

 Public synchronized Boolean throws IOException  

The Remove () method requires a key to be passed in and then deletes the cached image for that key:

Try {      = "Http://img.my.csdn.net/uploads/201309/01/1378037235_7476.jpg";         = Hashkeyfordisk (IMAGEURL);        Mdisklrucache.remove (key);   Catch (IOException e) {      e.printstacktrace ();  }  

This method should not be used to call it frequently. Because there is absolutely no need to worry about caching too much data and taking up too many space on the SD card, Disklrucache automatically deletes the extra cache based on the maximum cache value we set when we call the open () method. You should call the Remove () method to remove the cache only if you are sure that the cache content for a key has expired and you need to get the latest data from the network.

Hard disk caching Technology Disklrucache Technology < notes >

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.