Android-Universal-Image-Loader详解

时间:2021-06-08 18:04:34

原地址:https://github.com/nostra13/Android-Universal-Image-Loader/wiki/Quick-Setup

下载jar包导入到你的项目中

dodola/Android-Universal-Image-Loader Git下载地址
https://github.com/nostra13/Android-Universal-Image-Loader/tree/master/downloads

Maven依赖

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

Gradle依赖(Android Studio)

compile 'com.nostra13.universalimageloader:universal-image-loader:1.9.4'

清单文件添加权限

<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>

在第一次使用imagLoader之前最好在Application或Activity类中初始化配置(推荐自定义Application)

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);
        ...
    }
}

或者

public class MyApplication extends Application {
    @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);
        ...
    }
}

使用方法

默认情况下不启用缓存,如果你想要在内存和/或磁盘缓存中加载图片,那么你应该在DisplayImageOptions中国启用缓存如下设置:

// 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

displayImage(image资源,image控件);

或者使用这个方法:

DisplayImageOptions options = new DisplayImageOptions.Builder()
        ...
        .cacheInMemory(true)
        .cacheOnDisk(true)
        ...
        .build();
ImageLoader.getInstance().displayImage(imageUrl, imageView, options); // Incoming options will be used

这个前提是你要有读写sd卡权限:

 <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

如果你经常OutOfMemoryError

  • 禁用缓存
  • 减少线程池大小配置(.threadPoolSize(…))。建议1 - 5。
  • 在显示选项使用.bitmapConfig(Bitmap.Config.RGB_565)。位图RGB_565比ARGB_8888消耗更少的内存。
  • 使用.imageScaleType(ImageScaleType.EXACTLY)
  • 使用.diskCacheExtraOptions(480、320、null)配置

内存缓存配置(ImageLoaderConfiguration.memoryCache(…))可以使用以下内容:

  • 缓存只使用强引用:LruMemoryCache(最近最少使用位图缓存大小超过限制时被删除)-默认使用
  • 缓存使用弱和强引用:
    – UsingFreqLimitedMemoryCache (最少使用的位图缓存大小超过限制时被删除)
    – LRULimitedMemoryCache (最近最少使用位图缓存大小超过限制时被删除)
    – FIFOLimitedMemoryCache (先进先出规则用于缓存大小超过限制时被删除)
    – LargestLimitedMemoryCache (最大的位图缓存大小超过限制时被删除)
    – LimitedAgeMemoryCache (当缓存的年龄超过定义的值时被删除)

  • 缓存只使用弱引用:WeakMemoryCache(无限缓存)

磁盘缓存配置(ImageLoaderConfiguration.diskCache(…))可以使用以下内容:
- UnlimitedDiscCache (最快的缓存,缓存大小没有限制)–默认
- LruDiskCache (缓存被总缓存大小和/或文件总数限制,如果缓存大小超过限制而且最近最少使用指时将被删除)
- LimitedAgeDiscCache (大小无限制缓存会被年龄限制)

显示位图(DisplayImageOptions.displayer(…))
- RoundedBitmapDisplayer (显示圆角位图)
- FadeInBitmapDisplayer (“淡入”动画显示图像)

避免列表(网格,…)滚动滞后可以使用PauseOnScrollListener:

boolean pauseOnScroll = false; // or true
boolean pauseOnFling = true; // or false
PauseOnScrollListener listener = new PauseOnScrollListener(imageLoader, pauseOnScroll, pauseOnFling);
listView.setOnScrollListener(listener);

配置

配置最好全局设置到自定的application中:

配置分句解读:

memoryCacheExtraOptions(int maxImageWidthForMemoryCache, int maxImageHeightForMemoryCache) 
//在内存缓存时解码图像的最大图像宽高
taskExecutor(Executor executor)
//设置自定义任务加载图片,如果使用自定以下配置不会被考虑
//threadPoolSize(int)
//threadPriority(int)
//tasksProcessingOrder(QueueProcessingType)
discCacheExtraOptions(int maxImageWidthForDiskCache, int maxImageHeightForDiskCache,
                BitmapProcessor processorForDiskCache)
