Pictures in Android systems are generally represented by Bitmap objects, which support common formats such as png and jpg. Usually, the size of the picture is relatively large, and the memory allowed by a single application is limited, so we need to take some measures to reduce memory usage and improve loading speed.
1. Picture loading
The SDK provides the BitmapFactory class for us to load images. There are several commonly used methods:
- : Load from file.
- : Load from a byte array.
- : Load from the input stream.
- : Load from resource file.
Suppose we use ImageView to display images, and their size is usually much smaller than the size of the image, then it is obviously unnecessary to load the entire image into memory. There is a noun in graphics called "downsampling", which is to reduce the resolution of the image and make it conform to the size of the display area. Through classes, we can also achieve the same function. This is mainly used inSampleSize parameter. If its value is 1, the sampled picture is the same as the original picture. If it is 2, the length and width of the sampled picture are half of the original, and the memory occupied is one quarter of the original.
public static Bitmap decodeSampleBitmapFromBytes(byte[] data) { final options = new (); // When inJustDecodeBounds is true, only the original image information is parsed and the image will not be loaded. = true; (data, 0, , options); // At this time, the width and height of the picture can be obtained through and obtained. // The sampling ratio can be calculated based on your own needs. = 1; // inJustDecodeBounds is set to fales, loading the picture into memory. = false; return (res, resId, options); }
2. Image cache
Cache is widely used in the computer field, such as HTTP cache, DNS cache, etc. Cache can not only improve response speed, but also save server bandwidth. It is also applicable to image loading. In Android development, images are generally cached in two levels: memory cache and file cache, and they all have libraries for us to use, namely LruCache and DiskLruCache. From the name, we can see that both use the LRU algorithm, which is to give priority to the caches that are least used recently.
2.1、LruCache
LruCache is a cache class provided by Android, which is generally used to manage memory caches.
// #1: Determine the cache size.int maxMemory = (int)(().totalMemory() / 1024); int cacheSize = maxMemory / 8; // #2: Rewrite the sizeOf method to calculate the memory footprint of each cache object.LruCache<String, Bitmap> mMemoryCache = new LruCache<String, Bitmap>(cacheSize) { @Override protected int sizeOf(String key, Bitmap value) { return (); } };
LruCache is a generic class that can accommodate various objects, so it cannot calculate the size of the stored object, so we need to rewrite its sizeOf method and perform the calculation manually. So how is LruCache implemented? In fact, it just encapsulates LinkedHashMap and handles thread safety issues. There is a Boolean parameter in the constructor of LinkedHashMap, accessOrder , which is stored in access order when it is true, and in insert order when it is false. When an element is stored in the access order, the elements retrieved at its tail are the least recently used elements, and the LRU algorithm is implemented. LruCache only needs to calculate the current total cache size after each put function is called, and remove the element at the tail of LinkedHashMap when it exceeds the threshold.
2.2、DiskLruCache
Like LruCache, DiskLruCache uses LinkedHashMap to implement the LRU algorithm, but DiskLruCache is more complex in implementation and use, after all, files need to be managed.
To obtain the DiskLruCache object, you need to call the function:
public static DiskLruCache open(File directory, int appVersion, int valueCount, long maxSize)
It receives 4 parameters, the first is the cache directory, the second is the client version number. DiskLruCache believes that the cache is invalid when the version number changes, the third parameter represents that each key can be associated with several files, and the last parameter specifies the size of the cache area. When creating an object, DiskLruCache will index the cache file in LinkedHashMap based on the log file named "journal" in the buffer directory. All operations on the buffer will be recorded in this file. When the buffer size reaches the threshold value, the file is cleaned according to the LRU algorithm.
Use functions when reading cache:
public synchronized Snapshot get(String key) throws IOException
The function returns a Snapshot object through which we can get the input stream of the cache file. Multiple threads can use their respective SnapShot objects to read the cache corresponding to the same Key.
Use functions when operating cache:
public Editor edit(String key) throws IOException
After creation or change is completed, submit it with a function or cancel it with a function. When a Key's cache is operated, it can still use the Snapshot object to read its contents, because all the Editor's operations will first act on the temporary file. Note that each Key can only get one Editor object at the same time, which means that even if the Editor does not do anything, the function must be called or null, otherwise the function will return null when it is retrieved again.
2.3. Code examples
public Bitmap loadBitmap(String url) { // DiskLruCache requires that the key cannot contain special characters, so // Generally hashing is done first. String key = MD5(url); Bitmap bitmap = loadBitmapFromMemCache(key); if (bitmap != null) { return bitmap; } try { bitmap = loadBitmapFromDiskCache(key); if (bitmap != null) { return bitmap; } bitmap = loadBitmapFromHttp(url); if (bitmap != null) { return bitmap; } } catch (IOException e) { (); } return null; }
In the loadBitmapFromHttp function, you need to put the image resources into DiskLruCache, and in the loadBitmapFromDiskCache function, the loaded Bitmap object into LruCache, thus forming a cache chain.
Summarize
The above is the loading and caching of Android Bitmap that the editor introduced to you. I hope it will be helpful to you. If you have any questions, please leave me a message and the editor will reply to you in time. Thank you very much for your support for my website!