Android batch images loaded in classic series-use LRUCache, Asynctask cache and load images asynchronously

Source: Internet
Author: User
Tags file url

I. Descriptive narrative of the problem

Use LRUCache, asynctask to achieve bulk image loading and meet the following technical requirements

1, read the picture from the cache, if not in the cache, open the asynchronous thread (asynctask) load the picture, and put into the cache

2. Remove invalid asynchronous threads in time; Ensure that images are loaded asynchronously without ordering

3. Simply cache the visible part of the current screen and load the image asynchronously

4. Optimize performance to eliminate oom

Second, Case introduction

Case implementation Photo Wall effect

Third, the main technology

  LruCache

  Memory caching Technology . A component that is specifically used for image caching in Android, the main use step

(1) Set the memory size of the cached image, as set to 1/8 of the memory of the phone (when the cached picture reaches a predetermined value.) Then the most recently used pictures will be recycled) code such as the following:

Gets the maximum available memory of the application int maxmemory = (int) runtime.getruntime (). MaxMemory (); int cacheSize = maxmemory/8;//Set the picture cache size to the maximum available memory for the program 1/8mmemorycache = new lrucache<string, bitmap> (cacheSize) {            @Override            protected int sizeOf (String key, Bitmap Bitmap) {                return bitmap.getbytecount ();            }        };

(2) Put the picture in the cache (key-value pairs in the LRUCache are usually URLs and corresponding images)

Mmemorycache.put (key, bitmap);

(3) Take a picture from the cache

Mmemorycache.get (key);

  Asynctask

Take a time-consuming action, for example, loading a picture requires not clogging the UI thread. You must use an asynchronous task. Asynctask is a simple and lightweight component that does not require the use of Thread+handler to implement asynchronous tasks. Implement the Asynctask process such as the following:

  (1) Extension sub-asynctask, such as

Class Bitmapworkertask extends Asynctask<string, Void, bitmap>

  (2) Several methods of rewriting Asynctask

OnPreExecute (), the method is called by the UI thread before the actual background operation is run.

Be able to do some preparatory work in the method, such as displaying a progress bar on the interface.

Doinbackground (Params ...) will run after the OnPreExecute method is run. This method runs in a background thread and is primarily responsible for running those very time-consuming background computations. such as loading pictures

OnPostExecute (Result) after the Doinbackground has finished running. This will be called by the UI thread, and the results of the background will be passed to the UI thread through this method

  (3) Execute (Params ...) in the UI thread by calling Asynctask;

Starts running an asynchronous task and passes data to the background task. Run Order OnPreExecute ()--Doinbackground (Params ...) --OnPostExecute (Result)

  Experience: loading a large number of images. Requires that each picture be executed in a background task, so you need to use the collection to record all the tasks that are downloading or waiting to be downloaded

set<bitmapworkertask> taskcollection=new hashset< bitmapworkertask > ();

When there are no pictures in the cache. Joins the task and initiates asynchronous processing. Fragment code such as:

