Network Security Internet Technology Development Database Servers Mobile Phone Android Software Apple Software Computer Software News IT Information

In addition to Weibo, there is also WeChat

Please pay attention

WeChat public account

Shulou

How to implement Picture caching Mechanism in Android

2025-01-16 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >

Share

Shulou(Shulou.com)05/31 Report--

This article mainly introduces "how to achieve the picture caching mechanism in Android". In the daily operation, I believe many people have doubts about how to achieve the picture caching mechanism in Android. The editor consulted all kinds of materials and sorted out simple and easy-to-use operation methods. I hope it will be helpful for you to answer the doubts about "how to realize the picture caching mechanism in Android". Next, please follow the editor to study!

In-depth understanding of Android image caching mechanism

It's easy for Android to load a single image into the user interface, but when you load more than one image at a time, the situation becomes complicated. In many cases (components such as ListView, GridView, or ViewPager), there is virtually no limit to the number of pictures that have been displayed on the screen and the number of pictures that are about to slide to the current screen.

These components reduce memory usage by reusing child views that have been removed from the screen, and the garbage collector releases downloaded images that are no longer in use, all of which are good methods, but in order to maintain a smooth, fast-loading user interface, you should avoid reprocessing images when you go back to a page. Memory caching and disk caching can help us do this, allowing components to quickly reload processed images.

Use memory caching

Memory caching allows quick access to pictures, but at the expense of App's precious memory. The LruCache class (also supported by Support Library in API Level 4) is particularly suitable for image caching, which uses a strongly referenced LinkedHashMap to hold recently used objects and removes the least recently used objects before the number of caches exceeds the preset size.

Note: the popular in-memory caching scheme used to use soft or weak references to cache pictures, but this is no longer recommended, because since android 2.3 (API Level 9), garbage collectors tend to recycle soft or weak references first, making them inefficient. In addition, before Android 3.0 (API Level 11), the pixel data of the picture was stored in local memory (native memory), which was released in an unpredictable way, so it could cause App to exceed the memory limit or even crash.

To set an appropriate size for LruCache, here are some factors that should be considered:

1. How much memory is available in your Activity or App?

two。 How many pictures are displayed on the screen at a time? How many pictures need to be prepared in advance so that they can be loaded into the screen at any time?

3. What is the screen size and density of the equipment? High-resolution (xhdpi) devices like Galaxy Nexus require more cache space when caching the same number of images than Nexus S (hdpi) devices.

4. What is the size and configuration of the picture? How much memory does each picture take up?

5. How often do you visit the picture? Are some pictures visited more frequently than others? If so, it may be possible to keep some images in memory all the time or set different LruCache objects for different picture groups.

6. Can you balance the quality and quantity of pictures? Sometimes it is more useful to store more low-quality images, and when needed, download high-quality pictures through background tasks.

There is no specific size and formula for all App, you need to analyze your usage and come up with an appropriate solution. When a cache is too small, it can lead to unprofitable extra overhead, and when the cache is too large, it may also cause Java.lang.OutOfMemory exceptions, and the larger the cache, the smaller the memory left for the rest of the App.

Here is an example of setting LruCache for an image:

Private LruCache mMemoryCache; @ Override protected void onCreate (Bundle savedInstanceState) {... / / Get max available VM memory, exceeding this amount will throw an / / OutOfMemory exception. Stored in kilobytes as LruCache takes an / / int in its constructor. Final int maxMemory = (int) (Runtime.getRuntime (). MaxMemory () / 1024); / / Use 1/8th of the available memory for this memory cache. Final int cacheSize = maxMemory / 8; mMemoryCache = new LruCache (cacheSize) {@ Override protected int sizeOf (String key, Bitmap bitmap) {/ / The cache size will be measured in kilobytes rather than / / number of items. Return bitmap.getByteCount () / 1024;}};...} public void addBitmapToMemoryCache (String key, Bitmap bitmap) {if (getBitmapFromMemCache (key) = = null) {mMemoryCache.put (key, bitmap);}} public Bitmap getBitmapFromMemCache (String key) {return mMemoryCache.get (key);}

Note: in the above example, we have allocated 1x8 of the application memory as the cache size, which is at least the size of 4MB (32gam8) on a normal/hdpi device. A GridView full of pictures on an 800mm 480 resolution screen probably takes up the memory of 1.5MB (800*480*4byte), so the Cache can cache at least 2.5 pages of such images.

When loading an image into ImageView, first check the LruCache. If the image is found, it will be used to update the ImageView directly. If it is not found, a background thread will be opened to process it:

