Three-level caching mechanism for images in Android _android

Source: Internet
Author: User
Tags int size

We can not load the picture every time the user to download from the network, so that not only waste traffic and will affect the user experience, so Android introduced the image of the caching operation mechanism.

Principle:

First, according to the image of the network address on the network to download pictures, the picture first cached in the memory cache, the cache to the strong reference in the LRUCache. If there is not enough space in the strong reference, the earlier stored picture object is expelled to the soft reference (SoftReference) for storage, and then the picture is cached to the file (internal storage external storage); When you read the picture, read the memory cache to determine if there is a picture in the strong reference, if it exists in the strong reference, is read directly, if the strong reference does not exist, if the soft reference exists, the picture in the soft reference is added to the strong reference and the data in the soft reference is deleted, and if the soft reference does not exist, the file store is read and the network is loaded if the file store does not exist.

Downloads: Network--memory--Files

READ: Memory--strong reference--soft reference--file--Network

This is the process, the following with a simple demo to illustrate the image of your level three cache, this demo has only one interface, the interface of the last ImageView used to display pictures, a button to click when loading pictures. The layout is as follows:

<?xml version= "1.0" encoding= "Utf-8"?> <relativelayout xmlns:android=
"http://schemas.android.com/apk" /res/android "
android:layout_width=" match_parent "
android:layout_height=" match_parent "
>
<imageview
android:id= "@+id/iv_img"
android:layout_width= "Wrap_content"
Wrap_content "
android:src=" @mipmap/ic_launcher "
android:layout_centerinparent= true"/>
< Button
android:id= "@+id/btn_download"
android:layout_below= "@+id/iv_img"
android:layout_ Centerhorizontal= "true"
android:layout_width= "wrap_content"
android:layout_height= "Wrap_content"
android:text= "Load picture"/>
</RelativeLayout>

Because you want to download data from the network and store it in a local SD card, do not forget to add Network access permissions to your program, access to network status, and permissions to write content to external storage devices:

<uses-permission android:name= "Android.permission.INTERNET"/>
<uses-permission android:name= " Android.permission.ACCESS_NETWORK_STATE "/>
<uses-permission android:name=" android.permission.WRITE_ External_storage "/>

Next, create a Httputils tool class to access the network with the following code:

