In addition to Weibo, there is also WeChat
Please pay attention
WeChat public account
Shulou
2025-01-17 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >
Share
Shulou(Shulou.com)05/31 Report--
This article mainly introduces the relevant knowledge of how to use the Bitmap cache pool in Android, the content is detailed and easy to understand, the operation is simple and fast, and has a certain reference value. I believe you will gain something after reading this article on how to use the Bitmap cache pool in Android. Let's take a look.
Use memory caching
Memory caching increases the speed of accessing pictures, but takes up a lot of memory. The LruCache class (classes in Support Library can be used before API 4) is particularly suitable for caching Bitmap, saving recently used Bitmap objects with strong references (to LinkedHashMap), and deleting infrequently used objects when the number of caches reaches a predetermined value.
Note: in the past, the common way to implement in-memory caching was to use SoftReference or WeakReference bitmap caching, but this is not recommended. Starting with Android 2.3 (API Level 9), garbage collection begins to force the collection of soft/weak references, resulting in no efficiency improvement in these caches.
In addition, prior to Android 3.0 (API Level 11), these cached Bitmap data were kept in the underlying memory (native memory), and when the predetermined conditions were met, these objects were not released, which could cause the program to exceed the memory limit and crash.
When using LruCache, you need to consider the following factors to select an appropriate cache quantity parameter:
How much memory is available in the program?
How many pictures are displayed on the screen at the same time? How many pictures do you want to cache to display on the screen you are about to see?
What is the screen size and density of the device? Ultra-high screen density (xhdpi such as Galaxy Nexus)
Devices that display the same images require more memory than low-screen density (hdpi, such as Nexus S) devices.
The size and format of the picture determine how much memory each picture needs.
How often do you visit pictures? Some pictures are visited much more frequently than others? If so, you may need to put these frequently accessed images in memory.
How to balance quality and quantity? In some cases, it is useful to save a large number of low-quality images, using background threads to add a high-quality version of the image when needed.
There is no recipe for all programs. You need to analyze your usage and specify your own caching strategy. Using a cache that is too small will not have the desired effect, while using too large a cache will consume more
It is possible to cause java.lang.OutOfMemory exceptions or leave little memory for other functions of your program.
The following is an example of using LruCache caching:
Private LruCache mMemoryCache; @ Override protected void onCreate (Bundle savedInstanceState) {... / / Get memory class of this device, exceeding this amount will throw an / / OutOfMemory exception. Final int memClass = (ActivityManager) context.getSystemService (Context.ACTIVITY_SERVICE). GetMemoryClass (); / / Use 1/8th of the available memory for this memory cache. Final int cacheSize = 1024 * 1024 * memClass / 8; mMemoryCache = new LruCache (cacheSize) {@ Override protected int sizeOf (String key, Bitmap bitmap) {/ / The cache size will be measured in bytes rather than number of items. Return bitmap.getByteCount ();}};...} 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 this example, the program's 1ram 8 memory is used for caching. In a normal/hdpi device, this has at least 4MB (32 Universe 8) memory.
In a device with a resolution of 800 × 480, a full screen of GridView filled with images will use almost 1.5MB (800 / 480 / 480 / 4 bytes) memory, so it caches almost 2.5 pages of images in memory.
When displaying a picture in ImageView, first check to see if it exists in LruCache. If it exists, use the cached image. If it does not exist, start the background thread to load the image and cache 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);}}
BitmapWorkerTask needs to add new images to the 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;}.}
The next page will show you two other ways to use disk caching and handle configuration change events
Use disk caching
Memory caching is fast in accessing recently used pictures, but you are not sure whether the picture exists in the cache. Controls like GridView may have a lot of images to display, and soon the image data fills up the cache capacity.
At the same time, your program may also be interrupted by other tasks, such as incoming phone calls-when your program is in the background, the system may be aware of these image caches. Once the user resumes using your program, you also need to reprocess these pictures.
In this case, you can use the disk cache to save these processed pictures, and when these pictures are not available in the memory cache, they can be loaded from the disk cache to omit the image processing process.
Of course, loading pictures from disk is much slower than reading from memory, and you should load disk pictures in non-UI threads.
Note: if cached images are often used, consider using ContentProvider, for example, in a library program.
There is a simple DiskLruCache implementation in the sample code. Then, a more reliable and recommended DiskLruCache (libcore/luni/src/main/java/libcore/io/DiskLruCache.java) is included in Android 4.0. You can easily port this implementation to a version prior to 4.0 (href= "http://www.google.com/search?q=disklrucache">Google to see if someone else has already done so!).
Here is a newer version of DiskLruCache:
Private DiskLruCache mDiskCache; 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. File cacheDir = getCacheDir (this, DISK_CACHE_SUBDIR); mDiskCache = DiskLruCache.openCache (this, cacheDir, DISK_CACHE_SIZE);...} 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 (String.valueOf (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 if (! mDiskCache.containsKey (key)) {mDiskCache.put (key, bitmap);}} public Bitmap getBitmapFromDiskCache (String key) {return mDiskCache.get (key);} / / 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 getCacheDir (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.getExternalStorageState () = Environment.MEDIA_MOUNTED | |! Environment.isExternalStorageRemovable ()? Context.getExternalCacheDir () .getPath (): context.getCacheDir () .getPath (); return new File (cachePath + File.separator + uniqueName);}
Detect the memory cache in the UI thread and the disk cache in the background thread. Disk operations should never be implemented in UI threads. When the image is processed, the final result is added to both the memory cache and the disk cache for future use.
Handle configuration change events
Run-time configuration changes-such as a change in screen orientation-cause Android to destroy the running Activity and then restart the Activity with the new configuration (see Handling Runtime Changes here for details).
You need to be careful to avoid reprocessing all images when the configuration changes, thereby improving the user experience.
Fortunately, you already have a good image cache in the in-memory cache section. The cache can be passed to the new Activity via Fragment (Fragment will be saved through the setRetainInstance (true) function)
When the Activity is restarted, the Fragment is reattached to the Activity, and you can get the cache object through the Fragment.
The following is an example of saving a cache in Fragment:
Private LruCache mMemoryCache; @ Override protected void onCreate (Bundle savedInstanceState) {... RetainFragment mRetainFragment = RetainFragment.findOrCreateRetainFragment (getFragmentManager ()); mMemoryCache = RetainFragment.mRetainedCache; if (mMemoryCache = = null) {mMemoryCache = new LruCache (cacheSize) {... / Initialize cache here as usual} mRetainFragment.mRetainedCache = mMemoryCache;}...} class RetainFragment extends Fragment {private static final String TAG = "RetainFragment"; public LruCache mRetainedCache Public RetainFragment () {} public static RetainFragment findOrCreateRetainFragment (FragmentManager fm) {RetainFragment fragment = (RetainFragment) fm.findFragmentByTag (TAG); if (fragment = = null) {fragment = new RetainFragment ();} return fragment;} @ Override public void onCreate (Bundle savedInstanceState) {super.onCreate (savedInstanceState) SetRetainInstance (true);}} this is the end of the article on "how to use Bitmap cache pools in Android". Thank you for reading! I believe you all have a certain understanding of "how to use Bitmap cache pool in Android". If you want to learn more, you are welcome to follow the industry information channel.
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.
Continue with the installation of the previous hadoop.First, install zookooper1. Decompress zookoope
"Every 5-10 years, there's a rare product, a really special, very unusual product that's the most un
© 2024 shulou.com SLNews company. All rights reserved.