//在磁盘缓存之前对已下载的图片进行压缩调整大小处理(它会让你的imageloader变慢,酌情使用它)
taskExecutorForCachedImages(Executor executorForCachedImages)
//自定义任务缓存在磁盘上的图片,这个任务执行很快。使用它的话以下配置不会被考虑
//threadPoolSize(int)
//threadPriority(int)
//tasksProcessingOrder(QueueProcessingType)
threadPoolSize(int threadPoolSize)
//为图像显示任务设置线程池大小,默认是3
threadPriority(int threadPriority)
//设置图像加载线程的优先级
denyCacheImageMultipleSizesInMemory()
//同一个图片的缓存会因为尺寸的使用不一而拥有多个缓存,这个方法用于否定这样的行为,新的缓存会替换过去的缓存
tasksProcessingOrder(QueueProcessingType tasksProcessingType)
//设置以队列处理类型来加载图片,默认是先进先出类型
memoryCacheSize(int memoryCacheSize)
//设置最大内存缓存大小,默认值是可用应用程序内存的1/8,如果你使用这个方法,LruMemoryCache会作为内存缓存使用
memoryCacheSizePercentage(int availableMemoryPercent)
//以百分比设置最大内存缓存大小,0<availableMemoryPercent<100
//memoryCacheSize = (int) (availableMemory * (availableMemoryPercent / 100f));
memoryCache(MemoryCache memoryCache)
//为bitmap设置内存缓存,默认值LruMemoryCache大小为可用应用程序内存的1/8。如果你用它,则memoryCacheSize(int)不可用
discCacheSize(int maxCacheSize)
//不赞成使用,已经被diskCacheSize(int)取代
diskCacheSize(int maxCacheSize)
//设置最大磁盘缓存大小,默认是无限制,如果你使用这个方法,LruDiskCache会作为磁盘缓存使用
discCacheFileCount(int maxFileCount)
//不推荐使用,已被diskCacheFileCount(int)替换
diskCacheFileCount(int maxFileCount)
//在磁盘高速缓存目录中设置最大文件数,默认无限制,如果你使用这个方法,LruDiskCache会作为磁盘缓存使用
discCacheFileNameGenerator(FileNameGenerator fileNameGenerator)
//不推荐使用,已被diskCacheFileNameGenerator(FileNameGenerator fileNameGenerator)替换
diskCacheFileNameGenerator(FileNameGenerator fileNameGenerator)
//为磁盘缓存设置文件名字生成器
discCache(DiskCache diskCache)
//不推荐使用,已被diskCache(DiskCache diskCache)替换
diskCache(DiskCache diskCache)
//谁知磁盘缓存,默认无限制,缓存目录通过getCacheDirectory(Context)定义
//如果你设置自定义磁盘缓存,以下配置不可用
/** * diskCacheSize(int) * diskCacheFileCount(int) * diskCacheFileNameGenerator(FileNameGenerator) **/
imageDownloader(ImageDownloader imageDownloader)
//设置负责下载图片功能的对象
imageDecoder(ImageDecoder imageDecoder)
//设置负责解析图片流功能的对象
defaultDisplayImageOptions(DisplayImageOptions defaultDisplayImageOptions)
//设置默认的图片显示选项
writeDebugLogs()
//允许记录工作细节
/** Builds configured {@link ImageLoaderConfiguration} object */
public ImageLoaderConfiguration build() {
    initEmptyFieldsWithDefaultValues();
    return new ImageLoaderConfiguration(this);
}

initEmptyFieldsWithDefaultValues();

举例

// 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 = 设备屏幕的尺寸
        .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 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();

这些配置的java代码点此查看.

显示选项

分句解读:

showStubImage(int imageRes)
//被showImageOnLoading(int)替代
showImageOnLoading(int imageRes)
showImageOnLoading(Drawable drawable)
//设置在图像加载的时候显示的图片
showImageForEmptyUri(int imageRes)
//设置当图片URI为空或空字符串时显示的图片
showImageOnFail(int imageRes)
showImageOnFail(Drawable drawable)
//设置当有些错误发生在图片解析或者下载时显示的图像
resetViewBeforeLoading()
//被resetViewBeforeLoading(boolean)替代
 resetViewBeforeLoading(boolean resetViewBeforeLoading)
 //在图片加载前ImageAware 是否能够被重置,即图片的宽高资源缩放类型等。

ImageAware 点击查看。

cacheInMemory(boolean cacheInMemory)
//设置图像是否会缓存在内存中
cacheOnDisc(boolean cacheOnDisk)
//设置图像时否会缓存在磁盘上
imageScaleType(ImageScaleType imageScaleType)
//为解析图像设置缩放类型,默认是ImageScaleType#IN_SAMPLE_POWER_OF_2

ImageScaleType 参数:

  • NONE —-不缩放
  • NONE_SAFE —-只有在图片大于最大可接受的纹理大小(2048x2048)时才缩放
  • IN_SAMPLE_POWER_OF_2—-图片以折半的方式缩小直到小于目标大小
  • IN_SAMPLE_INT—-图像将以一个整数的次数(1、2、3、…)进行二次抽样
  • EXACTLY—-图像缩小尺寸刚好到目标大小(按比例缩小的宽度或高度将等于目标大小,依赖缩放类型)
    –注意:如果原始图片尺寸小于目标尺寸将不会缩放
  • EXACTLY_STRETCHED—-图像缩小尺寸刚好到目标大小(按比例缩小的宽度或高度将等于目标大小,依赖缩放类型)
    –注意:如果原始图片尺寸小于目标尺寸,原始图片将会拉伸至目标尺寸