Public void loadBitmap (int resId, ImageView imageView) {final String imageKey = String.valueOf (resId); final Bitmap bitmap = getBitmapFromMemCache (imageKey); if (bitmap! = null) {mImageView.setImageBitmap (bitmap);} else {mImageView.setImageResource (R.drawable.image_placeholder); BitmapWorkerTask task = new BitmapWorkerTask (mImageView); task.execute (resId);}}

In the above thread, after decoding the picture, you also need to add it to the memory cache:

Class BitmapWorkerTask extends AsyncTask {... / / Decode image in background. @ Override protected Bitmap doInBackground (Integer... Params) {final Bitmap bitmap = decodeSampledBitmapFromResource (getResources (), params [0], 100,100)); addBitmapToMemoryCache (String.valueOf (params [0]), bitmap); return bitmap;}.}

Use disk caching

While memory caches are useful for quick access to recently used images, you can't guarantee that the images you need are in the cache, and components like GridView that display large amounts of data can easily fill the memory cache. Your App may also be interrupted by tasks like the phone, App may be killed when it is switched to the background, memory cache may also be destroyed, and once the user goes back to the previous interface, your App will still have to reprocess every image.

Disk cache can be used to assist in storing processed pictures. When pictures are not available in the memory cache, they can be looked up from the disk cache to reduce the number of loads. Of course, reading pictures from disk is slower than reading from memory and the read time is unexpected, so you need to use background threads to read.

Note: ContentProvider may be a suitable place to store frequently accessed images, such as in Image Gallery applications.

The sample code here is the DiskLruCache stripped out of the Android source code. The following is the updated example code, which adds the disk cache to the memory cache:

Private DiskLruCache mDiskLruCache; private final Object mDiskCacheLock = new Object (); private boolean mDiskCacheStarting = true; private static final int DISK_CACHE_SIZE = 1024 * 1024 * 10; / / 10MB private static final String DISK_CACHE_SUBDIR = "thumbnails"; @ Override protected void onCreate (Bundle savedInstanceState) {. / / Initialize memory cache... / / Initialize disk cache on background thread File cacheDir = getDiskCacheDir (this, DISK_CACHE_SUBDIR); new InitDiskCacheTask () .execute (cacheDir) ...} class InitDiskCacheTask extends AsyncTask {@ Override protected Void doInBackground (File...) Params) {synchronized (mDiskCacheLock) {File cacheDir = params [0]; mDiskLruCache = DiskLruCache.open (cacheDir, DISK_CACHE_SIZE); mDiskCacheStarting = false; / / Finished initialization mDiskCacheLock.notifyAll (); / / Wake any waiting threads} return null;}} class BitmapWorkerTask extends AsyncTask {. / / Decode image in background. @ Override protected Bitmap doInBackground (Integer... Params) {final String imageKey = String.valueOf (params [0]); / / Check disk cache in background thread Bitmap bitmap = getBitmapFromDiskCache (imageKey); if (bitmap = = null) {/ / Not found in disk cache / / Process as normal final Bitmap bitmap = decodeSampledBitmapFromResource (getResources (), params [0], 100,100));} / / Add final bitmap to caches addBitmapToCache (imageKey, bitmap); return bitmap }...} public void addBitmapToCache (String key, Bitmap bitmap) {/ / Add to memory cache as before if (getBitmapFromMemCache (key) = = null) {mMemoryCache.put (key, bitmap);} / / Also add to disk cache synchronized (mDiskCacheLock) {if (mDiskLruCache! = null & & mDiskLruCache.get (key) = null) {mDiskLruCache.put (key, bitmap) }} public Bitmap getBitmapFromDiskCache (String key) {synchronized (mDiskCacheLock) {/ / Wait while disk cache is started from background thread while (mDiskCacheStarting) {try {mDiskCacheLock.wait ();} catch (InterruptedException e) {} if (mDiskLruCache! = null) {return mDiskLruCache.get (key);}} return null;} / / Creates a unique subdirectory of the designated app cache directory. Tries to use external / / but if not mounted, falls back on internal storage. Public static File getDiskCacheDir (Context context, String uniqueName) {/ / Check if media is mounted or storage is built-in, if so, try and use external cache dir / / otherwise use internal cache dir final String cachePath = Environment.MEDIA_MOUNTED.equals (Environment.getExternalStorageState ()) | | isExternalStorageRemovable ()? GetExternalCacheDir (context). GetPath (): context.getCacheDir (). GetPath (); return new File (cachePath + File.separator + uniqueName);} at this point, the study on "how to implement the image caching mechanism in Android" is over, hoping to solve everyone's doubts. The collocation of theory and practice can better help you learn, go and try it! If you want to continue to learn more related knowledge, please continue to follow the website, the editor will continue to work hard to bring you more practical articles!

Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.

Views: 0

*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.

Share To

Development

Wechat

© 2024 shulou.com SLNews company. All rights reserved.

12
Report