Easy Tutorial
❮ Npm Switch Repo Nvm Manager Node Versions ❯

12.3 DrySister's Sister Viewing App (First Edition) - 3. Image Loading Optimization (Creating a Simple Image Caching Framework)

Category Android Basic Tutorial

1. Some Chatter

In the previous section, we changed the data source for the sister images from local to parsing data from the Gank API. In this section, we want to optimize this image loading class, such as adding the display of local images, and another point is caching. The current image loading we use has no caching at all. Each time, it requests and parses the stream, even if it's the same image, it has to request it every time, which seems a bit redundant. How about caching the images in memory or on the disk, and when accessing the same image resources, we get them from here? Hmm, it seems promising, so in this section, let's write a simple image loading framework with caching! Yeah, let's call it SisterLoader!

(PS: The reason for the long delay in updating is that I have been looking at download-related things recently, and also fixing BUGs. When writing the image loading, I got stuck due to some issues and couldn't find time to resolve them...)


2. Simple Knowledge Popularization

Before we start writing code, let's clarify some concepts:

1) Caching

① The purpose of introducing image caching:

Answer: Loading images from the network is time-consuming, power-consuming, and data-consuming. We hope that some loaded images can be stored, and when loaded again, they can be reused.

② What is two-level caching:

Answer: Let me explain the logic you need to go through to display an image, and you will be clear: Need to display an image ——> Check memory (display if available) — No —> Check disk (display if available) — No —> Load from the network (display it) ——> Store a copy in memory ——> Store a copy on the disk

From the above, we know that there are two types of caches, memory cache and disk cache (SD card/phone storage):

Memory cache: First-level cache, priority is given to fetching from here, and the cache file is stored in the data/data/package name/cache directory. The old routine for writing memory cache used to be with Map weak reference Bitmap objects. I looked through the ancestral code of the previous company:

public class MemoryCache {

    private static final int MAX_CACHE_COUNT = 30;  //Set the maximum number of caches

    /**
    Map weak reference Bitmap, Bitmap will not be recycled if there is enough memory. When the cache count is greater than the threshold, it will clear the earliest cached
     */
    private HashMap&lt;String,SoftReference<Bitmap>> mCacheMap = new LinkedHashMap&lt;String,SoftReference<Bitmap>>() {
        @Override
        protected boolean removeEldestEntry(Entry eldest) {
            return size() > MAX_CACHE_COUNT;
        }
    };

    /**
     * Add an image to the cache
     * */
    public void put(String id,Bitmap bitmap) {
        mCacheMap.put(id, new SoftReference<>(bitmap));
    }

    /**
     * Get the image from the cache
     * */
    public Bitmap get(String id,Bitmap bitmap) {
       if(!mCacheMap.containsKey(id))return null;
        SoftReference<Bitmap> ref = mCacheMap.get(id);
        return ref.get();
    }

    /**
     * Clear all caches
     * */
    public void clear() {
        try{
            for (Map.Entry&lt;String,SoftReference<Bitmap>>entry : mCacheMap.entrySet()) {
                SoftReference<Bitmap> sr = entry.getValue();
                if(null != sr) {
                    Bitmap bitmap = sr.get();
                    if(null != bitmap) {
                        bitmap.recycle();
                    }
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

}

However, Google does not recommend doing this. The official best practice recommends two APIs for us regarding caching: LruCache (memory cache) and DiskLruCache (disk cache). LruCache refers to the cache objects in the outside world in a strong reference (direct reference) way, which will not be collected by GC, And SoftReference references, when the system memory is insufficient, will be collected by GC There is also a WeakReference, which can be collected by the system at any time... If you are very interested in this, you can go to the official best practice: [Caching Bitmaps](https://developer.android.com/training/displaying-bitmaps/cache-bitmap

❮ Npm Switch Repo Nvm Manager Node Versions ❯