(源代码分析)Android-Universal-Image-Loader (图片异步载入缓存库)的使用配置

转载请注明出处:http://blog.csdn.net/u011733020

前言:

在Android开发中,对于图片的载入能够说是个老生常谈的问题了,图片载入是一个比較坑的地方。处理不好,会有各种奇怪的问题,比方 载入导致界面卡顿。程序crash。

因此 怎样高效的载入大量图片。以及怎样载入大分辨率的图片到内存。是我们想要开发一款优质app时不得不去面对与解决的问题。

通常开发中,我们仅仅有两种选择:① 使用开源框架  ②自己去实现处理图片的载入与缓存。

通常一開始让我们自己去写,我们会无从下手,因此先去分析一下开源的思路,对我们的成长非常有必要。

眼下使用频率较高的图片缓存框架有  Universal-Image-Loader、android-Volley、Picasso、Fresco和Glide五大Android开源组件。

首先排除android-Volley 孰优孰劣,后面再去验证。剩下的四种对于 图片载入缓存的思想,从慷慨向上应该是相似的

而Android-Universal-Image-Loader(UIL for short)作为一款比較经典的框架,从早期到如今一直都比較常见,这里就拿UIL来看一下它对图片处理的思想,然后设置写一下自己的imagloader,本文首先介绍一下UIL的基本信息。

正文:

在本文中先介绍一下UIL在Github上的使用介绍。

UIL 在github上的地址https://github.com/nostra13/Android-Universal-Image-Loader 遗憾的是作者在2015.11月已经声明不在维护更新了。

UIL的介绍:Powerful and flexible library for loading, caching and displaying images on Android(高效灵活的载入、缓存以及展示图片)。

以下看一下详细怎么用

Quick Setup

1. Include library

Manual:

  • Download JAR
  • Put the JAR in the libs subfolder of your Android project

or

Maven dependency:

<dependency>
    <groupId>com.nostra13.universalimageloader</groupId>
    <artifactId>universal-image-loader</artifactId>
    <version>1.9.5</version>
</dependency>

or

Gradle dependency:

compile ‘com.nostra13.universalimageloader:universal-image-loader:1.9.5‘

2. Android Manifest

<manifest>
    <!-- Include following permission if you load images from Internet -->
    <uses-permission android:name="android.permission.INTERNET" />
    <!-- Include following permission if you want to cache images on SD card -->
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    ...
</manifest>

3. Application or Activity class (before the first usage of ImageLoader)

public class MyActivity extends Activity {
    @Override
    public void onCreate() {
        super.onCreate();

        // Create global configuration and initialize ImageLoader with this config
        ImageLoaderConfiguration config = new ImageLoaderConfiguration.Builder(this)
            ...
            .build();
        ImageLoader.getInstance().init(config);
        ...
    }
}

Configuration

ImageLoader Configuration (ImageLoaderConfiguration) is global for application. You should set it once.

All options in Configuration builder are optional. Use only those you really want to customize.
See default values for config options in Java docs for every option.

