Complete parsing of Android open-source framework Universal-Image-Loader (1) --- basic introduction and usage

Source: Internet
Author: User

Reprinted please indicate this article from xiaanming blog (http://blog.csdn.net/xiaanming/article/details/26810303), please respect others' hard work results, thank you!

Hello everyone! I haven't written any articles in the past two months. I was busy changing jobs some time ago. I have prepared for a test interview or something. Now I have found a new job and I am quite satisfied with my new job, the only pity is that I want to go to a new city, a new environment, and a new start. I hope I can adapt to the new environment as soon as possible. Now I have some time to prepare for the handover, so I will continue to share with you about Android.

I believe that when we use Android apps, we often encounter the problem of loading images asynchronously or loading a large number of images. However, we often encounter many problems when loading images, such as image disorder, OOM and other problems. For new users, these problems will be difficult to solve, so many open-source Image loading frameworks have emerged. The famous one is Universal-Image-Loader, I believe many of my friends have heard of or used this powerful image loading framework. Today, this article introduces and uses this framework, mainly to help those who have never used this framework. This project exists on Github.

Of course, the features listed above may not be complete. If you want to know some other features, you can only find them through our usage. Next, let's take a look at the simple use of this open source library.


Create an Android project, download the JAR package, and add it to the libs directory of the project.

Create a new MyApplication that inherits the Application, create the configuration parameters of ImageLoader in onCreate (), and initialize them to ImageLoader. The Code is as follows:

Package com. example. uil; import com. nostra13.universalimageloader. core. imageLoader; import com. nostra13.universalimageloader. core. imageLoaderConfiguration; import android. app. application; public class MyApplication extends Application {@ Overridepublic void onCreate () {super. onCreate (); // create the default ImageLoader configuration Parameter ImageLoaderConfiguration = ImageLoaderConfiguration. createDefault (this); // Initialize ImageLoader with configuration. imageLoader. getInstance (). init (configuration );}}
ImageLoaderConfiguration is the configuration parameter of ImageLoader of the image loader. The Builder mode is used. The createDefault () method is directly used to create a default ImageLoaderConfiguration. Of course, you can also set ImageLoaderConfiguration as follows:

File cacheDir = StorageUtils.getCacheDirectory(context);ImageLoaderConfiguration config = new ImageLoaderConfiguration.Builder(context)        .memoryCacheExtraOptions(480, 800) // default = device screen dimensions        .diskCacheExtraOptions(480, 800, CompressFormat.JPEG, 75, null)        .taskExecutor(...)        .taskExecutorForCachedImages(...)        .threadPoolSize(3) // default        .threadPriority(Thread.NORM_PRIORITY - 1) // default        .tasksProcessingOrder(QueueProcessingType.FIFO) // default        .denyCacheImageMultipleSizesInMemory()        .memoryCache(new LruMemoryCache(2 * 1024 * 1024))        .memoryCacheSize(2 * 1024 * 1024)        .memoryCacheSizePercentage(13) // default        .diskCache(new UnlimitedDiscCache(cacheDir)) // default        .diskCacheSize(50 * 1024 * 1024)        .diskCacheFileCount(100)        .diskCacheFileNameGenerator(new HashCodeFileNameGenerator()) // default        .imageDownloader(new BaseImageDownloader(context)) // default        .imageDecoder(new BaseImageDecoder()) // default        .defaultDisplayImageOptions(DisplayImageOptions.createSimple()) // default        .writeDebugLogs()        .build();

The above are all options. We do not need to set each item in the project. Generally, we can use the ImageLoaderConfiguration created by createDefault (), and then call the init () of ImageLoader () the ImageLoaderConfiguration parameter is passed in. ImageLoader uses the singleton mode.


Configure the Android Manifest File

<manifest>    <uses-permission android:name="android.permission.INTERNET" />    <!-- Include next permission if you want to allow UIL to cache images on SD card -->    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />    ...    <application android:name="MyApplication">        ...    </application></manifest>

Next, we can load images. First, we define the layout file of the Activity.

<?xml version="1.0" encoding="utf-8"?><FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"    android:layout_width="fill_parent"    android:layout_height="fill_parent">    <ImageView        android:layout_gravity="center"        android:id="@+id/image"        android:src="@drawable/ic_empty"        android:layout_width="wrap_content"        android:layout_height="wrap_content" /></FrameLayout>

There is only one ImageView, which is very simple. Next we will load the image. We will find that ImageLader provides several image loading methods, mainly including the displayImage (), loadImage (), the loadImageSync () and loadImageSync () methods are synchronized. android4.0 has a feature that prevents network operations from in the main thread. Therefore, we will not use the loadImageSync () method.

.

Loadimage () attach an image


We first use the loadImage () method of ImageLoader to load network images.

final ImageView mImageView = (ImageView) findViewById(R.id.image);String imageUrl = "https://lh6.googleusercontent.com/-55osAWw3x0Q/URquUtcFr5I/AAAAAAAAAbs/rWlj1RUKrYI/s1024/A%252520Photographer.jpg";ImageLoader.getInstance().loadImage(imageUrl, new ImageLoadingListener() {@Overridepublic void onLoadingStarted(String imageUri, View view) {}@Overridepublic void onLoadingFailed(String imageUri, View view,FailReason failReason) {}@Overridepublic void onLoadingComplete(String imageUri, View view, Bitmap loadedImage) {mImageView.setImageBitmap(loadedImage);}@Overridepublic void onLoadingCancelled(String imageUri, View view) {}});
Input the image url and ImageLoaderListener. In the callback method onLoadingComplete (), set loadedImage to ImageView. If you think it is too complicated to input ImageLoaderListener, we can use the SimpleImageLoadingListener class, this class provides an empty implementation of the ImageLoaderListener interface method, using the default adapter Mode

final ImageView mImageView = (ImageView) findViewById(R.id.image);String imageUrl = "https://lh6.googleusercontent.com/-55osAWw3x0Q/URquUtcFr5I/AAAAAAAAAbs/rWlj1RUKrYI/s1024/A%252520Photographer.jpg";ImageLoader.getInstance().loadImage(imageUrl, new SimpleImageLoadingListener(){@Overridepublic void onLoadingComplete(String imageUri, View view,Bitmap loadedImage) {super.onLoadingComplete(imageUri, view, loadedImage);mImageView.setImageBitmap(loadedImage);}});
What if we want to specify the image size? Initialize an ImageSize object and specify the image width and height. The Code is as follows:

final ImageView mImageView = (ImageView) findViewById(R.id.image);String imageUrl = "https://lh6.googleusercontent.com/-55osAWw3x0Q/URquUtcFr5I/AAAAAAAAAbs/rWlj1RUKrYI/s1024/A%252520Photographer.jpg";ImageSize mImageSize = new ImageSize(100, 100);ImageLoader.getInstance().loadImage(imageUrl, mImageSize, new SimpleImageLoadingListener(){@Overridepublic void onLoadingComplete(String imageUri, View view,Bitmap loadedImage) {super.onLoadingComplete(imageUri, view, loadedImage);mImageView.setImageBitmap(loadedImage);}});

The above is just simple to use ImageLoader to load network images. In actual development, we will not use this method. How can we use it normally? DisplayImageOptions is used. You can configure some image display options, such as the image displayed by ImageView during loading, whether memory cache is required, and whether File Cache is required, the available configurations are as follows:

DisplayImageOptions options = new DisplayImageOptions.Builder()        .showImageOnLoading(R.drawable.ic_stub) // resource or drawable        .showImageForEmptyUri(R.drawable.ic_empty) // resource or drawable        .showImageOnFail(R.drawable.ic_error) // resource or drawable        .resetViewBeforeLoading(false)  // default        .delayBeforeLoading(1000)        .cacheInMemory(false) // default        .cacheOnDisk(false) // default        .preProcessor(...)        .postProcessor(...)        .extraForDownloader(...)        .considerExifParams(false) // default        .imageScaleType(ImageScaleType.IN_SAMPLE_POWER_OF_2) // default        .bitmapConfig(Bitmap.Config.ARGB_8888) // default        .decodingOptions(...)        .displayer(new SimpleBitmapDisplayer()) // default        .handler(new Handler()) // default        .build();

We will slightly modify the above Code

Final ImageView mImageView = (ImageView) findViewById (R. id. image); String imageUrl = "https://lh6.googleusercontent.com/-55osAWw3x0Q/URquUtcFr5I/AAAAAAAAAbs/rWlj1RUKrYI/s1024/A%252520Photographer.jpg"; ImageSize mImageSize = new ImageSize (100,100); // display the image configuration DisplayImageOptions options = new DisplayImageOptions. builder (). cacheInMemory (true ). cacheOnDisk (true ). bitmapConfig (Bitmap. config. RGB_565 ). build (); ImageLoader. getInstance (). loadImage (imageUrl, mImageSize, options, new SimpleImageLoadingListener () {@ Overridepublic void onLoadingComplete (String imageUri, View, Bitmap loadedImage) {super. onLoadingComplete (imageUri, view, loadedImage); mImageView. setImageBitmap (loadedImage );}});

We have used DisplayImageOptions to configure some options for displaying images. Here I have added cache images to the memory and cached images to the file system, in this way, we don't have to worry about loading images from the network every time. Is it very convenient? However, some options in the DisplayImageOptions option are invalid for The loadImage () method, such as showImageOnLoading, showImageForEmptyUri, etc,


DisplayImage () attach an image


Next, let's take a look at the network image loading method displayImage (). The Code is as follows:

Final ImageView mImageView = (ImageView) findViewById (R. id. image); String imageUrl = "https://lh6.googleusercontent.com/-55osAWw3x0Q/URquUtcFr5I/AAAAAAAAAbs/rWlj1RUKrYI/s1024/A%252520Photographer.jpg"; // display the image configuration DisplayImageOptions = new DisplayImageOptions. builder (). showImageOnLoading (R. drawable. ic_stub ). showImageOnFail (R. drawable. ic_error ). cacheInMemory (true ). cacheOnDisk (true ). bitmapConfig (Bitmap. config. RGB_565 ). build (); ImageLoader. getInstance (). displayImage (imageUrl, mImageView, options );

From the code above, we can see that using displayImage () is much more convenient than using loadImage (). You do not need to add the ImageLoadingListener interface, and you do not need to manually set ImageView to display Bitmap objects, you can directly pass the ImageView as a parameter to displayImage (). In the image display configuration options, we add an image shown on the ImageVIew during image loading, and the image that is incorrectly displayed when the image is loaded. The effect is as follows. The ic_stub image is displayed at the beginning. If the image is successfully loaded, an error is displayed. ic_error is displayed.



This method is easy to use, and the displayImage () method will automatically crop the image based on the control size and imageScaleType. We can modify MyApplication to enable Log printing.

Public class MyApplication extends Application {@ Overridepublic void onCreate () {super. onCreate (); // create the default ImageLoader configuration Parameter ImageLoaderConfiguration = new ImageLoaderConfiguration. builder (this ). writeDebugLogs () // print log information. build (); // Initialize ImageLoader with configuration. imageLoader. getInstance (). init (configuration );}}

Let's take a look at the Log information of the slice.


The first message tells us to start loading the image, print the url of the image, and the maximum width and height of the image. The width and height of the image are the width and height of the device by default, of course, if we know the image size clearly, we can also set this size. In the options of ImageLoaderConfiguration, memoryCacheExtraOptions (int maxImageWidthForMemoryCache, int maxImageHeightForMemoryCache)

The second information shows that the picture we loaded comes from the network.

The third information shows that the original size of the image is 1024x682, Which is cropped to 512x341.

Article 4: The image is added to the memory cache. I have not added the image to the SD card, so the Log is not added to the file cache.


When loading network images, we often need to display the download progress of images. Of course, the Universal-Image-Loader also provides this function, only in displayImage () input the ImageLoadingProgressListener interface in the method. The Code is as follows:

imageLoader.displayImage(imageUrl, mImageView, options, new SimpleImageLoadingListener(), new ImageLoadingProgressListener() {@Overridepublic void onProgressUpdate(String imageUri, View view, int current,int total) {}});
Since the displayImage () method includes the ImageLoadingProgressListener parameter in all methods, the ImageLoadingListener parameter is included, so I will create a new SimpleImageLoadingListener directly, and then we can call the onProgressUpdate () method in the callback method () get the image loading progress.


Attach images from other sources


You can use the Universal-Image-Loader framework to load not only network images, but also images and Content providers in the SD card, you just need to change the image url slightly. The following figure shows the image for loading the file system.

// Display the image configuration DisplayImageOptions = new DisplayImageOptions. builder (). showImageOnLoading (R. drawable. ic_stub ). showImageOnFail (R. drawable. ic_error ). cacheInMemory (true ). cacheOnDisk (true ). bitmapConfig (Bitmap. config. RGB_565 ). build (); final ImageView mImageView = (ImageView) findViewById (R. id. image); String imagePath = "/mnt/sdcard/image.png"; String imageUrl = Scheme. FILE. wrap (imagePath); // String imageUrl = "http://img.my.csdn.net/uploads/201309/01/1378037235_7476.jpg"; imageLoader. displayImage (imageUrl, mImageView, options );
Of course, it is also very easy to use in Content provider, drawable, and assets. We only need to add Scheme packages to each image source (except Content provider ), then, the Image url is passed to imageLoader. The Universal-Image-Loader framework obtains the input stream based on different Scheme values.

// Image Source: Content providerString contentprividerUrl = "content: // media/external/audio/albumart/13"; // Image Source: assetsString assetsUrl = Scheme. ASSETS. wrap ("image.png"); // The image is from String drawableUrl = Scheme. DRAWABLE. wrap ("R. drawable. image ");


GirdView, ListView attach Images


I believe most people use the GridView and ListView to display a large number of images. When we quickly slide the GridView and ListView, we hope to stop image loading while in the GridView, when the ListView stops sliding, it loads the image of the current interface. This framework also provides this function and is easy to use. It provides the PauseOnScrollListener class to control the ListView, when the GridView slides, it stops loading images. This class uses the 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, and the second parameter is to control whether to pause loading the image during the sliding process. If you need to pause uploading true, the third parameter controls whether the image is loaded when the interface is swiped.


OutOfMemoryError


Although this framework has a good caching mechanism that effectively avoids OOM generation, the probability of OOM generation is generally small, but it cannot guarantee that OutOfMemoryError will never happen, this framework implements a simple catch for OutOfMemoryError to ensure that our program encounters OOM instead of being crash. But how can we improve it if OOM occurs frequently when we use this framework?

  • Reduce the number of threads in the thread pool. We recommend that you configure 1-5 in. threadPoolSize in ImageLoaderConfiguration.
  • In the DisplayImageOptions option, set bitmapConfig to Bitmap. Config. RGB_565 because the default value is ARGB_8888. Using RGB_565 will consume 2 times less memory than using ARGB_8888.
  • In ImageLoaderConfiguration, configure the image memory cache to memoryCache (new WeakMemoryCache () or disable the memory cache.
  • Set. imageScaleType (ImageScaleType. IN_SAMPLE_INT) or imageScaleType (ImageScaleType. EXACTLY) in the DisplayImageOptions option)

Through the above, I believe you have a good understanding of the use of the Universal-Image-Loader framework. When using this framework, we try to use the displayImage () method to load images, loadImage () is to call back the image object to the onLoadingComplete () method of the ImageLoadingListener interface. We need to manually set it to the ImageView and the displayImage () method, weak references is used for ImageView objects to facilitate the Garbage Collector to recycle ImageView objects. If we want to load images of a fixed size, we need to pass an ImageSize object using the loadImage () method, the displayImage () method will crop the Image Based on the ImageView object measurement value, or the value set by android: layout_width and android: layout_height, or the value set by android: maxWidth and/or android: maxHeight.


I will share this with you today. If you have any questions, I will leave a message below. I will try my best to answer this question. In the next article, I will continue to analyze this framework in a more in-depth manner, I hope you will continue to pay attention to it!









Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.