Android ListView asynchronous image loading and Image Memory Cache

Source: Internet
Author: User

I am so lazy in the middle that I haven't written a blog for a long time. Today I have studied Android ListView asynchronous image loading and image memory caching for several days. Hey.


Android applications often need to handle image loading issues. Because images are generally stored on the server and need to be loaded online, this is a time-consuming process. Therefore, Android can load images by enabling an asynchronous thread. In order to increase user experience and save traffic for users, the loaded images are usually cached first. The next time you load images, you do not need to connect them to the server for loading. Image cache is generally divided into Level 1 cache (memory cache) and level 2 cache (disk cache ). Here we only talk about Level 1 cache.

The memory cache first stores the Loaded Images in the mobile phone memory, and then extracts them from the memory when loading the next time.

AdvantagesIs fast,DisadvantagesIt cannot be saved for a long time. After the user exits the application, the memory cache will be recycled. In addition, a java. lang. OutOfMemory exception will be thrown when too many files are loaded.

The disk cache stores the loaded images on the built-in storage card or SD card of the mobile phone. It will be retrieved from the next load.

AdvantagesIt can be saved for a long time,DisadvantagesThe speed is slow. In order not to affect the user experience, the cached images in the disk are usually retrieved through asynchronous threads. Another reason is that the cached files will not be deleted after the user detaches the application, disk Space is wasted and needs to be deleted manually.

Many users use SoftRReference for image caching, but Android does not recommend it.

Android official reasons are: Note: In
The past, a popular memory cache implementation wasSoftReferenceOrWeakReferenceBitmap
Cache, however this is not recommended. starting from Android 2.3 (API Level 9) the garbage collector is more aggressive with collecting soft/weak references which makes them fairly ineffective. in addition, prior to Android 3.0 (API Level 11), the backing
Data of a bitmap was stored in native memory which is not released in a predictable manner, potentially causing an application to briefly exceed its memory limits and crash.


Therefore, we generally use the LruCache class. This class can be understood as follows: it is a memory cache object, and your images are cached in this class. (IN Java, everything is an object .)
Only in 12, but fortunately Android officially added it to the v4 package, so this class can be used in Versions later than 1.6. This class is also relatively simple to use (it is also detailed in the official documentation ).

The following describes how to use it:

First, define an Adapter for ListView (inherited from BaseAdapter), and then declare a member variable LruCache in this class, instead of declaring it in the getView () method. Because only one LruCache can be maintained for all Item items of a ListView. LruCache has a constructor LruCache (int maxSize). The parameter is the maximum capacity (in bytes) of the cache space ). Declare that an LruCache object generally needs to rewrite its sizeOf (K key, V value), and use this method to change the calculation size of each cache entry. In the Android source code, 1 is returned by default, indicating that the number is calculated by default. (In fact, I don't quite understand it here, and some people who know it can't help but give me some advice .)

 

Android sizeof () source code:

/**     * Returns the size of the entry for {@code key} and {@code value} in     * user-defined units.  The default implementation returns 1 so that size     * is the number of entries and max size is the maximum number of entries.     *     * <p>An entry's size must not change while it is in the cache.     */    protected int sizeOf(K key, V value) {        return 1;    }

But I wrote it in reference to the official document.

Private final int maxMemory = (int) Runtime. getRuntime (). maxMemory (); // obtain the maximum memory allocated by the current application. private final int cacheSize = maxMemory/5; // only one of five points is used for image cache private LruCache <String, bitmap> mLruCache = new LruCache <String, Bitmap> (cacheSize) {@ Overrideprotected int sizeOf (String key, Bitmap bitmap) {// rewrite sizeof () method // replaced by getByteCount () in API 12 return bitmap. getRowBytes () * bitmap. getHeight ()/1024; // here, the number of KB is calculated }};

Then write a class AsyncImageLoader that asynchronously loads images. This class uses AsyncTask to asynchronously load images.

Package com. folyd. tuan. util; import java. io. IOException; import android. graphics. bitmap; import android. OS. asyncTask; import android. support. v4.util. lruCache; import android. widget. imageView; import com. folyd. tuan. util. simpleImageLoader;/*** asynchronous image loading class with image memory cache ** @ author Folyd **/public class AsyncImageLoader extends AsyncTask <String, Void, Bitmap> {private ImageView image; private LruCache <String, Bitmap> lruCache;/*** constructor, you need to pass the ImageView control and LruCache object in * @ param image to load the image to this {@ code} ImageView * @ param lruCache cache image object */public AsyncImageLoader (ImageView image, lruCache <String, Bitmap> lruCache) {super (); this. image = image; this. lruCache = lruCache;} @ Overrideprotected Bitmap doInBackground (String... params) {Bitmap bitmap = null; try {bitmap = SimpleImageLoader. getBitmap (params [0]);} catch (IOException e) {e. printStackTrace ();} addBitmapToMemoryCache (params [0], bitmap); return bitmap;} @ Overrideprotected void onPostExecute (Bitmap bitmap) {image. setImageBitmap (bitmap);} // call the put Method of LruCache to add the image to the memory cache. You need to give the image a key so that the private void addBitmapToMemoryCache (String key, bitmap bitmap) {if (getBitmapFromMemoryCache (key) = null) {lruCache. put (key, bitmap) ;}// call the Lrucache get method to remove the image public Bitmap getBitmapFromMemoryCache (String key) {return lruCache from the memory cache. get (key );}}

SimpleImageLoader
The getBitmap method of is a simple method for obtaining images from the Internet.

Package com. folyd. tuan. util; import java. io. IOException; import java. io. inputStream; import java.net. httpURLConnection; import java.net. URL; import android. graphics. bitmap; import android. graphics. bitmapFactory;/*** a simple image loading tool class, which does not involve image caching. * @ Author Folyd **/public class SimpleImageLoader {public static Bitmap getBitmap (String urlStr) throws IOException {Bitmap bitmap; URL url = new URL (urlStr); HttpURLConnection conn = (HttpURLConnection) url. openConnection (); conn. setRequestMethod ("GET"); conn. setReadTimeout (5*1000); conn. setDoInput (true); conn. connect (); InputStream is = conn. getInputStream (); bitmap = BitmapFactory. decodeStream (is); is. close (); return bitmap ;}}

Then encapsulate an image loading method in the Custom Adapter. Some knowledge about AsyncTask is involved here. You can refer to the official document for more information.

/***** @ Param urlStr: the url of the image to be loaded, which is passed in as a String, you can use this url as the key * @ param image ImageView control */private void loadBitmap (String urlStr, ImageView image) {AsyncImageLoader asyncLoader = new AsyncImageLoader (image, mLruCache) of the cached image ); // What is an asynchronous image loading object Bitmap bitmap = asyncLoader. getBitmapFromMemoryCache (urlStr); // obtain the image if (bitmap! = Null) {image. setImageBitmap (bitmap); // if this image exists in the cache, it is directly set to ImageView} else {image. setImageResource (R. drawable. thum); // if this parameter is not specified, the system first sets the image asyncloader.exe cute (urlStr); // then executes the asynchronous task AsycnTask to load the image online }}

Call the above loadBitmap () method in the getView () method of the custom Adapter.


In this way, the asynchronous loading of images and the memory cache will be practiced.

Take a look:

 


Of course, ListView without disk cache
Absolutely not. ListView also has many optimization techniques that need to be learned continuously. For example, images can be loaded lazily.

Related Article

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.