使用universalimageloader初始化内存溢出怎么解决

您所在的位置: &
Android开发中如何解决加载大图片时内存溢出的问题
Android开发中如何解决加载大图片时内存溢出的问题
CrazyBirds
eoe Android开发者社区
在Android开发过程中,我们经常会遇到加载的图片过大导致内存溢出的问题,其实类似这样的问题已经屡见不鲜了,下面将一些好的解决方案分享给大家。
尽量不要使用setImageBitmap或setImageResource或BitmapFactory.decodeResource来设置一张大图,因为这些函数在完成decode后,最终都是通过java层的createBitmap来完成的,需要消耗更多内存。
因此,改用先通过BitmapFactory.decodeStream方法,创建出一个bitmap,再将其设为ImageView的
source,decodeStream最大的秘密在于其直接调用JNI&&nativeDecodeAsset()来完成decode,无需再使用java层的createBitmap,从而节省了java层的空间。
如果在读取时加上图片的Config参数,可以跟有效减少加载的内存,从而跟有效阻止抛out of
Memory异常,另外,decodeStream直接拿的图片来读取字节码了, 不会根据机器的各种分辨率来自动适应,
使用了decodeStream之后,需要在hdpi和mdpi,ldpi中配置相应的图片资源,
否则在不同分辨率机器上都是同样大小(像素点数量),显示出来的大小就不对了。
另外,以下方式也大有帮助:
InputStream&is&=&this.getResources().openRawResource(R.drawable.pic1);&&&&&&BitmapFactory.Options&options=new&BitmapFactory.Options();&&&&&&options.inJustDecodeBounds&=&false;&&&&&&options.inSampleSize&=&10;&&&&&&&&&Bitmap&btp&=BitmapFactory.decodeStream(is,null,options);&&&if(!bmp.isRecycle()&){&&&&&&&&&&bmp.recycle()&&&&&&&&&&&&&system.gc()&&&}&&&
以下奉上一个方法:
&&&&&&&&&&&&&&public&static&Bitmap&readBitMap(Context&context,&int&resId){&&&&BitmapFactory.Options&opt&=&new&BitmapFactory.Options();&&&&opt.inPreferredConfig&=&Bitmap.Config.RGB_565;&&&&opt.inPurgeable&=&true;&&&&opt.inInputShareable&=&true;&&&&&&&&InputStream&is&=&context.getResources().openRawResource(resId);&&&&return&BitmapFactory.decodeStream(is,null,opt);&&&&}&
================================================================================&Android内存溢出的解决办法&&转自:http:&&昨天在模拟器上给gallery放入图片的时候,出现java.lang.OutOfMemoryError:&bitmap&size&exceeds&VM&budget&异常,图像大小超过了RAM内存。&&&&&&&&模拟器RAM比较小,只有8M内存,当我放入的大量的图片(每个100多K左右),就出现上面的原因。&由于每张图片先前是压缩的情况,放入到Bitmap的时候,大小会变大,导致超出RAM内存,具体解决办法如下:&&```java&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&BitmapFactory.Options&opts&=&new&BitmapFactory.Options();&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&opts.inSampleSize&=&4;&&&&&&&&&&&&&&&&&Bitmap&bmp&=&null;&&&&&&&&&&&&&&&&&bmp&=&BitmapFactory.decodeResource(getResources(),&mImageIds[position],opts);&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&...&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&bmp.recycle();&&&&
通过上面的方式解决了,但是这并不是最完美的解决方式。
通过一些了解,得知如下:
优化Dalvik虚拟机的堆内存分配
对于Android平台来说,其托管层使用的Dalvik
JavaVM从目前的表现来看还有很多地方可以优化处理,比如我们在开发一些大型游戏或耗资源的应用中可能考虑手动干涉GC处理,使用dalvik.system.VMRuntime类提供的setTargetHeapUtilization方法可以增强程序堆内存的处理效率。当然具体原理我们可以参考开源工程,这里我们仅说下使用方法:
private final static floatTARGET_HEAP_UTILIZATION = 0.75f;
在程序onCreate时就可以调用VMRuntime.getRuntime().setTargetHeapUtilization(TARGET_HEAP_UTILIZATION);即可。
Android堆内存也可自己定义大小
对于一些Android项目,影响性能瓶颈的主要是Android自己内存管理机制问题,目前手机厂商对RAM都比较吝啬,对于软件的流畅性来说RAM对性能的影响十分敏感,除了
优化Dalvik虚拟机的堆内存分配外,我们还可以强制定义自己软件的对内存大小,我们使用Dalvik提供的dalvik.system.VMRuntime类来设置最小堆内存为例:
private final static int CWJ_HEAP_SIZE = 6*
VMRuntime.getRuntime().setMinimumHeapSize(CWJ_HEAP_SIZE);
//设置最小heap内存为6MB大小。当然对于内存吃紧来说还可以通过手动干涉GC去处理
bitmap 设置图片尺寸,避免 内存溢出 OutOfMemoryError的优化方法
★android 中用bitmap
时很容易内存溢出,报如下错误:Java.lang.OutOfMemoryError : bitmap size exceeds VM budget
● 主要是加上这段:
BitmapFactory.Options&options&=&new&BitmapFactory.Options();&&&&&&&&&&&&&&&&&options.inSampleSize&=&2;&&&
● eg1:(通过Uri取图片)
private&ImageView&&BitmapFactory.Options&options&=&new&BitmapFactory.Options();&&&&&&&&&&&&&&&&&&&&&options.inSampleSize&=&2;&&&&&&&&&&&&&&&&&&&&&Bitmap&bitmap&=&BitmapFactory.decodeStream(cr&&&&&&&&&&&&&&&&&&&&&&&&&&&&&.openInputStream(uri),&null,&options);&&&&&&&&&&&&&&&&&&&&&preview.setImageBitmap(bitmap);&&&
以上代码可以优化内存溢出,但它只是改变图片大小,并不能彻底解决内存溢出。
● eg2:(通过路径去图片)
private&ImageView&&private&String&fileName=&&/sdcard/DCIM/Camera/&16.01.44.jpg&;&BitmapFactory.Options&options&=&new&BitmapFactory.Options();&&&&&&&&&&&&&&&&&options.inSampleSize&=&2;&&&&&&&&&&&&&&&&&&&&&&&&&Bitmap&b&=&BitmapFactory.decodeFile(fileName,&options);&&&&&&&&&&&&&&&&&&&&&&&&&preview.setImageBitmap(b);&&&&&&&&&&&&&&&&&&&&&&&&&filePath.setText(fileName);&
【编辑推荐】
【责任编辑: TEL:(010)】
关于&&&&的更多文章
Android 自2007 年诞生之日起,在经过过去几年的发展,逐渐取得
既然强大的Android Studio来了,有什么理由不去用呢?
微软和诺基亚终于达成协议,微软将收购诺基亚设备与服
随着秋的到来,各路才子佳人渐渐开始回到学校上课。不
百度推出轻应用引起业界火热议论,收购91和推出轻应用
本书全面深入地介绍了在网络的日常管理中,网络管理员必须掌握的知识,包括系统基本管理、性能调优、故障恢复、域控制器管理、存
Windows Phone专家
Android开发专家
51CTO旗下网站电脑提示内存溢出是什么原因?怎么解决?
电脑提示内存溢出是什么原因?怎么解决?
不区分大小写匿名
打开机箱茶牢固
转的:
这个情况很普遍
最近发布的补丁稳定性极差
安了就会出现你这种情况
唯一解决办法卸掉IE8
如果不是IE的问题
请直接看最后俩条解决方案或者下载windows更新
如果想了解一下 那就从头看吧
该内存不能read 或written数值 叙述
0 0x0000 作业完成。
1 0x0001 不正确的函数。
2 0x0002 系统找不到指定的档案。
3 0x0003 系统找不到指定的路径。
4 0x0004 系统无法开启档案。
5 0x0005 拒绝存取。
6 0x0006 无效的代码。
7 0x0007 储存体控制区块已毁。
8 0x0008 储存体空间不足,无法处理这个指令。
9 0x0009 储存体控制区块位址无效。
10 0x000a 环境不正确。
11 0x000b 尝试载入一个格式错误的程式。
12 0x000c 存取码错误。
13 0x000d 资料错误。
14 0x000e 储存体空间不够,无法完成这项作业。
15 0x000f 系统找不到指定的磁碟机。
16 0x0010 无法移除目录。
17 0x0011 系统无法将档案移到 其他的磁碟机。
18 0x0012 没有任何档案。
19 0x0013 储存媒体为防写状态。
20 0x0014 系统找不到指定的装置。
21 0x0015 装置尚未就绪。
22 0x0016 装置无法识别指令。
23 0x0017 资料错误 (cyclic redundancy check)
24 0x0018 程式发出一个长 度错误的指令。
25 0x0019 磁碟机在磁碟找不到 持定的磁区或磁轨。
26 0x001a 指定的磁碟或磁片无法存取。
27 0x001b 磁碟机找不到要求的磁区。
28 0x001c 印表机没有纸。
29 0x001d 系统无法将资料写入指定的磁碟机。
30 0x001e 系统无法读取指定的装置。
31 0x001f 连接到系统的某个装置没有作用。
32 0x0020 the process cannot access the file because it is being used by another process.
33 0x0021 档案的一部份被锁定, 现在无法存取。
34 0x0022 磁碟机的磁片不正确。 请将 %2 (volume serial number: %3) 插入磁碟机 %1。
36 0x0024 开启的分享档案数量太多。
38 0x0026 到达档案结尾。
39 0x0027 磁碟已满。
50 0x0032 不支援这种网路要求。
51 0x0033 远端电脑无法使用。
52 0x0034 网路名称重复。
53 0x0035 网路路径找不到。
54 0x0036 网路忙碌中。
55 0x0037 the specified network resource or device is no longer available.
56 0x0038 the network bios command limit has been reached.
57 0x0039 网路配接卡发生问题。
58 0x003a 指定的伺服器无法执行要求的作业。
59 0x003b 网路发生意外错误。
60 0x003c 远端配接卡不相容。
61 0x003d 印表机伫列已满。
62 0x003e 伺服器的空间无法储存等候列印的档案。
63 0x003f 等候列印的档案已经删除。
64 0x0040 指定的网路名称无法使用。
65 0x0041 拒绝存取网路。
66 0x0042 网路资源类型错误。
67 0x0043 网路名称找不到。
68 0x0044 超过区域电脑网路配接卡的名称限制。
69 0x0045 超过网路 bios 作业阶段的限制。
70 0x0046 远端伺服器已经暂停或者正在起始中。
71 0x0047 由于连线数目已达上限,此时无法再连线到这台远端电脑。
72 0x0048 指定的印表机或磁碟装置已经暂停作用。
80 0x0050 档案已经存在。
82 0x0052 无法建立目录或档案。
83 0x0053 int 24 失败
84 0x0054 处理这项要求的储存体无法使用。
85 0x0055 近端装置名称已经在使用中。
86 0x0056 指定的网路密码错误。
87 0x0057 参数错误。
88 0x0058 网路发生资料写入错误。
89 0x0059 此时系统无法执行其他行程。
100 0x0064 无法建立其他的系统 semaphore。
101 0x0065 属于其他行程专用的 semaphore 。
102 0x0066 semaphore 已经设定,而且无法关闭。
103 0x0067 无法指定 semaphore 。
104 0x0068 在岔断时间无法要求专用的 semaphore 。
105 0x0069 此 semaphore 先前的拥有权已经结束。
106 0x006a 请将磁片插入 %1。
107 0x006b 因为代用的磁片尚未插入,所以程式已经停止。
108 0x006c 磁碟正在使用中或被锁定。
109 0x006d pipe 已经中止。
110 0x006e 系统无法开启指定的 装置或档案。
111 0x006f 档名太长。
112 0x0070 磁碟空间不足。
113 0x0071 没有可用的内部档案识别字。
114 0x0072 目标内部档案识别字不正确。
117 0x0075 由应用程式所执行的 ioctl 呼叫 不正确。
118 0x0076 写入验证参数值不正确。
119 0x0077 系统不支援所要求的指令。
120 0x0078 此项功能仅在 win32 模式有效。
121 0x0079 semaphore 超过逾时期间。
122 0x007a 传到系统呼叫的资料区域 太小。
123 0x007b 档名、目录名称或储存体标签语法错误。
124 0x007c 系统呼叫层次不正确。
125 0x007d 磁碟没有设定标签。
126 0x007e 找不到指定的模组。
127 0x007f 找不到指定的程序。
128 0x0080 没有子行程可供等待。
129 0x0081 %1 这个应用程式无法在 win32 模式下执行。
130 0x0082 attempt to use a file handle to an open disk partition for an
operation other than raw disk i/o.
131 0x0083 尝试将档案指标移至档案开头之前。
132 0x0084 无法在指定的装置或档案,设定档案指标。
133 0x0085 join 或 subst 指令 无法用于 内含事先结合过的磁碟机。
134 0x0086 尝试在已经结合的磁碟机,使用 join 或 subst 指令。
135 0x0087 尝试在已经替换的磁碟机,使 用 join 或 subst 指令。
136 0x0088 系统尝试删除 未连结过的磁碟机的连结关系。
137 0x0089 系统尝试删除 未替换过的磁碟机的替换关系。
138 0x008a 系统尝试将磁碟机结合到已经结合过之磁碟机的目录。
139 0x008b 系统尝试将磁碟机替换成已经替换过之磁碟机的目录。
140 0x008c 系统尝试将磁碟机替换成已经替换过之磁碟机的目录。
141 0x008d 系统尝试将磁碟机 subst 成已结合的磁碟机 目录。
142 0x008e 系统此刻无法执行 join 或 subst。
143 0x008f 系统无法将磁碟机结合或替换同一磁碟机下目录。
144 0x0090 这个目录不是根目录的子目录。
145 0x0091 目录仍有资料。
146 0x0092 指定的路径已经被替换过。
147 0x0093 资源不足,无法处理这项 指令。
148 0x0094 指定的路径这时候无法使用。
149 0x0095 尝试要结合或替换的磁碟机目录,是已经替换过的的目标。
150 0x0096 config.sys 档未指定系统追踪资讯,或是追踪功能被取消。
151 0x0097 指定的 semaphore事件 dosmuxsemwait 数目不正确。
152 0x0098 dosmuxsemwait 没有执行;设定太多的 semaphore。
153 0x0099 dosmuxsemwait 清单不正确。
154 0x009a 您所输入的储存媒体标 元长度限制。
155 0x009b 无法建立其他的执行绪。
156 0x009c 接收行程拒绝接受信号。
157 0x009d 区段已经被舍弃,无法被锁定。
158 0x009e 区段已经解除锁定。
159 0x009f 执行绪识别码的位址不正确。
160 0x00a0 传到 dosexecpgm 的引数字串不正确。
161 0x00a1 指定的路径不正确。
162 0x00a2 信号等候处理。
164 0x00a4 系统无法建立执行绪。
167 0x00a7 无法锁定档案的部份范围。
170 0x00aa 所要求的资源正在使用中。
173 0x00ad 取消范围的锁定要求不明显。
174 0x00ae 档案系统不支援自动变更锁定类型。
180 0x00b4 系统发现不正确的区段号码。
182 0x00b6 作业系统无法执行 %1。
183 0x00b7 档案已存在,无法建立同一档案。
186 0x00ba 传送的旗号错误。
187 0x00bb 指定的系统旗号找不到。
188 0x00bc 作业系统无法执行 %1。
189 0x00bd 作业系统无法执行 %1。
190 0x00be 作业系统无法执行 %1。
191 0x00bf 无法在 win32 模式下执行 %1。
192 0x00c0 作业系统无法执行 %1。
193 0x00c1 %1 不是正确的 win32 应用程式。
194 0x00c2 作业系统无法执行 %1。
195 0x00c3 作业系统无法执行 %1。
196 0x00c4 作业系统无法执行 这个应用程式。
197 0x00c5 作业系统目前无法执行 这个应用程式。
198 0x00c6 作业系统无法执行 %1。
199 0x00c7 作业系统无法执行 这个应用程式。
200 0x00c8 程式码的区段不可以大于或等于 64kb。
201 0x00c9 作业系统无法执行 %1。
202 0x00ca 作业系统无法执行 %1。
203 0x00cb 系统找不到输入的环境选项。 \r
205 0x00cd 在指令子目录下,没有任何行程有信号副处理程式。
206 0x00ce 档案名称或副档名太长。
207 0x00cf ring 2 堆叠使用中。
使用Windows操作系统的人有时会遇到这样的错误信息:“0X????????指令引用的 0x内存,该内存不能written”,然后应用程序被关闭。如果去请教一些“高手”,得到的回答往往是“Windows就是这样不稳定”之类的义愤和不屑。其实,这个错误并不一定是Windows不稳定造成的。本文就来简单分析这种错误的常见原因。
内存不能为read的问题是一个非常复杂的问题,造成的原因是多方面的,有硬件的原因,也有软件的原因,一时半会儿很难搞的清楚。就是对那些整天玩电脑的老手来说也是一个非常辣手的问题。就我个人的理解,大多与使用非原版的系统而产生的不稳定性有关,轻易很难修复。所以我一般的主张是,只要不是频繁出现,可以不必管它,点一下“确定”或者“取消”就可以了。如果真有兴趣想研究一下的话,你可以试着从一下方面寻找原因:
1. 内存条坏了或与主板不兼容 更换内存条
2. 双内存不兼容 使用同品牌的内存或只要一条内存
3. 内存质量问题 更换内存条
4. 散热问题 加强机箱内部的散热
5. 内存和主板没插好或其他硬件不兼容 重插内存或换个插槽
6. 硬盘有问题 更换硬盘
7. 驱动问题 重装驱动,如果是新系统,应先安装主板驱动
8. 软件损坏 重装软件
9. 软件有BUG 打补丁或更新到最新版本
10 软件和系统不兼容 给软件打上补丁或是试试系统的兼容模式
11 软件和软件之间有冲突 如果最近安装了什么新软件,卸载了试试
12 软件要使用其他相关的软件有问题 重装相关软件,比如播放某一格式的文件时出错,可能是这个文件的解码器有问题
13 病毒问题 杀毒
14 杀毒软件与系统或软件相冲突 由于杀毒软件是进入底层监控系统的,可能与一些软件相冲突,卸载试试
15 系统本身有问题 有时候操作系统本身也会有BUG,要注意安装官方发行的更新程序,象SP的补丁,最好打上
——最后我再强调一下,不是所有的电脑问题我们普通人都能搞得清摸得透的,以上的方法即使都已试过,谁也不能保证一定能够解决你的问题,因为电脑的问题的确很复杂,“不能为read”这仅仅是一个症状,单凭这一个小小的症状是很难一下子找到问题所在的。我们都希望当说明了问题之后能够马上得到满意的回答,有时候是不可能的,必须慢慢的摸索才能知道问题所在。如果想省心的话,也许只有最后这两点建议最有用:一是不管它(反正也没有大碍),二是重装一个稳定的系统。说到系统,这也是我要说的重点,实际上我们的电脑之所以出现“内存不能为read的问题”,大多都与安装了Ghost系统有关,“内存不能为read”现象可以说是Ghost系统的一个不可修复的通病。所以我建议你用原版系统盘重装系统。关于什么是Ghost系统,我在这里也解释一下(好多现在正在使用Ghost系统的人都不知道自己的系统是Ghost系统),所谓Ghost系统,就是指像那些番茄花园、电脑公司版、雨林木风、萝卜家园等改版本的XP系统,即非原版的系统。你可以通过点“我的电脑”右键-属性来查看你的系统属性。
感觉跟读天书差不多,我对电脑实在是一窍不通,能不能麻烦您说的再简单易懂一点啊?
内存不够了运行大型软件或游戏时,软件或游戏所需要的内存远远超出了你主机内安装的内存所承受大小,就叫内存溢出。此时软件或游戏就运行不了,系统会提示内存溢出,有时候会自动关闭软件,重启电脑或者软件后释放掉一部分内存又可以正常运行该软件或游戏一段时间。可以尝试用内存自动释放软件解决一下。windows优化大师有内存整理的,再不行就只有加内存了。
加内存怎么加啊?我对电脑一窍不通!
把你的电脑信息发一下。。。。用鲁大师看 然后截图发下、。&& 看一下内存是什么频率的,。
内存溢出的意思是有些文件在大量吃你的物理内存,以至于有些新运行的文件运行不了,你需要走2步1、清理垃圾文件,释放内存2、把你的虚拟内存设置大点希望可以帮到你
内存已满!
相关知识等待您来回答
电脑常识领域专家是一个开源的UI组件程序,该项目的目的是提供一个可重复使用的仪器为异步图像加载,缓存和显示。所以,如果你的程序里需要这个功能的话,那么不妨试试它。因为已经封装好了一些类和方法。我们 可以直接拿来用了。而不用重复去写了。其实,写一个这方面的程序还是比较麻烦的,要考虑多线程缓存,内存溢出等很多方面。
二、具体使用
一个好的类库的重要特征就是可配置性强。我们先简单使用Android-Universal-Image-Loader,一般情况下使用默认配置就可以了。
下面的实例利用Android-Universal-Image-Loader将网络图片加载到图片墙中。
1 public class BaseActivity extends Activity {
ImageLoader imageL
protected void onCreate(Bundle savedInstanceState) {
// Create global configuration and initialize ImageLoader with this configuration
ImageLoaderConfiguration config = new ImageLoaderConfiguration.Builder(getApplicationContext())
ImageLoader.getInstance().init(config);
super.onCreate(savedInstanceState);
1 public class MainActivity extends BaseActivity {
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ImageLoader imageLoader = ImageLoader.getInstance();
GridView gridView = (GridView) this.findViewById(R.id.grdvImageWall);
gridView.setAdapter(new PhotoWallAdapter(Constants.IMAGES));
static class ViewHolder {
ImageView imageV
ProgressBar progressB
public class PhotoWallAdapter extends BaseAdapter {
String[] imageU
ImageLoader imageL
DisplayImageOptions
LinearLayout gridViewI
public PhotoWallAdapter(String[] imageUrls) {
assert imageUrls != null;
this.imageUrls = imageU
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
.considerExifParams(false) // default
.imageScaleType(ImageScaleType.IN_SAMPLE_POWER_OF_2) // default
.bitmapConfig(Bitmap.Config.ARGB_8888) // default
.displayer(new SimpleBitmapDisplayer()) // default
.handler(new Handler()) // default
this.imageLoad = ImageLoader.getInstance();
public int getCount() {
return this.imageUrls.
public Object getItem(int position) {
if (position &= 0 || position &= this.imageUrls.length) {
throw new IllegalArgumentException(
"position&=0||position&=this.imageUrls.length");
return this.imageUrls[position];
public long getItemId(int position) {
public View getView(int position, View convertView, ViewGroup parent) {
// 判断这个image是否已经在缓存当中,如果没有就下载
final ViewH
if (convertView == null) {
holder = new ViewHolder();
gridViewItem = (LinearLayout) getLayoutInflater().inflate(
R.layout.image_wall_item, null);
holder.imageView = (ImageView) gridViewItem
.findViewById(R.id.item_image);
holder.progressBar = (ProgressBar) gridViewItem
.findViewById(R.id.item_process);
gridViewItem.setTag(holder);
convertView = gridViewI
holder = (ViewHolder) gridViewItem.getTag();
this.imageLoad.displayImage(this.imageUrls[position],
holder.imageView, options,
new SimpleImageLoadingListener() {
public void onLoadingStarted(String imageUri, View view) {
holder.progressBar.setProgress(0);
holder.progressBar.setVisibility(View.VISIBLE);
public void onLoadingFailed(String imageUri, View view,
FailReason failReason) {
holder.progressBar.setVisibility(View.GONE);
public void onLoadingComplete(String imageUri,
View view, Bitmap loadedImage) {
holder.progressBar.setVisibility(View.GONE);
}, new ImageLoadingProgressListener() {
public void onProgressUpdate(String imageUri,
View view, int current, int total) {
holder.progressBar.setProgress(Math.round(100.0f
* current / total));
}); // 通过URL判断图片是否已经下载
return convertV
里面主要的对象都用& & & &&突出显示了。
三者的关系
ImageLoaderConfiguration是针对图片缓存的全局配置,主要有线程类、缓存大小、磁盘大小、图片下载与解析、日志方面的配置。
ImageLoader是具体下载图片,缓存图片,显示图片的具体执行类,它有两个具体的方法displayImage(...)、loadImage(...),但是其实最终他们的实现都是displayImage(...)。
DisplayImageOptions用于指导每一个Imageloader根据网络图片的状态(空白、下载错误、正在下载)显示对应的图片,是否将缓存加载到磁盘上,下载完后对图片进行怎么样的处理。
从三者的协作关系上看,他们有点像厨房规定、厨师、客户个人口味之间的关系。ImageLoaderConfiguration就像是厨房里面的规定,每一个厨师要怎么着装,要怎么保持厨房的干净,这是针对每一个厨师都适用的规定,而且不允许个性化改变。ImageLoader就像是具体做菜的厨师,负责具体菜谱的制作。DisplayImageOptions就像每个客户的偏好,根据客户是重口味还是清淡,每一个imageLoader根据DisplayImageOptions的要求具体执行。
ImageLoaderConfiguration
在上面的示例代码中,我们使用ImageLoaderConfiguration的默认配置,下面给出ImageLoaderConfiguration比较详尽的配置,从下面的配置中,可以看出ImageLoaderConfiguration的配置主要是全局性的配置,主要有线程类、缓存大小、磁盘大小、图片下载与解析、日志方面的配置。
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 - 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()
ImageLoaderConfiguration的主要职责就是记录相关的配置,它的内部其实就是一些字段的集合(如下面的源代码)。它有一个builder的内部类,这个类中的字段跟ImageLoaderConfiguration中的字段完全一致,它有一些默认值,通过修改builder可以配置ImageLoaderConfiguration。
1 /*******************************************************************************
* Copyright
Sergey Tarasevich
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*******************************************************************************/
16 package com.nostra13.universalimageloader.
18 import android.content.C
19 import android.content.res.R
20 import android.util.DisplayM
21 import com.nostra13.universalimageloader.cache.disc.DiskC
22 import com.nostra13.universalimageloader.cache.disc.naming.FileNameG
23 import com.nostra13.universalimageloader.cache.memory.MemoryC
24 import com.nostra13.universalimageloader.cache.memory.impl.FuzzyKeyMemoryC
25 import com.nostra13.universalimageloader.core.assist.FlushedInputS
26 import com.nostra13.universalimageloader.core.assist.ImageS
27 import com.nostra13.universalimageloader.core.assist.QueueProcessingT
28 import com.nostra13.universalimageloader.core.decode.ImageD
29 import com.nostra13.universalimageloader.core.download.ImageD
30 import com.nostra13.universalimageloader.core.process.BitmapP
31 import com.nostra13.universalimageloader.utils.L;
32 import com.nostra13.universalimageloader.utils.MemoryCacheU
34 import java.io.IOE
35 import java.io.InputS
36 import java.util.concurrent.E
* Presents configuration for {@link ImageLoader}
* @author Sergey Tarasevich (nostra13[at]gmail[dot]com)
* @see ImageLoader
* @see MemoryCache
* @see DiskCache
* @see DisplayImageOptions
* @see ImageDownloader
* @see FileNameGenerator
* @since 1.0.0
50 public final class ImageLoaderConfiguration {
final int maxImageWidthForMemoryC
final int maxImageHeightForMemoryC
final int maxImageWidthForDiskC
final int maxImageHeightForDiskC
final BitmapProcessor processorForDiskC
final Executor taskE
final Executor taskExecutorForCachedI
final boolean customE
final boolean customExecutorForCachedI
final int threadPoolS
final int threadP
final QueueProcessingType tasksProcessingT
final MemoryCache memoryC
final DiskCache diskC
final ImageD
final ImageD
final DisplayImageOptions defaultDisplayImageO
final ImageDownloader networkDeniedD
final ImageDownloader slowNetworkD
private ImageLoaderConfiguration(final Builder builder) {
resources = builder.context.getResources();
maxImageWidthForMemoryCache = builder.maxImageWidthForMemoryC
maxImageHeightForMemoryCache = builder.maxImageHeightForMemoryC
maxImageWidthForDiskCache = builder.maxImageWidthForDiskC
maxImageHeightForDiskCache = builder.maxImageHeightForDiskC
processorForDiskCache = builder.processorForDiskC
taskExecutor = builder.taskE
taskExecutorForCachedImages = builder.taskExecutorForCachedI
threadPoolSize = builder.threadPoolS
threadPriority = builder.threadP
tasksProcessingType = builder.tasksProcessingT
diskCache = builder.diskC
memoryCache = builder.memoryC
defaultDisplayImageOptions = builder.defaultDisplayImageO
downloader = builder.
decoder = builder.
customExecutor = builder.customE
customExecutorForCachedImages = builder.customExecutorForCachedI
networkDeniedDownloader = new NetworkDeniedImageDownloader(downloader);
slowNetworkDownloader = new SlowNetworkImageDownloader(downloader);
L.writeDebugLogs(builder.writeLogs);
* Creates default configuration for {@link ImageLoader} &br /&
* &b&Default values:&/b&
* &li&maxImageWidthForMemoryCache = device's screen width&/li&
* &li&maxImageHeightForMemoryCache = device's screen height&/li&
* &li&maxImageWidthForDikcCache = unlimited&/li&
* &li&maxImageHeightForDiskCache = unlimited&/li&
* &li&threadPoolSize = {@link Builder#DEFAULT_THREAD_POOL_SIZE this}&/li&
* &li&threadPriority = {@link Builder#DEFAULT_THREAD_PRIORITY this}&/li&
* &li&allow to cache different sizes of image in memory&/li&
* &li&memoryCache = {@link DefaultConfigurationFactory#createMemoryCache(int)}&/li&
* &li&diskCache = {@link com.nostra13.universalimageloader.cache.disc.impl.UnlimitedDiscCache}&/li&
* &li&imageDownloader = {@link DefaultConfigurationFactory#createImageDownloader(Context)}&/li&
* &li&imageDecoder = {@link DefaultConfigurationFactory#createImageDecoder(boolean)}&/li&
* &li&diskCacheFileNameGenerator = {@link DefaultConfigurationFactory#createFileNameGenerator()}&/li&
* &li&defaultDisplayImageOptions = {@link DisplayImageOptions#createSimple() Simple options}&/li&
* &li&tasksProcessingOrder = {@link QueueProcessingType#FIFO}&/li&
* &li&detailed logging disabled&/li&
public static ImageLoaderConfiguration createDefault(Context context) {
return new Builder(context).build();
ImageSize getMaxImageSize() {
DisplayMetrics displayMetrics = resources.getDisplayMetrics();
int width = maxImageWidthForMemoryC
if (width &= 0) {
width = displayMetrics.widthP
int height = maxImageHeightForMemoryC
if (height &= 0) {
height = displayMetrics.heightP
return new ImageSize(width, height);
* Builder for {@link ImageLoaderConfiguration}
* @author Sergey Tarasevich (nostra13[at]gmail[dot]com)
public static class Builder {
private static final String WARNING_OVERLAP_DISK_CACHE_PARAMS = "diskCache(), diskCacheSize() and diskCacheFileCount calls overlap each other";
private static final String WARNING_OVERLAP_DISK_CACHE_NAME_GENERATOR = "diskCache() and diskCacheFileNameGenerator() calls overlap each other";
private static final String WARNING_OVERLAP_MEMORY_CACHE = "memoryCache() and memoryCacheSize() calls overlap each other";
private static final String WARNING_OVERLAP_EXECUTOR = "threadPoolSize(), threadPriority() and tasksProcessingOrder() calls "
+ "can overlap taskExecutor() and taskExecutorForCachedImages() calls.";
/** {@value} */
public static final int DEFAULT_THREAD_POOL_SIZE = 3;
/** {@value} */
public static final int DEFAULT_THREAD_PRIORITY = Thread.NORM_PRIORITY - 1;
/** {@value} */
public static final QueueProcessingType DEFAULT_TASK_PROCESSING_TYPE = QueueProcessingType.FIFO;
private int maxImageWidthForMemoryCache = 0;
private int maxImageHeightForMemoryCache = 0;
private int maxImageWidthForDiskCache = 0;
private int maxImageHeightForDiskCache = 0;
private BitmapProcessor processorForDiskCache = null;
private Executor taskExecutor = null;
private Executor taskExecutorForCachedImages = null;
private boolean customExecutor = false;
private boolean customExecutorForCachedImages = false;
private int threadPoolSize = DEFAULT_THREAD_POOL_SIZE;
private int threadPriority = DEFAULT_THREAD_PRIORITY;
private boolean denyCacheImageMultipleSizesInMemory = false;
private QueueProcessingType tasksProcessingType = DEFAULT_TASK_PROCESSING_TYPE;
private int memoryCacheSize = 0;
private long diskCacheSize = 0;
private int diskCacheFileCount = 0;
private MemoryCache memoryCache = null;
private DiskCache diskCache = null;
private FileNameGenerator diskCacheFileNameGenerator = null;
private ImageDownloader downloader = null;
private ImageD
private DisplayImageOptions defaultDisplayImageOptions = null;
private boolean writeLogs = false;
public Builder(Context context) {
this.context = context.getApplicationContext();
* Sets options for memory cache
* @param maxImageWidthForMemoryCache
Maximum image width which will be used for memory saving during decoding
an image to {@link android.graphics.Bitmap Bitmap}. &b&Default value - device's screen width&/b&
* @param maxImageHeightForMemoryCache Maximum image height which will be used for memory saving during decoding
an image to {@link android.graphics.Bitmap Bitmap}. &b&Default value&/b& - device's screen height
public Builder memoryCacheExtraOptions(int maxImageWidthForMemoryCache, int maxImageHeightForMemoryCache) {
this.maxImageWidthForMemoryCache = maxImageWidthForMemoryC
this.maxImageHeightForMemoryCache = maxImageHeightForMemoryC
return this;
* @deprecated Use
* {@link #diskCacheExtraOptions(int, int, com.nostra13.universalimageloader.core.process.BitmapProcessor)}
@Deprecated
public Builder discCacheExtraOptions(int maxImageWidthForDiskCache, int maxImageHeightForDiskCache,
BitmapProcessor processorForDiskCache) {
return diskCacheExtraOptions(maxImageWidthForDiskCache, maxImageHeightForDiskCache, processorForDiskCache);
* Sets options for resizing/compressing of downloaded images before saving to disk cache.&br /&
* &b&NOTE: Use this option only when you have appropriate needs. It can make ImageLoader slower.&/b&
* @param maxImageWidthForDiskCache
Maximum width of downloaded images for saving at disk cache
* @param maxImageHeightForDiskCache Maximum height of downloaded images for saving at disk cache
* @param processorForDiskCache
null- {@linkplain BitmapProcessor Bitmap processor} which process images before saving them in disc cache
public Builder diskCacheExtraOptions(int maxImageWidthForDiskCache, int maxImageHeightForDiskCache,
BitmapProcessor processorForDiskCache) {
this.maxImageWidthForDiskCache = maxImageWidthForDiskC
this.maxImageHeightForDiskCache = maxImageHeightForDiskC
this.processorForDiskCache = processorForDiskC
return this;
* Sets custom {@linkplain Executor executor} for tasks of loading and displaying images.&br /&
* &b&NOTE:&/b& If you set custom executor then following configuration options will not be considered for this
* executor:
* &li&{@link #threadPoolSize(int)}&/li&
* &li&{@link #threadPriority(int)}&/li&
* &li&{@link #tasksProcessingOrder(QueueProcessingType)}&/li&
* @see #taskExecutorForCachedImages(Executor)
public Builder taskExecutor(Executor executor) {
if (threadPoolSize != DEFAULT_THREAD_POOL_SIZE || threadPriority != DEFAULT_THREAD_PRIORITY || tasksProcessingType != DEFAULT_TASK_PROCESSING_TYPE) {
L.w(WARNING_OVERLAP_EXECUTOR);
this.taskExecutor =
return this;
* Sets custom {@linkplain Executor executor} for tasks of displaying &b&cached on disk&/b& images (these tasks
* are executed quickly so UIL prefer to use separate executor for them).&br /&
* If you set the same executor for {@linkplain #taskExecutor(Executor) general tasks} and
* tasks about cached images (this method) then these tasks will be in the
* same thread pool. So short-lived tasks can wait a long time for their turn.&br /&
* &b&NOTE:&/b& If you set custom executor then following configuration options will not be considered for this
* executor:
* &li&{@link #threadPoolSize(int)}&/li&
* &li&{@link #threadPriority(int)}&/li&
* &li&{@link #tasksProcessingOrder(QueueProcessingType)}&/li&
* @see #taskExecutor(Executor)
public Builder taskExecutorForCachedImages(Executor executorForCachedImages) {
if (threadPoolSize != DEFAULT_THREAD_POOL_SIZE || threadPriority != DEFAULT_THREAD_PRIORITY || tasksProcessingType != DEFAULT_TASK_PROCESSING_TYPE) {
L.w(WARNING_OVERLAP_EXECUTOR);
this.taskExecutorForCachedImages = executorForCachedI
return this;
* Sets thread pool size for image display tasks.&br /&
* Default value - {@link #DEFAULT_THREAD_POOL_SIZE this}
public Builder threadPoolSize(int threadPoolSize) {
if (taskExecutor != null || taskExecutorForCachedImages != null) {
L.w(WARNING_OVERLAP_EXECUTOR);
this.threadPoolSize = threadPoolS
return this;
* Sets the priority for image loading threads. Should be &b&NOT&/b& greater than {@link Thread#MAX_PRIORITY} or
* less than {@link Thread#MIN_PRIORITY}&br /&
* Default value - {@link #DEFAULT_THREAD_PRIORITY this}
public Builder threadPriority(int threadPriority) {
if (taskExecutor != null || taskExecutorForCachedImages != null) {
L.w(WARNING_OVERLAP_EXECUTOR);
if (threadPriority & Thread.MIN_PRIORITY) {
this.threadPriority = Thread.MIN_PRIORITY;
if (threadPriority & Thread.MAX_PRIORITY) {
this.threadPriority = Thread.MAX_PRIORITY;
this.threadPriority = threadP
return this;
* When you display an image in a small {@link android.widget.ImageView ImageView} and later you try to display
* this image (from identical URI) in a larger {@link android.widget.ImageView ImageView} so decoded image of
* bigger size will be cached in memory as a previous decoded image of smaller size.&br /&
* So &b&the default behavior is to allow to cache multiple sizes of one image in memory&/b&. You can
* &b&deny&/b& it by calling &b&this&/b& method: so when some image will be cached in memory then previous
* cached size of this image (if it exists) will be removed from memory cache before.
public Builder denyCacheImageMultipleSizesInMemory() {
this.denyCacheImageMultipleSizesInMemory = true;
return this;
* Sets type of queue processing for tasks for loading and displaying images.&br /&
* Default value - {@link QueueProcessingType#FIFO}
public Builder tasksProcessingOrder(QueueProcessingType tasksProcessingType) {
if (taskExecutor != null || taskExecutorForCachedImages != null) {
L.w(WARNING_OVERLAP_EXECUTOR);
this.tasksProcessingType = tasksProcessingT
return this;
* Sets maximum memory cache size for {@link android.graphics.Bitmap bitmaps} (in bytes).&br /&
* Default value - 1/8 of available app memory.&br /&
* &b&NOTE:&/b& If you use this method then
* {@link com.nostra13.universalimageloader.cache.memory.impl.LruMemoryCache LruMemoryCache} will be used as
* memory cache. You can use {@link #memoryCache(MemoryCache)} method to set your own implementation of
* {@link MemoryCache}.
public Builder memoryCacheSize(int memoryCacheSize) {
if (memoryCacheSize &= 0) throw new IllegalArgumentException("memoryCacheSize must be a positive number");
if (memoryCache != null) {
L.w(WARNING_OVERLAP_MEMORY_CACHE);
this.memoryCacheSize = memoryCacheS
return this;
* Sets maximum memory cache size (in percent of available app memory) for {@link android.graphics.Bitmap
* bitmaps}.&br /&
* Default value - 1/8 of available app memory.&br /&
* &b&NOTE:&/b& If you use this method then
* {@link com.nostra13.universalimageloader.cache.memory.impl.LruMemoryCache LruMemoryCache} will be used as
* memory cache. You can use {@link #memoryCache(MemoryCache)} method to set your own implementation of
* {@link MemoryCache}.
public Builder memoryCacheSizePercentage(int availableMemoryPercent) {
if (availableMemoryPercent &= 0 || availableMemoryPercent &= 100) {
throw new IllegalArgumentException("availableMemoryPercent must be in range (0 & % & 100)");
if (memoryCache != null) {
L.w(WARNING_OVERLAP_MEMORY_CACHE);
long availableMemory = Runtime.getRuntime().maxMemory();
memoryCacheSize = (int) (availableMemory * (availableMemoryPercent / 100f));
return this;
* Sets memory cache for {@link android.graphics.Bitmap bitmaps}.&br /&
* Default value - {@link com.nostra13.universalimageloader.cache.memory.impl.LruMemoryCache LruMemoryCache}
* with limited memory cache size (size = 1/8 of available app memory)&br /&
* &b&NOTE:&/b& If you set custom memory cache then following configuration option will not be considered:
* &li&{@link #memoryCacheSize(int)}&/li&
public Builder memoryCache(MemoryCache memoryCache) {
if (memoryCacheSize != 0) {
L.w(WARNING_OVERLAP_MEMORY_CACHE);
this.memoryCache = memoryC
return this;
/** @deprecated Use {@link #diskCacheSize(int)} instead */
@Deprecated
public Builder discCacheSize(int maxCacheSize) {
return diskCacheSize(maxCacheSize);
* Sets maximum disk cache size for images (in bytes).&br /&
* By default: disk cache is unlimited.&br /&
* &b&NOTE:&/b& If you use this method then
* {@link com.nostra13.universalimageloader.cache.disc.impl.ext.LruDiscCache LruDiscCache}
* will be used as disk cache. You can use {@link #diskCache(DiskCache)} method for introduction your own
* implementation of {@link DiskCache}
public Builder diskCacheSize(int maxCacheSize) {
if (maxCacheSize &= 0) throw new IllegalArgumentException("maxCacheSize must be a positive number");
if (diskCache != null) {
L.w(WARNING_OVERLAP_DISK_CACHE_PARAMS);
this.diskCacheSize = maxCacheS
return this;
/** @deprecated Use {@link #diskCacheFileCount(int)} instead */
@Deprecated
public Builder discCacheFileCount(int maxFileCount) {
return diskCacheFileCount(maxFileCount);
* Sets maximum file count in disk cache directory.&br /&
* By default: disk cache is unlimited.&br /&
* &b&NOTE:&/b& If you use this method then
* {@link com.nostra13.universalimageloader.cache.disc.impl.ext.LruDiscCache LruDiscCache}
* will be used as disk cache. You can use {@link #diskCache(DiskCache)} method for introduction your own
* implementation of {@link DiskCache}
public Builder diskCacheFileCount(int maxFileCount) {
if (maxFileCount &= 0) throw new IllegalArgumentException("maxFileCount must be a positive number");
if (diskCache != null) {
L.w(WARNING_OVERLAP_DISK_CACHE_PARAMS);
this.diskCacheFileCount = maxFileC
return this;
/** @deprecated Use {@link #diskCacheFileNameGenerator(com.nostra13.universalimageloader.cache.disc.naming.FileNameGenerator)} */
@Deprecated
public Builder discCacheFileNameGenerator(FileNameGenerator fileNameGenerator) {
return diskCacheFileNameGenerator(fileNameGenerator);
* Sets name generator for files cached in disk cache.&br /&
* Default value -
* {@link com.nostra13.universalimageloader.core.DefaultConfigurationFactory#createFileNameGenerator()
* DefaultConfigurationFactory.createFileNameGenerator()}
public Builder diskCacheFileNameGenerator(FileNameGenerator fileNameGenerator) {
if (diskCache != null) {
L.w(WARNING_OVERLAP_DISK_CACHE_NAME_GENERATOR);
this.diskCacheFileNameGenerator = fileNameG
return this;
/** @deprecated Use {@link #diskCache(com.nostra13.universalimageloader.cache.disc.DiskCache)} */
@Deprecated
public Builder discCache(DiskCache diskCache) {
return diskCache(diskCache);
* Sets disk cache for images.&br /&
* Default value - {@link com.nostra13.universalimageloader.cache.disc.impl.UnlimitedDiscCache
* BaseDiscCache}. Cache directory is defined by
* {@link com.nostra13.universalimageloader.utils.StorageUtils#getCacheDirectory(Context)
* StorageUtils.getCacheDirectory(Context)}.&br /&
* &b&NOTE:&/b& If you set custom disk cache then following configuration option will not be considered:
* &li&{@link #diskCacheSize(int)}&/li&
* &li&{@link #diskCacheFileCount(int)}&/li&
* &li&{@link #diskCacheFileNameGenerator(FileNameGenerator)}&/li&
public Builder diskCache(DiskCache diskCache) {
if (diskCacheSize & 0 || diskCacheFileCount & 0) {
L.w(WARNING_OVERLAP_DISK_CACHE_PARAMS);
if (diskCacheFileNameGenerator != null) {
L.w(WARNING_OVERLAP_DISK_CACHE_NAME_GENERATOR);
this.diskCache = diskC
return this;
* Sets utility which will be responsible for downloading of image.&br /&
* Default value -
* {@link com.nostra13.universalimageloader.core.DefaultConfigurationFactory#createImageDownloader(Context)
* DefaultConfigurationFactory.createImageDownloader()}
public Builder imageDownloader(ImageDownloader imageDownloader) {
this.downloader = imageD
return this;
* Sets utility which will be responsible for decoding of image stream.&br /&
* Default value -
* {@link com.nostra13.universalimageloader.core.DefaultConfigurationFactory#createImageDecoder(boolean)
* DefaultConfigurationFactory.createImageDecoder()}
public Builder imageDecoder(ImageDecoder imageDecoder) {
this.decoder = imageD
return this;
* Sets default {@linkplain DisplayImageOptions display image options} for image displaying. These options will
* be used for every {@linkplain ImageLoader#displayImage(String, android.widget.ImageView) image display call}
* without passing custom {@linkplain DisplayImageOptions options}&br /&
* Default value - {@link DisplayImageOptions#createSimple() Simple options}
public Builder defaultDisplayImageOptions(DisplayImageOptions defaultDisplayImageOptions) {
this.defaultDisplayImageOptions = defaultDisplayImageO
return this;
* Enables detail logging of {@link ImageLoader} work. To prevent detail logs don't call this method.
* Consider {@link com.nostra13.universalimageloader.utils.L#disableLogging()} to disable
* ImageLoader logging completely (even error logs)
public Builder writeDebugLogs() {
this.writeLogs = true;
return this;
/** Builds configured {@link ImageLoaderConfiguration} object */
public ImageLoaderConfiguration build() {
initEmptyFieldsWithDefaultValues();
return new ImageLoaderConfiguration(this);
private void initEmptyFieldsWithDefaultValues() {
if (taskExecutor == null) {
taskExecutor = DefaultConfigurationFactory
.createExecutor(threadPoolSize, threadPriority, tasksProcessingType);
customExecutor = true;
if (taskExecutorForCachedImages == null) {
taskExecutorForCachedImages = DefaultConfigurationFactory
.createExecutor(threadPoolSize, threadPriority, tasksProcessingType);
customExecutorForCachedImages = true;
if (diskCache == null) {
if (diskCacheFileNameGenerator == null) {
diskCacheFileNameGenerator = DefaultConfigurationFactory.createFileNameGenerator();
diskCache = DefaultConfigurationFactory
.createDiskCache(context, diskCacheFileNameGenerator, diskCacheSize, diskCacheFileCount);
if (memoryCache == null) {
memoryCache = DefaultConfigurationFactory.createMemoryCache(memoryCacheSize);
if (denyCacheImageMultipleSizesInMemory) {
memoryCache = new FuzzyKeyMemoryCache(memoryCache, MemoryCacheUtils.createFuzzyKeyComparator());
if (downloader == null) {
downloader = DefaultConfigurationFactory.createImageDownloader(context);
if (decoder == null) {
decoder = DefaultConfigurationFactory.createImageDecoder(writeLogs);
if (defaultDisplayImageOptions == null) {
defaultDisplayImageOptions = DisplayImageOptions.createSimple();
* Decorator. Prevents downloads from network (throws {@link IllegalStateException exception}).&br /&
* In most cases this downloader shouldn't be used directly.
* @author Sergey Tarasevich (nostra13[at]gmail[dot]com)
* @since 1.8.0
private static class NetworkDeniedImageDownloader implements ImageDownloader {
private final ImageDownloader wrappedD
public NetworkDeniedImageDownloader(ImageDownloader wrappedDownloader) {
this.wrappedDownloader = wrappedD
public InputStream getStream(String imageUri, Object extra) throws IOException {
switch (Scheme.ofUri(imageUri)) {
case HTTP:
case HTTPS:
throw new IllegalStateException();
return wrappedDownloader.getStream(imageUri, extra);
* Decorator. Handles &a href="/p/android/issues/detail?id=6066"&this problem&/a& on slow networks
* using {@link com.nostra13.universalimageloader.core.assist.FlushedInputStream}.
* @author Sergey Tarasevich (nostra13[at]gmail[dot]com)
* @since 1.8.1
private static class SlowNetworkImageDownloader implements ImageDownloader {
private final ImageDownloader wrappedD
public SlowNetworkImageDownloader(ImageDownloader wrappedDownloader) {
this.wrappedDownloader = wrappedD
public InputStream getStream(String imageUri, Object extra) throws IOException {
InputStream imageStream = wrappedDownloader.getStream(imageUri, extra);
switch (Scheme.ofUri(imageUri)) {
case HTTP:
case HTTPS:
return new FlushedInputStream(imageStream);
return imageS
&Display Options
每一个ImageLoader.displayImage(...)都可以使用Display Options。
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
&Display Options的主要职责就是记录相关的配置,它的内部其实就是一些字段的集合(如下面的源代码)。它有一个builder的内部类,这个类中的字段跟DisplayOption中的字段完全一致,它有一些默认值,通过修改builder可以配置DisplayOptions。
1 public final class DisplayImageOptions {
private final int imageResOnL
private final int imageResForEmptyU
private final int imageResOnF
private final Drawable imageOnL
private final Drawable imageForEmptyU
private final Drawable imageOnF
private final boolean resetViewBeforeL
private final boolean cacheInM
private final boolean cacheOnD
private final ImageScaleType imageScaleT
private final Options decodingO
private final int delayBeforeL
private final boolean considerExifP
private final Object extraForD
private final BitmapProcessor preP
private final BitmapProcessor postP
private final BitmapD
private final H
private final boolean isSyncL
private DisplayImageOptions(Builder builder) {
imageResOnLoading = builder.imageResOnL
imageResForEmptyUri = builder.imageResForEmptyU
imageResOnFail = builder.imageResOnF
imageOnLoading = builder.imageOnL
imageForEmptyUri = builder.imageForEmptyU
imageOnFail = builder.imageOnF
resetViewBeforeLoading = builder.resetViewBeforeL
cacheInMemory = builder.cacheInM
cacheOnDisk = builder.cacheOnD
imageScaleType = builder.imageScaleT
decodingOptions = builder.decodingO
delayBeforeLoading = builder.delayBeforeL
considerExifParams = builder.considerExifP
extraForDownloader = builder.extraForD
preProcessor = builder.preP
postProcessor = builder.postP
displayer = builder.
handler = builder.
isSyncLoading = builder.isSyncL
public boolean shouldShowImageOnLoading() {
return imageOnLoading != null || imageResOnLoading != 0;
public boolean shouldShowImageForEmptyUri() {
return imageForEmptyUri != null || imageResForEmptyUri != 0;
public boolean shouldShowImageOnFail() {
return imageOnFail != null || imageResOnFail != 0;
public boolean shouldPreProcess() {
return preProcessor != null;
public boolean shouldPostProcess() {
return postProcessor != null;
public boolean shouldDelayBeforeLoading() {
return delayBeforeLoading & 0;
public Drawable getImageOnLoading(Resources res) {
return imageResOnLoading != 0 ? res.getDrawable(imageResOnLoading) : imageOnL
public Drawable getImageForEmptyUri(Resources res) {
return imageResForEmptyUri != 0 ? res.getDrawable(imageResForEmptyUri) : imageForEmptyU
public Drawable getImageOnFail(Resources res) {
return imageResOnFail != 0 ? res.getDrawable(imageResOnFail) : imageOnF
public boolean isResetViewBeforeLoading() {
return resetViewBeforeL
public boolean isCacheInMemory() {
return cacheInM
public boolean isCacheOnDisk() {
return cacheOnD
public ImageScaleType getImageScaleType() {
return imageScaleT
public Options getDecodingOptions() {
return decodingO
public int getDelayBeforeLoading() {
return delayBeforeL
public boolean isConsiderExifParams() {
return considerExifP
public Object getExtraForDownloader() {
return extraForD
public BitmapProcessor getPreProcessor() {
return preP
public BitmapProcessor getPostProcessor() {
return postP
public BitmapDisplayer getDisplayer() {
public Handler getHandler() {
boolean isSyncLoading() {
return isSyncL
* Builder for {@link DisplayImageOptions}
* @author Sergey Tarasevich (nostra13[at]gmail[dot]com)
public static class Builder {
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;
public Builder() {
decodingOptions.inPurgeable = true;
decodingOptions.inInputShareable = true;
* Stub image will be displayed in {@link com.nostra13.universalimageloader.core.imageaware.ImageAware
* image aware view} during image loading
* @param imageRes Stub image resource
* @deprecated Use {@link #showImageOnLoading(int)} instead
@Deprecated
public Builder showStubImage(int imageRes) {
imageResOnLoading = imageR
return this;
* Incoming image will be displayed in {@link com.nostra13.universalimageloader.core.imageaware.ImageAware
* image aware view} during image loading
* @param imageRes Image resource
public Builder showImageOnLoading(int imageRes) {
imageResOnLoading = imageR
return this;
* Incoming drawable will be displayed in {@link com.nostra13.universalimageloader.core.imageaware.ImageAware
* image aware view} during image loading.
* This option will be ignored if {@link DisplayImageOptions.Builder#showImageOnLoading(int)} is set.
public Builder showImageOnLoading(Drawable drawable) {
imageOnLoading =
return this;
* Incoming image will be displayed in {@link com.nostra13.universalimageloader.core.imageaware.ImageAware
* image aware view} if empty URI (null or empty
* string) will be passed to &b&ImageLoader.displayImage(...)&/b& method.
* @param imageRes Image resource
public Builder showImageForEmptyUri(int imageRes) {
imageResForEmptyUri = imageR
return this;
* Incoming drawable will be displayed in {@link com.nostra13.universalimageloader.core.imageaware.ImageAware
* image aware view} if empty URI (null or empty
* string) will be passed to &b&ImageLoader.displayImage(...)&/b& method.
* This option will be ignored if {@link DisplayImageOptions.Builder#showImageForEmptyUri(int)} is set.
public Builder showImageForEmptyUri(Drawable drawable) {
imageForEmptyUri =
return this;
* Incoming image will be displayed in {@link com.nostra13.universalimageloader.core.imageaware.ImageAware
* image aware view} if some error occurs during
* requested image loading/decoding.
* @param imageRes Image resource
public Builder showImageOnFail(int imageRes) {
imageResOnFail = imageR
return this;
* Incoming drawable will be displayed in {@link com.nostra13.universalimageloader.core.imageaware.ImageAware
* image aware view} if some error occurs during
* requested image loading/decoding.
* This option will be ignored if {@link DisplayImageOptions.Builder#showImageOnFail(int)} is set.
public Builder showImageOnFail(Drawable drawable) {
imageOnFail =
return this;
* {@link com.nostra13.universalimageloader.core.imageaware.ImageAware
* image aware view} will be reset (set &b&null&/b&) before image loading start
* @deprecated Use {@link #resetViewBeforeLoading(boolean) resetViewBeforeLoading(true)} instead
public Builder resetViewBeforeLoading() {
resetViewBeforeLoading = true;
return this;
* Sets whether {@link com.nostra13.universalimageloader.core.imageaware.ImageAware
* image aware view} will be reset (set &b&null&/b&) before image loading start
public Builder resetViewBeforeLoading(boolean resetViewBeforeLoading) {
this.resetViewBeforeLoading = resetViewBeforeL
return this;
* Loaded image will be cached in memory
* @deprecated Use {@link #cacheInMemory(boolean) cacheInMemory(true)} instead
@Deprecated
public Builder cacheInMemory() {
cacheInMemory = true;
return this;
/** Sets whether loaded image will be cached in memory */
public Builder cacheInMemory(boolean cacheInMemory) {
this.cacheInMemory = cacheInM
return this;
* Loaded image will be cached on disk
* @deprecated Use {@link #cacheOnDisk(boolean) cacheOnDisk(true)} instead
@Deprecated
public Builder cacheOnDisc() {
return cacheOnDisk(true);
* Sets whether loaded image will be cached on disk
* @deprecated Use {@link #cacheOnDisk(boolean)} instead
@Deprecated
public Builder cacheOnDisc(boolean cacheOnDisk) {
return cacheOnDisk(cacheOnDisk);
/** Sets whether loaded image will be cached on disk */
public Builder cacheOnDisk(boolean cacheOnDisk) {
this.cacheOnDisk = cacheOnD
return this;
* Sets {@linkplain ImageScaleType scale type} for decoding image. This parameter is used while define scale
* size for decoding image to Bitmap. Default value - {@link ImageScaleType#IN_SAMPLE_POWER_OF_2}
public Builder imageScaleType(ImageScaleType imageScaleType) {
this.imageScaleType = imageScaleT
return this;
/** Sets {@link Bitmap.Config bitmap config} for image decoding. Default value - {@link Bitmap.Config#ARGB_8888} */
public Builder bitmapConfig(Bitmap.Config bitmapConfig) {
if (bitmapConfig == null) throw new IllegalArgumentException("bitmapConfig can't be null");
decodingOptions.inPreferredConfig = bitmapC
return this;
* Sets options for image decoding.&br /&
* &b&NOTE:&/b& {@link Options#inSampleSize} of incoming options will &b&NOT&/b& be considered. Library
* calculate the most appropriate sample size itself according yo {@link #imageScaleType(ImageScaleType)}
* options.&br /&
* &b&NOTE:&/b& This option overlaps {@link #bitmapConfig(android.graphics.Bitmap.Config) bitmapConfig()}
public Builder decodingOptions(Options decodingOptions) {
if (decodingOptions == null) throw new IllegalArgumentException("decodingOptions can't be null");
this.decodingOptions = decodingO
return this;
/** Sets delay time before starting loading task. Default - no delay. */
public Builder delayBeforeLoading(int delayInMillis) {
this.delayBeforeLoading = delayInM
return this;
/** Sets auxiliary object which will be passed to {@link ImageDownloader#getStream(String, Object)} */
public Builder extraForDownloader(Object extra) {
this.extraForDownloader =
return this;
/** Sets whether ImageLoader will consider EXIF parameters of JPEG image (rotate, flip) */
public Builder considerExifParams(boolean considerExifParams) {
this.considerExifParams = considerExifP
return this;
* Sets bitmap processor which will be process bitmaps before they will be cached in memory. So memory cache
* will contain bitmap processed by incoming preProcessor.&br /&
* Image will be pre-processed even if caching in memory is disabled.
public Builder preProcessor(BitmapProcessor preProcessor) {
this.preProcessor = preP
return this;
* Sets bitmap processor which will be process bitmaps before they will be displayed in
* {@link com.nostra13.universalimageloader.core.imageaware.ImageAware image aware view} but
* after they'll have been saved in memory cache.
public Builder postProcessor(BitmapProcessor postProcessor) {
this.postProcessor = postP
return this;
* Sets custom {@link BitmapDisplayer displayer} for image loading task. Default value -
* {@link DefaultConfigurationFactory#createBitmapDisplayer()}
public Builder displayer(BitmapDisplayer displayer) {
if (displayer == null) throw new IllegalArgumentException("displayer can't be null");
this.displayer =
return this;
Builder syncLoading(boolean isSyncLoading) {
this.isSyncLoading = isSyncL
return this;
* Sets custom {@linkplain Handler handler} for displaying images and firing {@linkplain ImageLoadingListener
* listener} events.
public Builder handler(Handler handler) {
this.handler =
return this;
/** Sets all options equal to incoming options */
public Builder cloneFrom(DisplayImageOptions options) {
imageResOnLoading = options.imageResOnL
imageResForEmptyUri = options.imageResForEmptyU
imageResOnFail = options.imageResOnF
imageOnLoading = options.imageOnL
imageForEmptyUri = options.imageForEmptyU
imageOnFail = options.imageOnF
resetViewBeforeLoading = options.resetViewBeforeL
cacheInMemory = options.cacheInM
cacheOnDisk = options.cacheOnD
imageScaleType = options.imageScaleT
decodingOptions = options.decodingO
delayBeforeLoading = options.delayBeforeL
considerExifParams = options.considerExifP
extraForDownloader = options.extraForD
preProcessor = options.preP
postProcessor = options.postP
displayer = options.
handler = options.
isSyncLoading = options.isSyncL
return this;
/** Builds configured {@link DisplayImageOptions} object */
public DisplayImageOptions build() {
return new DisplayImageOptions(this);
* Creates options appropriate for single displaying:
* &li&View will &b&not&/b& be reset before loading&/li&
* &li&Loaded image will &b&not&/b& be cached in memory&/li&
* &li&Loaded image will &b&not&/b& be cached on disk&/li&
* &li&{@link ImageScaleType#IN_SAMPLE_POWER_OF_2} decoding type will be used&/li&
* &li&{@link Bitmap.Config#ARGB_8888} bitmap config will be used for image decoding&/li&
* &li&{@link SimpleBitmapDisplayer} will be used for image displaying&/li&
* These option are appropriate for simple single-use image (from drawables or from Internet) displaying.
public static DisplayImageOptions createSimple() {
return new Builder().build();
http://blog.csdn.net/wangjinyu501/article/details/8091623
/nostra13/Android-Universal-Image-Loader
/blog/item/74-universal-image-loader-part-3.html
阅读(...) 评论()

我要回帖

更多关于 怎么解决内存溢出 的文章

 

随机推荐