// DON‘T COPY THIS CODE TO YOUR PROJECT! This is just example of ALL options using.
// See the sample project how to use ImageLoader correctly.
File cacheDir = StorageUtils.getCacheDirectory(context);
ImageLoaderConfiguration config = new ImageLoaderConfiguration.Builder(context)
        .memoryCacheExtraOptions(480, 800) // default = device screen dimensions
        .diskCacheExtraOptions(480, 800, null)
        .taskExecutor(...)
        .taskExecutorForCachedImages(...)
        .threadPoolSize(3) // default
        .threadPriority(Thread.NORM_PRIORITY - 2) // default
        .tasksProcessingOrder(QueueProcessingType.FIFO) // default
        .denyCacheImageMultipleSizesInMemory()
        .memoryCache(new LruMemoryCache(2 * 1024 * 1024))
        .memoryCacheSize(2 * 1024 * 1024)
        .memoryCacheSizePercentage(13) // default
        .diskCache(new UnlimitedDiskCache(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();

Display Options

Display Options (DisplayImageOptions) are local for every display task (ImageLoader.displayImage(...)).

Display Options can be applied to every display task (ImageLoader.displayImage(...) call).

Note: If Display Options wasn‘t passed to ImageLoader.displayImage(...)method then default Display Options from configuration (ImageLoaderConfiguration.defaultDisplayImageOptions(...)) will be used.

// DON‘T COPY THIS CODE TO YOUR PROJECT! This is just example of ALL options using.
// See the sample project how to use ImageLoader correctly.
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();

Useful Info

  1. Caching is NOT enabled by default. If you want loaded images to be cached in memory and/or on disk then you should enable caching in DisplayImageOptions this way:

    // Create default options which will be used for every
    //  displayImage(...) call if no options will be passed to this method
    DisplayImageOptions defaultOptions = new DisplayImageOptions.Builder()
            ...
            .cacheInMemory(true)
            .cacheOnDisk(true)
            ...
            .build();
    ImageLoaderConfiguration config = new ImageLoaderConfiguration.Builder(getApplicationContext())
            ...
            .defaultDisplayImageOptions(defaultOptions)
            ...
            .build();
    ImageLoader.getInstance().init(config); // Do it on Application start
    // Then later, when you want to display image
    ImageLoader.getInstance().displayImage(imageUrl, imageView); // Default options will be used

    or this way:

    DisplayImageOptions options = new DisplayImageOptions.Builder()
            ...
            .cacheInMemory(true)
            .cacheOnDisk(true)
            ...
            .build();
    ImageLoader.getInstance().displayImage(imageUrl, imageView, options); // Incoming options will be used
  2. If you enabled disk caching then UIL try to cache images on external storage (/sdcard/Android/data/[package_name]/cache). If external storage is not available then images are cached on device‘s filesystem. To provide caching on external storage (SD card) add following permission to AndroidManifest.xml:
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" android:maxSdkVersion="18" />
  3. How UIL define Bitmap size needed for exact ImageView?

    It searches defined parameters:

    • Get actual measured width and height of ImageView
    • Get android:layout_width and android:layout_height parameters
    • Get android:maxWidth and/or android:maxHeight parameters
    • Get maximum width and/or height parameters from configuration (memoryCacheExtraOptions(int, int) option)
    • Get width and/or height of device screen

    So try to set android:layout_width|android:layout_height orandroid:maxWidth|android:maxHeight parameters for ImageView if you know approximate maximum size of it. It will help correctly compute Bitmap size needed for this view and save memory.

  4. If you often got OutOfMemoryError in your app using Universal Image Loader then:
    • Disable caching in memory. If OOM is still occurs then it seems your app has a memory leak. Use MemoryAnalyzer to detect it. Otherwise try the following steps (all of them or several):
    • Reduce thread pool size in configuration (.threadPoolSize(...)). 1 - 5 is recommended.
    • Use .bitmapConfig(Bitmap.Config.RGB_565) in display options. Bitmaps in RGB_565 consume 2 times less memory than in ARGB_8888.
    • Use .imageScaleType(ImageScaleType.EXACTLY)
    • Use .diskCacheExtraOptions(480, 320, null) in configuration
  5. For memory cache configuration (ImageLoaderConfiguration.memoryCache(...)) you can use already prepared implementations.
    • Cache using only strong references:

      • LruMemoryCache (Least recently used bitmap is deleted when cache size limit is exceeded) - Used by default
    • Caches using weak and strong references:
      • UsingFreqLimitedMemoryCache (Least frequently used bitmap is deleted when cache size limit is exceeded)
      • LRULimitedMemoryCache (Least recently used bitmap is deleted when cache size limit is exceeded)
      • FIFOLimitedMemoryCache (FIFO rule is used for deletion when cache size limit is exceeded)
      • LargestLimitedMemoryCache (The largest bitmap is deleted when cache size limit is exceeded)
      • LimitedAgeMemoryCache (Decorator. Cached object is deleted when its age exceeds defined value)
    • Cache using only weak references:
      • WeakMemoryCache (Unlimited cache)
  6. For disk cache configuration (ImageLoaderConfiguration.diskCache(...)) you can use already prepared implementations:
    • UnlimitedDiscCache (The fastest cache, doesn‘t limit cache size) - Used by default
    • LruDiskCache (Cache limited by total cache size and/or by file count. If cache size exceeds specified limit then least-recently used file will be deleted)
    • LimitedAgeDiscCache (Size-unlimited cache with limited files‘ lifetime. If age of cached file exceeds defined limit then it will be deleted from cache.)

    NOTE: UnlimitedDiscCache is pretty faster than other limited disk cache implementations.

  7. To display bitmap (DisplayImageOptions.displayer(...)) you can use already prepared implementations:
    • RoundedBitmapDisplayer (Displays bitmap with rounded corners)
    • FadeInBitmapDisplayer (Displays image with "fade in" animation)
  8. To avoid list (grid, ...) scrolling lags you can use PauseOnScrollListener:
    boolean pauseOnScroll = false; // or true
    boolean pauseOnFling = true; // or false
    PauseOnScrollListener listener = new PauseOnScrollListener(imageLoader, pauseOnScroll, pauseOnFling);
    listView.setOnScrollListener(listener);
  9. If you see in logs some strange supplement at the end of image URL (e.g.http://anysite.com/images/image.png_230x460) then it doesn‘t mean this URL is used in requests. This is just "URL + target size", also this is key for Bitmap in memory cache. This postfix (_230x460) is NOT used in requests.
  10. ImageLoader always keeps aspect ratio of images.

以上都是UIL在Github的 readme 中提到的使用。以及注意事项,当遇到问题是,先在useful info中看能否找到答案,然后在去找其它解决方式。

将UIL加入到我们的工程中仅仅须要以下三步就可以:

1.下载lib 导入到目标工程。

2.manifest 文件里加入权限。

3.在application 中进行UIL的初始化配置。

然后通过 displayImage(String uri, ImageView imageView) 进行载入图片使用。

UIL特点介绍:

能够通过配置显示圆角图片。

支持多种网络情况下的 载入机制。
  仅仅须要传递一个url 就可以(网络、本地都能够)。

将要显示的图片url 与View绑定,避免了图片错位这样的现象。
  使用线程池管理任务线程:既保证载入效率,也保证了优化app性能。

设置本地缓存路径。方便后期查看管理缓存文件(清空本地缓存)。
  载入高分辨率的图片。自己主动改变bitmap分辨率,降低内存占用防止oom。
  支持特殊情况比方滑动过程中暂停载入,停止滑动后,在载入,保证了载入当前页面的效率。
  能够加入下载过程的监听,能够设置下载中的默认图片背景,下载完毕后。能够选择显示图片的动画。

实际项目中使用:

以下是在项目中使用的详细介绍:

1.在Application中进行init:

	public static void initImageLoader(Context context) {

		ImageLoaderConfiguration config = new ImageLoaderConfiguration.Builder(
				context)
				.threadPriority(Thread.NORM_PRIORITY + 2)
				.denyCacheImageMultipleSizesInMemory()
				.threadPoolSize(10)
				.discCacheFileNameGenerator(new Md5FileNameGenerator())
				.tasksProcessingOrder(QueueProcessingType.LIFO)
				.diskCache(
						new UnlimitedDiskCache(new File(ApplicationData
								.getPicDir())))
				.memoryCache(new LRULimitedMemoryCache(2 * 1024 * 1024))
				.build();

		ImageLoader.getInstance().init(config);
	}

2.在要显示图片的地方,比方ListView、GridView的Adapter的getView() 方法中:

    imageLoader.displayImage(url, shower, roundShapeOption) ; 

而且能够动态传入 须要的option:

options = new DisplayImageOptions.Builder()
		.showStubImage(R.drawable.trans_pic)
		.showImageForEmptyUri(R.drawable.trans_pic)
		.showImageOnFail(R.drawable.trans_pic)
		.delayBeforeLoading(IMG_LOAD_DELAY)
		.cacheInMemory(true)
		.cacheOnDisc(true)
		.bitmapConfig(Bitmap.Config.RGB_565)	 //设置图片的解码类型
		.build();

怎样在低内存手机上降低OOM的概率:

在低内存的手机上建议以下配置:

对ImageLoaderConfiguration 參数的设置:

降低配置之中线程池的大小(threadPoolSize)

对DisplayImageOptions  參数设置:

imageScaleType(ImageScaleType.IN_SAMPLE_INT)或者        try.imageScaleType(ImageScaleType.EXACTLY)。

.bitmapConfig(Bitmap.Config.RGB_565) //默认是ARGB_8888,使用RGB_565会比使用ARGB_8888少消耗2倍的内。

避免使用RoundedBitmapDisplayer.他会创建新的ARGB_8888格式的Bitmap对象。

使用.memoryCache(new WeakMemoryCache()),不要使用.cacheInMemory()。

依据url 的来源:
  http://site.com/image.png // from Web
  file:///mnt/sdcard/image.png // from SD card
  file:///mnt/sdcard/video.mp4 // from SD card (video thumbnail)
  content://media/external/images/media/13 // from content provider
  content://media/external/video/media/13 // from content provider (video thumbnail)
  assets://image.png // from assets
  drawable:// + R.drawable.img // from drawables (non-9patch images)

file:///storage/emulated/0/UIL/Document/pics/aaa.jpg

手机版本号不一致,可能也不一样 ,详细还是要自己灵活区分。

很多其它配置參考:http://www.yq1012.com/android/2053.html 。

本文主要介绍 UIL的基本接入以及 使用配置,有关载入过程,缓存过程,请看下一篇 Android-Universal-Image-Loader (图片异步载入缓存库)的源代码解读

谢谢认真观读本文的每一位小伙伴。衷心欢迎小伙伴给我指出文中的错误,也欢迎小伙伴与我交流学习。

欢迎爱学习的小伙伴加群一起进步:230274309 。

时间: 2024-10-25 20:43:33

(源代码分析)Android-Universal-Image-Loader (图片异步载入缓存库)的使用配置的相关文章

Android Universal Image Loader 使用

1. 功能介绍 1.1 Android Universal Image Loader Android Universal Image Loader 是一个强大的.可高度定制的图片缓存,本文简称为UIL. 简单的说 UIL 就做了一件事--获取图片并显示在相应的控件上. 1.2 基本使用 1.2.1 初始化 添加完依赖后在Application或Activity中初始化ImageLoader,如下: public class YourApplication extends Application

Android Universal Image Loader java.io.FileNotFoundException: http:/xxx/lxx/xxxx.jpg

前段时间在使用ImageLoader异步加载服务端返回的图片时总是出现 java.io.FileNotFoundException: http://xxxx/l046/10046137034b1c0db0.jpg at libcore.net.http.HttpURLConnectionImpl.getInputStream(HttpURLConnectionImpl.java:177) at com.nostra13.universalimageloader.core.download.URL

Android Universal Image Loader 架构剖析

简介 Android Universal Image Loader简称UIL, 其github链接https://github.com/nostra13/Android-Universal-Image-Loader, 它用于Android应用中的图片加载(从网络,本地文件,或资源文件),本地缓存(内存和磁盘), 以及展示在ImageView中. 示例 整体框架 各模块的流程图 Task流程: 下载流程: decode流程: cache流程: 主要类图:

自己动手写android图片异步加载库(二)

在<自己动手写android图片异步加载库>系列的第一篇文章中,主要是学习了使用ReferenceQueue来实现一个内存缓存.在这篇文章中主要是介绍在下载很多图片是怎么控制线程和队列.在这版代码里,加入信号量和队列,可以控制下载任务的顺序.可以控制暂停和结束. 代码A:ImageLoader.java /** * 图片加载工具类 * * @author qingtian * @blog http://blog.csdn.net/bingoSpunky */ @SuppressLint(&qu

android:强大的图片下载和缓存库Picasso

1.Picasso简介 Picasso是Square公司出品的一个强大的图片下载和缓存图片库.官方网址是:http://square.github.io/picasso/ 只需要一句代码就可以将图片下载并设置到ImageView上. Picasso.with(context).load("http://i.imgur.com/DvpvklR.png").into(imageView); 2.主要特点 2.1Adapter downloads 使用ListView,GridView的时候

BitmapCache-master图片异步下载缓存

BitmapCache-master图片异步下载缓存 实现图片下载和缓存功能,可以将图片下载之后缓存到内存或者SD卡中.图片第一次从互联网下载之后,就会缓存到内存或者SD卡中.第二次再打开浏览时,就无需再从互联网下载,而是直接从内存或者SD卡中读取. 效果图说:第一幅图是第一次打开应用,所有图片都来自互联网,第二幅图是第二次打开应用,可以看到部分图片来自缓存,部分图片来自互联网. 下载地址:http://www.devstore.cn/code/info/903.html 运行截图:  

MapleBacon 是一个非常棒的图片下载和缓存库

http://www.oschina.net/ios/codingList/367/ios-image http://www.oschina.net/p/maplebacon MapleBacon 是一个非常棒的图片下载和缓存库,使用 Swift 开发,用于 iOS 系统. 示例代码: import MapleBacon @IBOutlet weak var imageView: UIImageView! if let imageURL = NSURL(string: "something.jp

Universal Image Loader_图片异步加载

Universal Image Loader 是一个开源的UI组件程序,该项目的目的是提供一个可重复使用的仪器为异步图像加载,缓存和显示.所以,如果你的程序里需要这个功能的话,那么不妨试试它.他本来是基于Fedor Vlasov's project 项目的,Universal Image Loader在此基础上做了很多修改. 下面是Universal Image Loader官方的说明文档: 开发安卓应用的过程中往往与遇到需要显示网络图片的情形.其实,在手机设备有限的内存空间和处理能力限制下,写

自己动手写android图片异步加载库

尊重他人劳动成果,转载请说明出处:http://blog.csdn.net/bingospunky/article/details/44344085 接触android有半年了,关于图片异步加载,一直只用别人的框架,虽然特别方便,但是始终未见识到图片异步加载的庐山真面目.最近比较悠闲,研究一些高大上的东西.在这篇文章总结一下我对图片异步加载的一些学习心得. 图片加载最重要的无非就是内存和线程.大家都知道关于内存溢出一般的解决方案就是LruCache,在我的这个demo里我只要使用SoftRefe