if (bitmap = = null) {//Assume that the cache does not have bitmapworkertask task = new Bitmapworkertask (); Taskcollection.add (Task);     Task.execute (IMAGEURL);//Run an asynchronous task and pass in the loaded picture URL address}

Be careful to remove completed tasks in a timely manner, such as the following code

protected void OnPostExecute (Bitmap Bitmap) {.... taskcollection.remove (this);}

and cancels the running task when the adapter control slide is stopped. Fragment codes such as the following:

public void onscrollstatechanged (Abslistview view, int scrollstate) {//Only when the GridView is compact to download pictures, the GridView swipe cancels all the tasks that are being downloaded if ( Scrollstate = = Scroll_state_idle) {loadbitmaps (Mfirstvisibleitem, mvisibleitemcount);} else {cancelalltasks ();// Cancels all tasks that are downloading or waiting to be downloaded. }}public void Cancelalltasks () {if (taskcollection! = null) {for (Bitmapworkertask task:taskcollection) {task.cancel (FAL SE);}}}
Three, the complete code

  1,  mainactivity

public class Mainactivity extends Activity {private GridView mphotowall;    Private Photowalladapter adapter;private arraylist<file> list;        protected void OnCreate (Bundle savedinstancestate) {super.oncreate (savedinstancestate);        Setcontentview (R.layout.activity_main);        List = new arraylist<file> ();        Getallfiles (New File ("/sdcard"));        Mphotowall = (GridView) Findviewbyid (R.id.photo_wall);        adapter = new Photowalladapter (this, 0, list, mphotowall);    Mphotowall.setadapter (adapter);        }/** * Gets the specified folder slice file */private void Getallfiles (file root) {file files[] = Root.listfiles (); if (Files! = null) for (File f:files) {if (F.isdirectory ()) {Getallfiles (                f); } else {if (F.getname (). IndexOf (". png") > 0 | | f.getname (). IndexOf (". jpg ") > 0 | | F.getname (). IndexOf (". jpeg") > 0) this.list.add (f);        }}} protected void OnDestroy () {Super.ondestroy (); Adapter.cancelalltasks ();//End all download tasks when exiting the program}}

2, Photowalladapter Adapter

public class Photowalladapter extends arrayadapter<file> implements Onscrolllistener {//record all tasks that are downloading or waiting to be downloaded 。

Private set<bitmapworkertask> taskcollection; The core class of image caching technology. Used to cache all downloaded images and remove the least recently used images when the program memory reaches the set value. Private lrucache<string, bitmap> Mmemorycache; Instance of the GridView private GridView Mphotowall; The first visible image of the subscript private int mfirstvisibleitem; How many pictures can be seen on a screen private int mvisibleitemcount; Record whether the program was just opened to resolve the entry program without scrolling the screen. The problem of not downloading pictures. Private Boolean isfirstenter = true; arraylist<file> list = null; Public Photowalladapter (context context, int Textviewresourceid, arraylist<file> objects, GridView Photow All) {Super (context, Textviewresourceid, objects); Mphotowall = Photowall; List = objects; Taskcollection = new hashset<bitmapworkertask> (); Gets the application maximum available memory int maxmemory = (int) runtime.getruntime (). MaxMemory (); int cacheSize = MAXMEMORY/8; Set the picture cache size to the maximum available memory for the program 1/8 Mmemorycache = new lrucache<string, bitmap> (cacheSize) {@Override Protected int sizeOf (String key, Bitmap Bitmap) {return bitmap.getbytecount (); } }; Mphotowall.setonscrolllistener (this); Public View GetView (int position, View Convertview, ViewGroup parent) {final File url = getItem (position); View view; if (Convertview = = null) {view = Layoutinflater.from (GetContext ()). Inflate (r.layout.photo_ layout, NULL); } else {view = Convertview; } final ImageView photo = (ImageView) View.findviewbyid (R.id.photo); Set a tag for ImageView to ensure that the image is loaded asynchronously without disorderly ordering Photo.settag (Url.getabsolutepath ()); Setimageview (Url.getabsolutepath (), photo); return view; }/** * Set picture for ImageView. First, remove the cache of the image from the LRUCache and set it to ImageView. Assume that there is no cache for the picture in LRUCache. * Set a default picture for ImageView. * @param imageUrl * The URL address of the picture. Used as a key for LRUCache. * @param ImageView * controls for displaying pictures. */private void Setimageview (String imageUrl, ImageView ImageView) {Bitmap Bitmap = Getbitmapfrommemorycache (IMAGEURL); if (bitmap! = null) {Imageview.setimagebitmap (bitmap); } else {bitmap=getloacalbitmap (IMAGEURL); Imageview.setimageresource (R.drawable.empty_photo); }}/** * Store a picture in the LRUCache.

* @param key * LRUCache, where the URL of the image is passed in. * @param bitmap * LRUCache key, where bitmap objects downloaded from the network are passed in. */@SuppressLint ("Newapi") public void Addbitmaptomemorycache (String key, Bitmap Bitmap) {if (Getbitmapfrommemor Ycache (key) = = null) {Mmemorycache.put (key, bitmap); }}/** * Gets a picture from LRUCache and returns null if it does not exist. * @param key * LRUCache, where the URL of the image is passed in. * @return the Bitmap object with the corresponding incoming key, or null. */@SuppressLint ("Newapi") public Bitmap Getbitmapfrommemorycache (String key) {return mmemorycache.get (key); } @Override public void onscrollstatechanged (Abslistview view, int scrollstate) {//Only when the GridView is compact to download pictures, The GridView slider cancels all the tasks that are being downloaded if (scrollstate = = Scroll_state_idle) {loadbitmaps (Mfirstvisibleitem, Mvisibleit Emcount); } else {cancelalltasks (); }} @Override public void onscroll (Abslistview view, int firstvisibleitem, int visibleitemcount, int totalitemcount) {mfirstvisibleitem = Firstvisibleitem; Mvisibleitemcount = VisibleItemCount; The downloaded task should be called by onscrollstatechanged. However, the first time you enter the program, Onscrollstatechanged will not be called,//So here for the first entry program to open the download task. if (isfirstenter && visibleitemcount > 0) {loadbitmaps (Firstvisibleitem, VisibleItemCount); Isfirstenter = false; }}/** * Loads the bitmap object. This method checks the ImageView bitmap object that is visible on all screens in LRUCache, and assumes that no matter what ImageView bitmap object is not in the cache, the asynchronous thread is opened to download the image. * * @param firstvisibleitem * The first visible imageview subscript * @param visibleitemcount * screen for a total of Number of elements to see */private void loadbitmaps (int firstvisibleitem, int visibleitemcount) {try {for (int i = Firstvisibleitem; I < Firstvisibleitem + VisibleItemCount; i++) {String imageUrl = List.get (i). GetAbsolutePath (); Bitmap Bitmap = Getbitmapfrommemorycache (imageUrl); if (bitmap = = null) {//Assume that the cache does not have bitmapworkertask task = new Bitmapworkertask (); Taskcollection.add (Task); Task.execute (IMAGEURL);//Run the asynchronous task and pass in the loaded Picture URL address (here is the picture on the SD card)} else {ImageView ImageView = (ImageView) Mphotowall. Findviewwithtag (IMAGEURL); if (ImageView! = null && bitmap! = null) {Imageview.setimagebitmap (bitmap); }}}} catch (Exception e) {e.printstacktrace (); }}/** * Cancels all tasks that are downloading or waiting to be downloaded. */public void Cancelalltasks () {if (taskcollection! = null) {for (Bitmapworkertask Task:taskcoll ection) {Task.cancel (false); }}}/** * The task of downloading pictures asynchronously. */class Bitmapworkertask extends Asynctask<string, Void, bitmap> {/** * image URL Address */Private String IMAGEURL; @Override protected Bitmap doinbackground (String ... params) {imageUrl = params[0]; Download the image in the background Bitmap Bitmap = Getloacalbitmap (Params[0]); if (bitmap! = null) {//The picture is downloaded and cached to Lrccache Addbitmaptomemorycache (Params[0], bitmap); } return bitmap; } @Override protected void OnPostExecute (Bitmap Bitmap) {super.onpostexecute (BITMAP); Find the appropriate ImageView control according to tag and display the downloaded picture. ImageView ImageView = (ImageView) mphotowall. Findviewwithtag (IMAGEURL); if (ImageView! = null && bitmap! = null) {Imageview.setimagebitmap (bitmap); } taskcollection.remove (this); }} private Bitmap getloacalbitmap (String url) {try {FileInputStream FIS = new FileInputStream ( URL); Return bitmapfactory.Decodestream (FIS); /Turn the flow into bitmap picture} catch (FileNotFoundException e) {e.printstacktrace (); return null; } }}

Small partners who want to know a lot of other content can click to view the source code and perform the test in person.

Inquiries or technical exchanges, please add the official QQ Group: (452379712)

Jerry Education
Source:http://blog.csdn.net/jerehedu/
This article belongs to Yantai Jerry Education Technology Co., Ltd. and CSDN co-owned, welcome reprint, but without the author's permission must retain this paragraph statement. And in the article page obvious location to the original link, otherwise reserves the right to pursue legal responsibility.

Android batch images loaded in classic series-use LRUCache, Asynctask cache and load images asynchronously

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.