Detailed explanation of the disk cache of the image download framework UniversialImageLoader for Android (1 ),
The monkeys who have been immersed in the development world of Android for some years are probably able to deeply understand that downloading, displaying, and caching images in Android has always been hard to erase. This is also true for the monks. Okay, let's talk about it. In order to urge you to learn, we will explore the UniversialImageLoader, which is a cool image processing framework in Android!
If everything is too hasty, it will be stuck in the mud. We still step by step to break through this framework.
The first thing to talk about is the disk cache interface DiskCache.
First, let's take a look at the code of the core interface:
File getDirectory();File get(String imageUri);boolean save(String imageUri, InputStream imageStream, IoUtils.CopyListener listener) throws IOException;boolean save(String imageUri, Bitmap bitmap) throws IOException;boolean remove(String imageUri);void close();void clear();
Through the above Code, we found that the disk cache interface only contains this content.
1. Get the root directory of the current disk cache
2. Get the object corresponding to the current image cache through the specified image uri
3. Save the file stream to the disk. The corresponding parameters include: 1. uri2. 3. file stream. 3. Observer of the current stream write progress and status.
4. Save the Bitmap view object to the disk.
5. If there is a cached image, it is inevitable that the image file will be deleted, just as if there is Yin and Yang, the parameter for deleting the image is uri
6. Close the stream of the current disk and release the related resources created during the operation.
7. The last one is to clear the disk cache.
The second thing to talk about is the class that implements the disk cache interface. In this lecture, we mainly need to pay attention to three classes. They are: BasicDiskCache, LimitedAgeDiskCache, and UnLimitedAgeDiskCache.
We should analyze the abstract class BasicDiskCache for disk caching in a logical order.
To streamline the process, first analyze the member variables. I believe that the explanation of the temporary variables can also be used to understand the overall functions.
public static final int DEFAULT_BUFFER_SIZE = 32 * 1024; // 32 Kbpublic static final Bitmap.CompressFormat DEFAULT_COMPRESS_FORMAT = Bitmap.CompressFormat.PNG;public static final int DEFAULT_COMPRESS_QUALITY = 100;private static final String ERROR_ARG_NULL = " argument must be not null";private static final String TEMP_IMAGE_POSTFIX = ".tmp";protected final File cacheDir;protected final File reserveCacheDir;protected final FileNameGenerator fileNameGenerator;protected int bufferSize = DEFAULT_BUFFER_SIZE;protected Bitmap.CompressFormat compressFormat = DEFAULT_COMPRESS_FORMAT;protected int compressQuality = DEFAULT_COMPRESS_QUALITY;
That is to say, the member variable is: 1. default buffer size 2. The default image compression format is PNG 3, the default compression quality is 100 4, including the temporary Image File Cache name 5, cache file directory 6. cache file backup directory 7. File name Generator
For better understanding, let's take another method to save the byte stream of images:
@ Overridepublic boolean save (String imageUri, InputStream imageStream, IoUtils. copyListener listener) throws IOException {// analyze how the File is saved // create an empty File imageFile = getFile (imageUri ); // create a temporary File tmpFile = new File (imageFile. getAbsolutePath () + TEMP_IMAGE_POSTFIX); // boolean loaded = false is not loaded by default; try {// create an input stream object with a temporary file OutputStream OS = new BufferedOutputStream (new FileOutputStream (tmpFile), bufferSi Ze); try {// The current image is being copied loaded = IoUtils. copyStream (imageStream, OS, listener, bufferSize);} finally {IoUtils. closeSilently (OS) ;}} finally {if (loaded &&! TmpFile. renameTo (imageFile) {loaded = false;} if (! Loaded) {tmpFile. delete () ;}return loaded ;}
From the above Code, we know that we will create a file with a temporary cached Image Based on the uri parameter, and then use the tool class method to copy the input stream to the output stream.
The following describes the limited lifecycle of the disk cache LimitedAgeDiskCache.
Compared with the abstract class, two new member variables of the current class are added:
// Maximum lifetime of a File private final long maxFileAge; // each File corresponds to a lifetime date private final Map <File, Long> loadingDates = Collections. synchronizedMap (new HashMap <File, Long> ());
The Maximum Cache Time of the file maxFileAge is measured in seconds, and the corresponding HashMap is used to cache the loading time of the image file.
You can pay attention to the function of caching the file loading time in this class.
Private void rememberUsage (String imageUri) {// handle File file = getFile (imageUri) of the File created by the Prime Minister; // obtain the current time long currentTime = System. currentTimeMillis (); // remember the modified time file. setLastModified (currentTime); // put it in the memory loadingDates. put (file, currentTime );}
Compared with the LimitedAgeDiskCache with the cache time limit, the UnlimitedDiskCache is obviously better understood, which is the same as its parent class abstract class. I will not go into details.