Imageloader such pictures load a big push on the web, like the more famous Nostra13-image-loader pictures loaded, xutil pictures loaded, and Facebook Fresco. A lot, but in the attitude of learning, recently in the project when the need to load the picture to write a lightweight (local) image cache loading function, to share with you.
It involves the LruCache, the Executorservice, the bitmapfactory principle of the large map, View.settag ().
Well, no more, first step:
First look at how my encapsulated class is used:
Local photo absolute path
String imageUrl = (string) t;
Get ImageView
ImageView grid_item = Holder.getview (R.id.grid_item);
Set tag, tagged with, anyway the picture shows dislocation
Grid_item.settag (IMAGEURL);
/** *
Display Picture
* *
@param
Context * : Contextual
* @param imageview
* : ImageView Control
* Param sourcepath
* : Picture address
* @param r_id
* : Default picture Id, R.drowable.id;
* @param callback
* : Picture shows callback
/
new Imageloader (). Displaybmp (Mcontext,grid_item, IMAGEURL, R.drawable.img_bg,this);
is not very simple.
The next concrete analysis Imageloader this class:
Know that the phone's memory is limited, it is not possible to add all of the pictures to memory, so Android offers a LruCache method, using algorithms that are least recently used, and where images are constantly being added to the cache, and the least used images are constantly removing the cache, avoiding the problem of insufficient memory.
The initialization code for the LruCache is as follows:
Public Imageloader () {
//Take 8/1 of the application memory as a picture cache with
int cacheSize = MAXMEMORY/8;
Get LruCache
Mlrucache = new lrucache<string, bitmap> (cacheSize) {
@Override
protected int sizeOf ( String key, Bitmap Bitmap) {return
bitmap.getbytecount ();}}
;
}
/**
* Store picture to LRUCache */public
void Putbitmaptolrucache (String key, Bitmap Bitmap) {
if ( Getbitmapfromlrucache (key) = = NULL && mlrucache!= null) {
mlrucache.put (key, bitmap)
;
}
/**
* Get picture from LRUCache cache/public
Bitmap Getbitmapfromlrucache (String key) {return
mlrucache.get ( key);
}
LruCache, like HashMap, uses put and get to cache things.
Then look at the concrete loading of the picture and post the code first:
/** * Display Picture * * @param contexts *: Context * @param ImageView *: ImageView control * @param sou
Rcepath *: Picture address * @param r_id *: Default picture Id, R.drowable.id; * @param callback *: Picture shows callback/public void Displaybmp (final context, final ImageView ImageView, Fina
L string sourcepath, final int r_id, final Imagecallback callback) {final String path; if (!
Textutils.isempty (SourcePath)) {path = SourcePath;
else {return;
///First try to get the picture from the cache, path as the key Bitmap BMP = Mlrucache.get (path); if (BMP!= null) {if (callback!= null) {//Callback picture Display Callback.imageload (ImageView, BMP, SourcePath
);
}//Imageview.setimagebitmap (BMP);
Return
//If BMP = NULL, show default picture to ImageView Imageview.setimageresource (r_id);
Start thread pool Threadpoolutils.getexecutorservice (). Execute (new Runnable () {Bitmap Bitmap = null;@Override public void Run () {//TODO auto-generated Method Stub try {///Load picture address corresponding indent
Sketch bitmap = Revitionimagesize (ImageView, SourcePath);
catch (Exception e) {} if (bitmap = = null) {try {//If the thumbnail does not load a picture that successfully displays the default settings
Bitmap = Bitmapfactory.decoderesource (Context.getresources (), r_id); catch (Exception e) {}} if (path!= null && bitmap!= null) {//Put thumbnails in
Cache, path as key Putbitmaptolrucache (path, bitmap); } if (callback!= null) {Handler.post (new Runnable () {@Override public void R
Un () {//Callback picture shows Callback.imageload (ImageView, Bitmap, SourcePath);
}
});
}
}
});
}
Code is not malicious, mainly is to load the picture from the cache, when loading the picture is empty, and then from the phone's picture address load picture
bitmap = revitionImageSize(imageView, sourcePath);
Load cache picture is not much to say, see also understand, mlrucache.get (key); it's that simple.
The concrete Analysis Revitionimagesize () This method:
Public Bitmap revitionimagesize (ImageView imageview, String path) throws IOException {//Get layout imageview width height
int img_width = Imageview.getwidth ();
int img_height = Imageview.getheight ();
Bufferedinputstream in = new Bufferedinputstream (new FileInputStream (New File (path));
Bitmapfactory.options Options = new Bitmapfactory.options ();
Options.injustdecodebounds = true;
Bitmapfactory.decodestream (in, null, options);
In.close ();
int height = options.outheight;
int width = options.outwidth;
Bitmap Bitmap = null;
int insamplesize = 1;
The ratio of final int heightratio = Math.Round ((float) height/(float) img_height) is calculated with the actual width and height of the target.
Final int widthRatio = Math.Round ((float) width/(float) img_width);
Choose width and high school minimum ratio as the value of insamplesize, so that the final picture width and height//must be greater than or equal to the width and height of the target. Insamplesize = HeightRatio < WidthRatio?
Heightratio:widthratio;
Call the method defined above to compute the insamplesize value options.insamplesize = insamplesize; OptIons.injustdecodebounds = false;
in = new Bufferedinputstream (new FileInputStream (New File (path));
Bitmap = Bitmapfactory.decodestream (in, null, options);
In.close ();
return bitmap;
}
Code I also wrote a note, generally in the loading of pictures have a certain compression processing to avoid oom, so the above processing method is quite common, to display pictures according to ImageView control size for a certain compression.
If the image compression processing is not very understanding of friends so I would like to explain briefly:
First load the picture:
BufferedInputStream in = new BufferedInputStream(new FileInputStream(new File(path)));
And then:
options.inJustDecodeBounds = true;
and then:
int height = options.outheight;
int width = options.outwidth;
At this time notice the program does not put the picture really loaded in, Options.injustdecodebounds = true;
This sentence at work, but the picture width and height of the information we have got, we can deal with compressed pictures!
After compressing the picture again:
options.inJustDecodeBounds = false;
To get the compressed picture back:
bitmap = BitmapFactory.decodeStream(in, null, options);
Explanation completed.
Students who look at the code will find that there is a callback parameter in the Displaybmp () method:
The callback interface is as follows:
/**
* Display Picture callback
* *
@author Administrator
*/public
interface Imagecallback {public
void Imageload (ImageView ImageView, Bitmap Bitmap, Object ... params);
A specific implementation is a callback where the picture is displayed:
/**
* Image Cache callback
/@Override public
void Imageload (ImageView imageview, Bitmap Bitmap, Object ... params) {
if (ImageView!= null && bitmap!= null) {
string url = (String) params[0];
To determine if the URL here corresponds to Imageview.gettag ()
//If the sentence is removed then there will be a recurring picture showing the dislocation problem!!!!
if (URL!= null && url.equals ((String) Imageview.gettag ()) {(
(ImageView) imageview). Setimagebitmap (bitmap);}}
Code comment Place also wrote, not understand the classmate can DMS exchange, and attached to my GitHub GitHub connection on the source code, you can download the running convenient good understanding:
For your convenience use, add the following dependencies to your project:
dependencies {
compile ' com.zts:imageloader:1.1.1 '
}