Package com.yztc.lx.cashimg;
Import Android.content.Context;
Import Android.net.ConnectivityManager;
Import Android.net.NetworkInfo;
Import Java.io.ByteArrayOutputStream;
Import java.io.IOException;
Import Java.io.InputStream;
Import java.net.HttpURLConnection;
Import Java.net.URL;
/** Network Access Tool class * Created by Lx on 2016/8/19. * * public class Httputils {/** * To determine whether the network connection is unobstructed * @param mcontext * @return * * public static Boolean isnetconn (context Mconte
XT) {Connectivitymanager manager = (Connectivitymanager) mcontext.getsystemservice (Context.connectivity_service);
Networkinfo info = Manager.getactivenetworkinfo ();
if (info!= null) {return info.isconnected ();} else {return false;}} /** * Download data on the network based on path * @param path PATH * @return Returns the byte data form of the download/public static byte[] Getdatefromnet (String path) {byte
Arrayoutputstream BAOs = new Bytearrayoutputstream ();
try {URL url = new URL (path);
HttpURLConnection conn = (httpurlconnection) url.openconnection ();
Conn.setrequestmethod ("get"); Conn.setcOnnecttimeout (5000);
Conn.setdoinput (TRUE);
Conn.connect (); if (Conn.getresponsecode () ==200) {InputStream is = Conn.getinputstream (); byte b[] = new byte[1024]; int Len (len
=is.read (b))!=-1) {baos.write (b, 0, Len);} return Baos.tobytearray ();
} catch (IOException e) {e.printstacktrace ();} return Baos.tobytearray (); }
}

There are also tool classes that manipulate external storage:

Package com.yztc.lx.cashimg;
Import Android.graphics.Bitmap;
Import Android.graphics.BitmapFactory;
Import android.os.Environment;
Import Java.io.ByteArrayOutputStream;
Import Java.io.File;
Import Java.io.FileInputStream;
Import Java.io.FileOutputStream;
Import java.io.IOException;
/** * Created by Lx on 2016/8/20. * * public class Externalstorageutils {/** * will pass over the image byte array stored in the SD card * @param imgname the name of the picture * @param buff byte array * @return return
Whether the back is stored successfully/public static Boolean Storetosdroot (String imgname, byte buff[]) {Boolean b = false;
String basepath = Environment.getexternalstoragedirectory (). GetAbsolutePath ();
File File = new file (BasePath, imgname); 
try {fileoutputstream fos = new FileOutputStream (file); Fos.write (buff); Fos.close (); b = true;} catch (IOException e) {
E.printstacktrace ();
return b; /** * Get picture from local memory according to picture name * @param imgname picture name * @return Returns the BITMAP format of the picture * * public static Bitmap getimgfromsdroot (String img
Name) {Bitmap Bitmap = null; String BasePath = Environment.getexTernalstoragedirectory (). GetAbsolutePath ();
File File = new file (BasePath, imgname);
try {fileinputstream fis = new FileInputStream (file);
Bytearrayoutputstream BAOs = new Bytearrayoutputstream ();
byte b[] = new byte[1024];
int Len;
while (len = Fis.read (b))!=-1) {baos.write (b, 0, Len);} byte buff[] = Baos.tobytearray (); if (Buff!= null && buff.length!= 0) {bitmap = Bitmapfactory.decodebytearray (buff, 0, buff.length);}
catch (IOException e) {e.printstacktrace ();} return bitmap; }
}

In this example, the image defaults to the SD card root directory.

And then the main main function:

Package com.yztc.lx.cashimg;
Import Android.graphics.Bitmap;
Import Android.graphics.BitmapFactory;
Import Android.os.Bundle;
Import Android.os.Handler;
Import Android.os.Message;
Import android.support.v7.app.AppCompatActivity;
Import Android.util.Log;
Import Android.util.LruCache;
Import Android.view.View;
Import Android.widget.Button;
Import Android.widget.ImageView;
Import Android.widget.Toast;
Import java.lang.ref.SoftReference;
Import Java.util.LinkedHashMap; public class Mainactivity extends Appcompatactivity implements View.onclicklistener {private Button btn_download; privat
e ImageView iv_img;
Private Mylrucache Mylrucache;
Private linkedhashmap<string, softreference<bitmap>> cashmap = new linkedhashmap<> ();
private static final String TAG = "mainactivity";
Private String Imgpath = "Yun_qi_img/medium_20121217143424221.jpg"; Private Handler Handler = new Handler () {@Override public void Handlemessage (msg) {Bitmap Bitmap = (Bitmap) msg.
Obj Iv_img.sEtimagebitmap (bitmap);
Toast.maketext (mainactivity.this, "Download pictures from the Web", Toast.length_short). Show ();
}
}; @Override protected void OnCreate (Bundle savedinstancestate) {super.oncreate (savedinstancestate); Setcontentview (
R.layout.activity_main);
Initview ();
int totalmemory = (int) runtime.getruntime (). MaxMemory ();
int size = TOTALMEMORY/8;
Mylrucache = new Mylrucache (size);
Btn_download.setonclicklistener (this); private void Initview () {btn_download = (Button) Findviewbyid (r.id.btn_download); iv_img = (ImageView) Findviewbyid (R.i
D.IV_IMG); @Override public void OnClick (View v) {Bitmap b = getimgcache (); if (b!= null) {Iv_img.setimagebitmap (b);} else {NE W Thread (New Runnable () {@Override public void run () {if (Httputils.isnetconn (mainactivity.this)) {byte b[] = Httputils
. getdatefromnet (Imgpath);
if (b!= null && b.length!= 0) {Bitmap Bitmap = Bitmapfactory.decodebytearray (b, 0, b.length);
Message msg = Message.obtain ();
Msg.obj = bitmap;
Handler.sendmessage (msg); MylRucache.put (Imgpath, bitmap);
LOG.D (TAG, "Run:" + "cache to strong reference success");
Boolean bl = Externalstorageutils.storetosdroot ("haha.jpg", b); if (BL) {LOG.D (TAG, "Run:" + "cached to local memory success");} else {log.d (TAG, "Run:" + "cached to local memory failed");} else {toast.maketext (mainactivity.this, "Download failed!) ", Toast.length_short). Show ();} else {toast.maketext (mainactivity.this, "Please check your network!") ", Toast.length_short). Show ();}}.
Start (); /** * Get Picture from Cache * * @return returns the Bitmap/public Bitmap Getimgcache () {Bitmap Bitmap = Mylrucache.get (Imgpath); if ( Bitmap!= null) {LOG.D (TAG, "Getimgcache:" + "get Picture from LRUCache");}  else {softreference<bitmap> sr = Cashmap.get (imgpath); if (SR!= null) {Bitmap = Sr.get (); Mylrucache.put (Imgpath,
Bitmap);
Cashmap.remove (Imgpath); LOG.D (TAG, "Getimgcache:" + "get Picture from soft Reference");}
else {bitmap = Externalstorageutils.getimgfromsdroot ("haha.jpg");
LOG.D (TAG, "Getimgcache:" + "get Picture from external store");}
return bitmap; /** * Customize a method to inherit the LruCache method of the system * * public class Mylrucache extends Lrucache<stRing, bitmap> {/** * The constructor that must be overridden to define the size of the strong reference buffer * @param maxSize for caches that does not override {@link #sizeOf}. The maximum number of entries in the cache.
For all other caches, * it is the maximum sum of the sizes of the the entries in this cache.  */public Mylrucache (int maxSize) {super (maxSize);}//returns the size of each picture @Override protected int sizeOf (String key, Bitmap value) {//Get the number of bytes per row and row height of the current variable (basically fixed writing, don't remember to give me back!)
) return Value.getrowbytes () * Value.getheight (); /** * When the data in LRUCache is evicted or removed when the callback function * * @param evicted when the data in LRUCache is expelled to give the new value out of space, change * @param key is used to mark the key of the object. The URL address of the picture * @param the old object stored before OldValue * @param newvalue Stored new Object */@Override protected void Entryremoved (Boolean evicted, S Tring Key, Bitmap OldValue, Bitmap newvalue) {if (evicted) {/** * saves old values to soft references because multiple values may be evicted in a strong reference, * so create a linkedhashmap<s Tring, softreference<bitmap>> to store soft references * Basic is also fixed writing * * * softreference<bitmap> softreference = new
Softreference<bitmap> (OldValue); Cashmap.put (Key, softReference); }
}
}
}

The basic ideas are written in detail in the code comments, mainly to customize a class to inherit the LRUCache of the system, to implement the two main methods sizeof () and entryremoved (), and to rewrite its constructor.

The above is a small set up to introduce the Android picture of the three-level caching mechanism of all the narrative, I hope to help you, if you have any questions welcome to my message, small series will promptly reply to everyone, here also thank you for your support cloud Habitat community site!

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.