SoFunction
Updated on 2025-03-11

An example analysis of the third-level caching mechanism of Android pictures

An example analysis of the third-level caching mechanism of Android pictures

When we obtain pictures, if we do not coordinate the cache of the pictures, it will cause large traffic and cost traffic applications, poor user experience, affecting later development. To this end, I specially shared the Android image level three cache mechanism to obtain pictures from the network to optimize the application. It is carried out in three steps:

(1) Get pictures from cache
(2) Get the picture from the local cache directory and after obtaining it, put it in the cache
(3) Download the picture from the Internet, and after the download is completed, save it locally and put it in cache

Coordinating these three layers of image caching can greatly improve the performance and user experience of the application.

ImageCacheUtil, a tool class that quickly implements Level 3 caching, is as follows (if you have better suggestions, you can send me your email to express your ideas, and improve them together. See the blog homepage "Write me"):

1. ImageCacheUtil, a Level 3 cache tool class that obtains images from the network

public class ImageCacheUtil {
  private LruCache<String, Bitmap> lruCache;
  private File cacheDir;
  private ExecutorService newFixedThreadPool;
  private Handler handler;
  public static final int SUCCESS = 100;
  public static final int FAIL = 101;
  //When we get the picture, we have three steps  //1. Get the picture from the cache  //2. Get the image from the local cache directory and after obtaining it, put it in the cache  //3. Download the picture from the network, and after the download is completed, save it to the local cache directory and put it in the cache  public ImageCacheUtil(Context context,Handler handler){
    //Get the cache size    int maxsize = (int) (().maxMemory()/8);
    //maxSize: Set the maximum cache space    lruCache = new LruCache<String, Bitmap>(maxsize){
      //Get the space occupied by the moved out image. When the image is moved out, the cache space occupied by the image needs to be moved out of the cache.       @Override
      protected int sizeOf(String key, Bitmap value) {
         //Calculate the cache size occupied by the picture         //getRowBytes: Get the size occupied by a line of the image         //getHeight: Get the number of rows occupied by the picture        return ()*();
      }
    };
    //Get cache directory    cacheDir = ();
    //Get thread pool    //nThreads: Number of threads in the thread pool    newFixedThreadPool = (5);
     = handler;
  }
  /**
    * Methods to get pictures
    * @param url
    * @param positon
    * @return
    */
  public Bitmap getBitmap(String url,int position){
    Bitmap bitmap = null;
    //1. Get the image from the cache (LRUCache<k,v>) k:key Save the image mark, generally the url address of the image, v:value picture    bitmap = (url);//Get the corresponding picture from the cache according to the key    //(url, bitmap): Save the image to cache    if (bitmap!=null) {
      return bitmap;
    }
    //2. Get the image from the local cache directory and after obtaining it, put it in the cache    bitmap = getFromLocal(url);
    if (bitmap!=null) {
      return bitmap;
    }
    //3. Download the picture from the network, and after the download is completed, save it to the local cache directory and put it in the cache    getFromNet(url,position);
    return null;
  }
  /**
    * Download pictures from the network, asynchronous methods, thread pools
    * @param url
    * @param position
    */
  private void getFromNet(String url, int position) {
    (new RunnableTask(url,position));
  }
  class RunnableTask implements Runnable{
    private String imageUrl;
    private int position;
    public RunnableTask(String url,int position){
       = url;
       = position;
    }

    @Override
    public void run() {
      Message message = ();
      //Download pictures      try {
        URL url = new URL(imageUrl);
        HttpURLConnection conn = (HttpURLConnection) ();
        (3000);
        (5000);
        ("GET");
        InputStream inputStream = ();
        Bitmap bitmap = (inputStream);
        //Save to local cache        wirteToLocal(imageUrl, bitmap);
        //Save to system buffer        (imageUrl, bitmap);
        //Show the picture and send a message to the handler         = SUCCESS;
         = bitmap;
        message.arg1 = position;
        (message);
        return;
      } catch (Exception e) {
        ();
      }
       = FAIL;
      (message);
    }
  }
  /**
    * Get pictures from local cache directory
    * @param url
    */
  private Bitmap getFromLocal(String url) {
    //Get the picture based on the name of the picture    try {
      String fileName = (url).substring(10);
      File file = new File(cacheDir, fileName);
      Bitmap bitmap = (());
      //Anti-theft cache is in      (url, bitmap);
      return bitmap;
    } catch (Exception e) {
      ();
    }
    return null;
  }
  /**
    * Save the image to the local cache directory
    */
  public void wirteToLocal(String url,Bitmap bitmap){
    //url name, encrypted by MD5, and intercept the first 10 digits as names    try {
      String fileName = (url).substring(10);
      File file = new File(cacheDir, fileName);
      FileOutputStream out = new FileOutputStream(file);
      //format: The format of the picture (there are many pngs used in Android because the quality of the png will not change)      //quality: compression ratio      //stream: Stream information      (, 100, out);//Save the image to that location    } catch (Exception e) {
      ();
    }
  }

}

The MD5Encoder class used is as follows:

public class MD5Encoder {

  public static String encode(String string) throws Exception {
    byte[] hash = ("MD5").digest(("UTF-8"));
    StringBuilder hex = new StringBuilder( * 2);
    for (byte b : hash) {
      if ((b & 0xFF) < 0x10) {
        ("0");
      }
      ((b & 0xFF));
    }
    return ();
  }
}

2. Initialize imageCacheUtil in MainActivity

ImageCacheUtil imageCacheUtil = new ImageCacheUtil(getApplicationContext, handler);

3. Display the image through handler in MainActivity

After the image is successfully downloaded through the tool class, not only should the image be saved to the local cache and system cache, but the image must also be displayed and processed through the handler. This handler is set to use the ImageCacheUtil tool class, and you must pass your handler over so that we can send messages to the corresponding class using the ImageCacheUtil tool class for processing.

private Handler handler = new Handler(){
  public void handleMessage( msg) {
    switch () {
    case :
      //Set pictures for the control      Bitmap bitmap = (Bitmap) ;
      int position = msg.arg1;
      ImageView image= (ImageView) (position);//It is to obtain the corresponding control based on the position of the entry      if (image != null &amp;&amp; bitmap != null) {
        (bitmap);
      }
      break;
    case :
      (getApplicationContext, "Image download failed", 0).show();
      break;
    }
  };
};

4. Call in the getview of adapter in MainActivity

Bitmap bitmap = ((position).listimage, position);
if (bitmap != null) {
  (bitmap);
}

Thank you for reading, I hope it can help you. Thank you for your support for this site!