Go--memory cache technology of image cache LRUCache, soft reference

Source: Internet
Author: User

Whenever we encounter some big picture, we will report an OOM exception if we do not handle the image.
This problem once made me feel very vexed, and then finally got the solution,
So let me share it with you now.
This blog post to tell the picture caching mechanism, I have access to two minutes, one is a soft reference, the other is the memory cache technology.
First look at the use of the two ways, and then to compare.
In addition to loading the image to use the cache processing, there is a more important step to do is to compress the picture first.

1. Compress Pictures
As to what state to compress to see their own situation at the time, compress the picture when you need to achieve a small value, and can not let it blur
, and you can't stretch the picture.
/**
* Load memory card picture
*/
Bitmapfactory.options Options = new Bitmapfactory.options ();
Options.injustdecodebounds = true; Set this property be sure to remember to set the value to False
Bitmap Bitmap = null;
Bitmap = Bitmapfactory.decodefile (URL, options);
int be = (int) (Options.outheight > Options.outwidth? options.outheight/150
: options.outwidth/200));
if (be <= 0)//Determine if 200 exceeds the original image height
be = 1; If it is exceeded, no scaling is done
Options.insamplesize = be;
Options.inpreferredconfig = Bitmap.Config.ARGB_4444;
Options.inpurgeable = true;
Options.ininputshareable = true;
Options.injustdecodebounds = false;
try {
Bitmap = Bitmapfactory.decodefile (URL, options);
} catch (OutOfMemoryError e) {
System.GC ();
LOG.E (TAG, "OutOfMemoryError");
}

2. Soft reference:
As long as there is enough memory, the object is persisted until the memory is found to be tight and strong ref is not collected.
We can define this: the map inside the key is used to put the image address, can be the image address on the network, can also be sdcard on the image address,
The value inside the map is the bitmap that holds the soft reference, of course, if you want to put drawable, that is also possible.

Private map<string, softreference<bitmap>> ImageMap
= new hashmap<string, softreference<bitmap>> ();

Next, let me explain how to load the image:
Step: (1) first through the URL to see if there are pictures in the cache, if any, then go directly to the cache to get.
If not, the thread is re-downloaded online.
(2) After downloading, put the picture in the cache, convenient next time can be obtained directly from the cache.

Public Bitmap LoadBitmap (final String imageurl,final imagecallback imagecallback) {
softreference<bitmap> reference = Imagemap.get (IMAGEURL);
if (reference! = NULL) {
if (reference.get () = null) {
return Reference.get ();
}
}
Final Handler Handler = new Handler () {
public void Handlemessage (Final android.os.Message msg) {
Adding to the cache
Bitmap Bitmap = (Bitmap) msg.obj;
Imagemap.put (IMAGEURL, New softreference<bitmap> (Bitmap));
if (imagecallback! = null) {
Imagecallback.getbitmap (bitmap);
}
}
};
New Thread () {
public void Run () {
Message message = Handler.obtainmessage ();
Message.obj = Downloadbitmap (IMAGEURL);
Handler.sendmessage (message);
}
}.start ();
return null;
}

Download pictures from the internet
Private Bitmap Downloadbitmap (String imageUrl) {
Bitmap Bitmap = null;
try {
Bitmap = Bitmapfactory.decodestream (new URL (IMAGEURL). OpenStream ());
return bitmap;
} catch (Exception e) {
E.printstacktrace ();
return null;
}
}

public interface imagecallback{
void Getbitmap (Bitmap Bitmap);
}



3. Memory Cache Technology
Another way to cache images is in memory cache technology. In Android, there is a class called LRUCache that is specifically designed to handle image caching.
It has a feature that when the cached image reaches a predetermined value, the least recently used images are recycled.
Steps: (1) to set the memory size of the cached image, I set this to 1/8 of the phone memory,
How to get the phone memory: int maxmemonry = (int) (Runtime.getruntime (). MaxMemory ()/1024);
(2) The key-value pairs inside the LRUCache are URLs and corresponding images.
(3) Rewrite a method called sizeof, which returns the number of pictures.

Private lrucache<string, bitmap> Mmemorycache;
Private Lrucacheutils () {
if (Mmemorycache = = null)
Mmemorycache = new lrucache<string, bitmap> (
MAXMEMONRY/8) {
@Override
protected int sizeOf (String key, Bitmap Bitmap) {
Override this method to measure the size of each picture, returning the number of pictures by default.

return Bitmap.getrowbytes () * bitmap.getheight ()/1024;
}

@Override
protected void Entryremoved (Boolean evicted, String key,
Bitmap OldValue, Bitmap newvalue) {
LOG.V ("tag", "Hard cache are full, push to soft cache");

}
};
}
(4) The following methods are to empty the cache, add pictures to the cache, get pictures from the cache, remove from the cache.
Removing and clearing the cache is something that must be done, because the image cache is improperly handled to report a memory overflow, so be sure to pay attention.

public void ClearCache () {
if (Mmemorycache! = null) {
if (mmemorycache.size () > 0) {
LOG.D ("Cacheutils",
"Mmemorycache.size ()" + mmemorycache.size ());
Mmemorycache.evictall ();
LOG.D ("Cacheutils", "mmemorycache.size ()" + mmemorycache.size ());
}
Mmemorycache = null;
}
}

Public synchronized void Addbitmaptomemorycache (String key, Bitmap Bitmap) {
if (mmemorycache.get (key) = = null) {
if (key! = null && bitmap! = null)
Mmemorycache.put (key, bitmap);
} else
LOG.W (TAG, "The res is aready exits");
}

Public synchronized Bitmap Getbitmapfrommemcache (String key) {
Bitmap BM = mmemorycache.get (key);
if (key! = null) {
return BM;
}
return null;
}

/**
* Remove Cache
*
* @param key
*/
Public synchronized void Removeimagecache (String key) {
if (key! = null) {
if (Mmemorycache! = null) {
Bitmap BM = mmemorycache.remove (key);
if (BM! = NULL)
Bm.recycle ();
}
}
}

4, the comparison between the two
Speaking of which, I think it is necessary to make a comparison.
There are many people on the Internet that use soft references to load pictures, but it is no longer recommended to use this method,
(1) Because starting with Android 2.3 (API Level 9), the garbage collector is more inclined to reclaim objects that hold soft or weak references.
This makes soft references and weak references no longer reliable.
(2) In addition, in Android 3.0 (API level 11), the image data is stored in the local memory,
It is therefore not possible to release it in a predictable way, which poses a potential risk for the application to overflow and crash the memory,
So I use LRUCache here to cache the image, when the size of the storage image is larger than the value set by LRUCache, the system automatically frees the memory,
This class is available in version 3.1, and if you are developing in an earlier version of Android, you will need to import the ANDROID-SUPPORT-V4 jar package.

PostScript:I have always stressed that one thing, is that people should keep on improving, no one is born to code,
And no one can find a good solution from the start, and I've introduced both of these usages,

Go--memory cache technology of image cache LRUCache, soft reference

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.