Android Universal ImageLoader cache images

  • 2020-12-22 17:45:39
  • OfStack

Project Introduction:

One of the most frustrating aspects of Android is getting pictures, displaying them and retrieving them from the Internet. Any problem with any one of the links can be solved directly by OOM. This project may help you. Universal Image Loader for Android is designed to realize asynchronous network image loading, caching and display, and supports multi-threaded asynchronous loading. It was originally derived from the Fedor Vlasov project and has been extensively refactored and improved since.

Feature list:

Multi-threaded download images, images can be from the network, file system, project folder assets and drawable medium
Supports arbitrary configuration of ImageLoader, such as thread pools, image downloaders, memory caching policies, hard disk caching policies, image display options, and more
Support for image memory cache, file system cache or SD card cache
Support picture download process listening
Trim Bitmap to the size of the control (ImageView) to reduce the excessive memory footprint of Bitmap
Better control the loading process of pictures, such as suspending the loading of pictures and restarting the loading of pictures. Generally used in ListView and GridView, the loading of pictures is suspended during the sliding process and the loading of pictures is stopped when the sliding stops
Provides image loading on a slow network

Application process:

Create the default ImageLoader, with all operations controlled by ImageLoader. This class uses a singleton design pattern, so if you want to capture the strength of the class, you need to call the getInstance() method. Before displaying an image using ImageLoader, you first initialize its configuration, calling ImageLoaderConfiguration's init() method, and then you can implement various displays.


// Create default ImageLoader Configuration parameters  
ImageLoaderConfiguration configuration = ImageLoaderConfiguration 
.createDefault(this); 
//Initialize ImageLoader with configuration. 
ImageLoader.getInstance().init(configuration); 

Custom configure imageloader, as you already know, first you need to initialize ImageLoader with the ImageLoaderConfiguration object. Since ImageLoader is a singleton, it only needs to be initialized once at the beginning of the program. It is recommended that you initialize in the onCreate () method of Activity. If an ImageLoader has already been initialized, reinitializing it will not have any effect. Let's create 1 setting with ImageLoaderConfiguration.Builder


File cacheDir =StorageUtils.getOwnCacheDirectory(this, "imageloader/Cache"); 
ImageLoaderConfigurationconfig = new ImageLoaderConfiguration 
.Builder(this) 
.memoryCacheExtraOptions(480, 800) // maxwidth, max height , the maximum length and width of each cache file saved  
.threadPoolSize(3)// The number of loads in the thread pool  
.threadPriority(Thread.NORM_PRIORITY -2) 
.denyCacheImageMultipleSizesInMemory() 
.memoryCache(new UsingFreqLimitedMemoryCache(2* 1024 * 1024)) // You can pass your own memory cache implementation/ You can do this with your own memory cache  
.memoryCacheSize(2 * 1024 * 1024) 
.discCacheSize(50 * 1024 * 1024) 
.discCacheFileNameGenerator(newMd5FileNameGenerator())// Will save the time of URI The name with MD5  encryption  
.tasksProcessingOrder(QueueProcessingType.LIFO) 
.discCacheFileCount(100) // The number of files cached  
.discCache(new UnlimitedDiscCache(cacheDir))// Customize the cache path  
.defaultDisplayImageOptions(DisplayImageOptions.createSimple()) 
.imageDownloader(new BaseImageDownloader(this,5 * 1000, 30 * 1000)) // connectTimeout (5 s), readTimeout (30 s) timeout  
.writeDebugLogs() // Remove for releaseapp 
.build();// Begin to build  
ImageLoader.getInstance().init(config); 

Get imageLoader


ImageLoader imageLoader imageLoader = ImageLoader.getInstance(); 

Application process:

(1) Whether image operation is involved in caching and image effect configuration operation


DisplayImageOptions options = new DisplayImageOptions.Builder() 
.showImageOnLoading(R.drawable.ic_stub) // The image when the image is loaded  
.showImageForEmptyUri(R.drawable.ic_empty) // Default image when no image resource is available  
.showImageOnFail(R.drawable.ic_error) // Failed to load the image  
.cacheInMemory(true) // Enable memory caching  
.cacheOnDisk(true) // Enable external memory caching  
.considerExifParams(true) // To enable the EXIF and JPEG Image format  
.displayer(new RoundedBitmapDisplayer(20)) // I'm going to set the display style and here's the rounded rectangle  
.build(); 

DisplayImageOptions below are all default configuration parameters that can be customized as required