bitmapConfig(Bitmap.Config bitmapConfig)
//为图片解析设置位图配置,默认Bitmap.Config#ARGB_8888
decodingOptions(Options decodingOptions)
//设置图像解码选项
delayBeforeLoading(int delayInMillis) 
//开始加载图像前的延迟,默认无延迟
extraForDownloader(Object extra)
//设置辅助对象将被传递给ImageDownloader#getStream(String, Object)
considerExifParams(boolean considerExifParams)
//设置ImageLoader是否会考虑JPEG图像的EXIF参数(旋转、翻转)
preProcessor(BitmapProcessor preProcessor)
//设置在图片被缓存在内存之前的bitmap处理器,因此内存缓存会通过传入的预处理器包含bitmap处理器。
//图像会被预处理即使内存不被允许缓存
postProcessor(BitmapProcessor postProcessor)
//设置图片被显示之前的bitmap处理器,设置之后它们就已经被存储在内存缓存了
displayer(BitmapDisplayer displayer)
//为图片加载任务设置自定义显示器
handler(Handler handler) //设置自定义显示图像和发射事件侦听器

举例

// 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();

sample

自定义application

public class MyApplication extends Application {
    @Override
    public void onCreate() {
        super.onCreate();

        DisplayImageOptions defaultOptions = new DisplayImageOptions.Builder()  
        .cacheInMemory().cacheOnDisc().build();  


        ImageLoaderConfiguration config = new ImageLoaderConfiguration.Builder(  
                getApplicationContext()).defaultDisplayImageOptions(defaultOptions)  
                .threadPriority(Thread.NORM_PRIORITY - 2)  
                .denyCacheImageMultipleSizesInMemory()  
                .discCacheFileNameGenerator(new Md5FileNameGenerator())  
                .tasksProcessingOrder(QueueProcessingType.LIFO).build();  
        ImageLoader.getInstance().init(config);   
    }
}

如下使用:

ImageView imageView = new ImageView(CebMainActivity.this);
imageView.setScaleType(ScaleType.FIT_XY);
ImageLoader.getInstance().displayImage(getImage(), imageView); 

Library Map

ImageLoader |
| - init(ImageLoaderConfiguration)
| - isInited()
| - displayImage(…)
| - loadImage(…)
| - loadImageSync(…)
| - getMemoryCache()
| - clearMemoryCache()
| - getDiskCache()
| - clearDiskCache()
| - denyNetworkDownloads(boolean)
| - handleSlowNetwork(boolean)
| - pause()
| - resume()
| - stop()
| - destroy()
| - getLoadingUriForView(ImageView)
| - cancelDisplayTask(ImageView)

ImageAware |
| - getId()
| - getWidth()
| - getHeight()
| - getScaleType()
| - getWrappedView()
| - isCollected()
| - setImageDrawable(Drawable)
| - setImageBitmap(Bitmap)

MemoryCacheUtil |
| - findCachedBitmapsForImageUri(…)
| - findCacheKeysForImageUri(…)
| - removeFromCache(…)

DiskCacheUtil |
| - findInCache(…)
| - removeFromCache(…)

StorageUtils |
| - getCacheDirectory(Context)
| - getIndividualCacheDirectory(Context)
| - getOwnCacheDirectory(Context, String)

ImageScaleType | NONE
| IN_SAMPLE_POWER_OF_2
| IN_SAMPLE_INT
| EXACTLY
| EXACTLY_STRETCHED

QueueProcessingType | FIFO
| LIFO

FailReason.FailType | IO_ERROR
| DECODING_ERROR
| NETWORK_DENIED
| OUT_OF_MEMORY
| UNKNOWN

ImageLoadingListener | | | -
onLoadingStarted(String, View) | | -
onLoadingFailed(String, View, FailReason) | | -
onLoadingComplete(String, View, Bitmap) | | -
onLoadingCancelled(String, View) |—- SimpleImageLoadingListener

ImageDownloader |—- BaseImageDownloader |—-
NetworkDeniedImageDownloader |—- SlowNetworkImageDownloader

ImageDecoder |—- BaseImageDecoder

BitmapDisplayer |—- SimpleBitmapDisplayer |—-
FadeInBitmapDisplayer |—- RoundedBitmapDisplayer |—-
RoundedVignetteBitmapDisplayer

DiskCache |—- BaseDiscCache
|—- UnlimitedDiscCache
|—- LruDiskCache
|—- LimitedAgeDiscCache

MemoryCacheAware |—- BaseMemoryCache | |—- WeakMemoryCache |
|—- LimitedMemoryCache | |—- UsingFreqLimitedMemoryCache
| |—- LRULimitedMemoryCache | |—-
LargestLimitedMemoryCache | |—- FIFOLimitedMemoryCache
|—- LimitedAgeMemoryCache |—- LruMemoryCache

FileNameGenerator |—- HashCodeFileNameGenerator |—-
Md5FileNameGenerator

PauseOnScrollListener