转载请注明出处: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 。

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

  1. android universal image loader 缓冲原理详解

    1. 功能介绍 1.1 Android Universal Image Loader Android Universal Image Loader 是一个强大的.可高度定制的图片缓存,本文简称为UIL ...

  2. Android图片异步载入框架Android-Universal-Image-Loader

    Android-Universal-Image-Loader是一个图片异步载入,缓存和显示的框架.这个框架已经被非常多开发人员所使用,是最经常使用的几个Android开源项目之中的一个,主流的应用,随 ...

  3. Jetpack Compose学习(4)——Image(图片)使用及Coil图片异步加载库使用

    原文地址 Jetpack Compose学习(4)--Image(图片)使用及Coil图片异步加载库使用 | Stars-One的杂货小窝 本篇讲解下关于Image的使用及使用Coil开源库异步加载网 ...

  4. lazyload.js实现图片异步载入

    所谓图片异步加载,意思是不用一次把图片全部加载完,你可以叫它延迟加载,缓冲加载都行. 看看你有没有这种需求:某篇文章图片很多,如果在载入文章时就载入所有图片,无疑会延缓载入速度,让用户等更久,所以,我 ...

  5. Universal Image Loader_图片异步加载

    Universal Image Loader 是一个开源的UI组件程序,该项目的目的是提供一个可重复使用的仪器为异步图像加载,缓存和显示.所以,如果你的程序里需要这个功能的话,那么不妨试试它.他本来是 ...

  6. MonkeyRunner源代码分析Android通信设备

    正如前面<谁动了我的截图?--Monkeyrunner takeSnapshot方法源代码跟踪分析>所述,本文主要会尝试描写叙述android的自己主动化測试框架MonkeyRunner到 ...

  7. ImageLoader实现图片异步载入

    ImageLoader是一个广泛使用的图片库,在向网络请求图片时.使用imageView和smartView常会产生outofmemory错误,这时ImageLoader能够起到非常大的作用.主要有例 ...

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

    1.Picasso简单介绍 Picasso是Square公司出品的一个强大的图片下载和缓存图片库.官方网址是:http://square.github.io/picasso/ 仅仅须要一句代码就能够将 ...

  9. Android 使用图片异步载入框架Universal Image Loader的问题

    使用的Jar包 问题:        optionsm = new DisplayImageOptions.Builder()         .displayer(new RoundedBitmap ...

随机推荐

  1. python 内置2to3工具将python2代码转换为python3代码

    python2与python3代码不兼容,如果需要python2代码在python3环境下运行,需要将代码进行转换,本文介绍使用python3内置工具2to3.py对代码进行转换 一:2to3.py在 ...

  2. 【计算机网络】3.2 无连接运输:UDP

    第三章第二节 无连接运输:UDP UDP(用户数据报协议,User Datagram Protocol),它只是做了运输层协议能够做的最少工作,除了多路复用和多路分解及一些差错检测外,它几乎没有做任何 ...

  3. js 技巧 (八)JS代码判断集锦(之二)

    JS代码判断集锦(之二) <INPUT TYPE="button" value="登录"  tabindex="4"> < ...

  4. python3.x Day6 paramiko

    python3 paramiko模块,用来进行远程操作linux服务器,利用的就是ssh #利用用户名,密码,进行连接 import paramiko #创建一个SSH对象 ssh=paramiko. ...

  5. Buffer.alloc()

    Buffer.alloc(size[, fill[, encoding]]) Node.js FS模块方法速查 size {Number} fill {Value} 默认:undefined enco ...

  6. MySQL-----连表

    连表: **拿到两张表的信息** select * from userinfo,department 弊端是数据会乱,出现重复,不建议这样. **使userinfo表的part_id列与departm ...

  7. Atcoder regular Contest 073(C - Sentou)

    Atcoder regular Contest 073(C - Sentou) 传送门 每个人对开关的影响区间为a[i]--a[i]+t,因此此题即为将所有区间离散化后求所有独立区间的长度和 #inc ...

  8. 关于必须添加对程序集“System.Runtime, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a”的引用异常问题

    问题描述: 下午调试代码的时候突然发现页面突然异常了,原本以为是代码哪里写错了,后来通过定位发现MVC,UI界面的Linq异常,即关于必须添加对程序集“System.Runtime, Version= ...

  9. 任务3.站会或DoD

    三选一 1.为开展敏捷团队:尝试一下引入站会 2.正在实践敏捷团队:定义DoD 3.从本次和上次学习中自己找出一个任务 <我们知道何时才算完成> <富有成效的每日站会> 目前所 ...

  10. SPOJ-BRCKTS (括号序列,线段树)

    维护括号序列 Replace(i): 将第i个位置的括号反向. Check:测试当前序列是否合法. 题解 将左括号定为1,右括号定为-1,所以只需要满足前缀和序列没有负数即可,即最小值 为正即可,第i ...