private int imageResOnLoading = 0; 
private int imageResForEmptyUri = 0; 
private int imageResOnFail = 0; 
private Drawable imageOnLoading = null; 
private Drawable imageForEmptyUri = null; 
private Drawable imageOnFail = null; 
private boolean resetViewBeforeLoading = false; 
private boolean cacheInMemory = false; 
private boolean cacheOnDisk = false; 
private ImageScaleType imageScaleType = ImageScaleType.IN_SAMPLE_POWER_OF_2; 
private Options decodingOptions = new Options(); 
private int delayBeforeLoading = 0; 
private boolean considerExifParams = false; 
private Object extraForDownloader = null; 
private BitmapProcessor preProcessor = null; 
private BitmapProcessor postProcessor = null; 
private BitmapDisplayer displayer = DefaultConfigurationFactory.createBitmapDisplayer(); 
private Handler handler = null; 
private boolean isSyncLoading = false; 

(2) The image load listener is in here and you can set the animation when it loads or the progress bar or something like that


ImageLoadingListener animateFirstListener = new AnimateFirstDisplayListener(); 
private static class AnimateFirstDisplayListener extends SimpleImageLoadingListener { 
static final List<String> displayedImages = Collections.synchronizedList(new LinkedList<String>()); 
@Override 
public void onLoadingComplete(String imageUri, View view, Bitmap loadedImage) { 
if (loadedImage != null) { 
ImageView imageView = (ImageView) view; 
boolean firstDisplay = !displayedImages.contains(imageUri); 
if (firstDisplay) { 
FadeInBitmapDisplayer.animate(imageView, 500); 
displayedImages.add(imageUri); 
} 
} 
} 
}

(3) Simple Settings can add images to ImageView


imageLoader.displayImage(imageUrl, imageview, options, animateFirstListener); 

For local images, add "file://" before their absolute address. The network picture directly writes the path.

Since my bag is the latest one, it may be different from the old one. Some netizens said:


String imageUri = "http://site.com/image.png"; //  Network image  
String imageUri = "file:///mnt/sdcard/image.png"; //SD Card image  
String imageUri = "content://media/external/audio/albumart/13"; //  Media folder  
String imageUri = "assets://image.png"; // assets 
String imageUri = "drawable://" + R.drawable.image; // drawable file  

Cache cleaning:

Cache cleaning can be done on demand, either in each Activity lifecycle function onDestroy or separately for the user to clean.


@Override 
public void onDestroy() { 
super.onDestroy(); 
imageLoader.clearMemoryCache(); 
imageLoader.clearDiskCache(); 
}

GirdView,ListView Loading picture:

Believe that most people are using GridView, ListView to show a lot of pictures, and when we fast sliding GridView ListView, we hope that we can stop the loading pictures, in GridView ListView stop sliding load current pictures of the interface, this framework also provides the function, of course, it is very easy to use, it provides PauseOnScrollListener this class to control ListView, GridView stop to load images in the process of sliding, the class is using a proxy mode


listView.setOnScrollListener(new PauseOnScrollListener(imageLoader, pauseOnScroll, pauseOnFling)); 
gridView.setOnScrollListener(new PauseOnScrollListener(imageLoader, pauseOnScroll, pauseOnFling)); 

The first parameter is our image loading object ImageLoader, the second parameter is to control whether the image loading is suspended during the sliding process, if it is necessary to suspend the transmission of true, the third parameter is to control whether the image loading when the heavy sliding interface

OutOfMemoryError:

Although this framework has good caching mechanism, effectively avoid the OOM, 1 case of produce OOM probability is small, but does not guarantee OutOfMemoryError never occurs, the framework of OutOfMemoryError made the simple catch, ensure that our programs meet OOM without being crash drop, but if we use the framework OOM happens often, we should be how to improve?

Reduce the number of threads in the thread pool, configure in ImageLoaderConfiguration (.threadPoolSize), and recommend configurations 1-5

In the DisplayImageOptions option, configure bitmapConfig as ES128en.Config.RGB_565. Since the default is ARGB_8888, using RGB_565 will consume twice as much memory as using ARGB_8888

Configure the memory cache for images in ImageLoaderConfiguration as memoryCache(newWeakMemoryCache()) or do not use the memory cache

In the DisplayImageOptions option, set.imageScaleType (ES143en.IN_SAMPLE_ES146en) or imageScaleType(ES148en.EXACTLY)

Through these, I believe everyone to Universal Image - Loader framework have been very understanding of the use of, when we were in the use of the framework as far as possible the use of displayImage () method to load images, loadImage () object callback is to picture the ImageLoadingListener interface onLoadingComplete () method, we need to manually set to ImageView above, displayImage () method, to ImageView objects using the Weak references, To make it easier for the garbage collector to recycle the ImageView object, if we want to load a fixed size image, the loadImage() method needs to pass 1 ImageSize object, and the displayImage() method will be based on the measurement value of the ImageView object, or the value set by android:layout_width android:layout_height. Or android:maxWidth and/or android:maxHeight set the value to crop the image


Related articles: