Universal-Image-Loader这个开源框架又来给我们造福了,它是一个图片加载框架,主要强大在于可以用于网络等图片源的加载,并且有多重缓存机制。先给出其项目地址:https://github.com/nostra13/Android-Universal-Image-Loader

一、简要说明:

1.多线程下载图片,图片可以来源于网络,文件系统,项目文件夹assets中以及drawable中等
2.支持随意的配置ImageLoader,例如线程池,图片下载器,内存缓存策略,硬盘缓存策略,图片显示选项以及其他的一些配置
3.支持图片的内存缓存,文件系统缓存或者SD卡缓存
4.支持图片下载过程的监听
5.根据控件(ImageView)的大小对Bitmap进行裁剪,减少Bitmap占用过多的内存
6.较好的控制图片的加载过程,例如暂停图片加载,重新开始加载图片,一般使用在ListView,GridView中,滑动过程中暂停加载图片,停止滑动的时候去加载图片
7.提供在较慢的网络下对图片进行加载

二、配置和使用

1.新建一个类继承Application,实现初始化ImageLoader

ImageLoader是一个配置方案,主要是一次性的配置项目中的缓存策略,这样独立的配置很便于模块化。

@Override
public void onCreate() {
// TODO 自动生成的方法存根
super.onCreate(); //通过配置方案来初始化ImageLoader
ImageLoader.getInstance().init(ImageLoaderConfiguration configuration);
    }

这里的参数是一个ImageLoaderConfiguration,这个对象可以设置缓存,缓存路径等等,下面我们先得到一个默认的配置好的对象。

它使用了Build模式,这样我们就可以很方便的来得到一个默认的配置好的ImageLoaderConfiguration对象

    /**
* 创建默认的ImageLoader配置参数,这里创建了一个默认的配置方案
* @return
*/
private ImageLoaderConfiguration getDefaultConfig() {
ImageLoaderConfiguration config = ImageLoaderConfiguration.createDefault(getApplicationContext());
return config;
}

当然,ImageLoaderConfiguration有多重选项可以配置。下面是各种属性和自己的默认值

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

example:

    /**
* 所有的配置参数举例
* @return
*/
private ImageLoaderConfiguration getWholeConfig() {
//设置默认的配置,设置缓存,这里不设置可以到别的地方设置
DisplayImageOptions defaultOptions = new DisplayImageOptions.Builder()
.cacheInMemory(true)
.cacheOnDisk(true)
.build(); //设置缓存的路径
File cacheDir = StorageUtils.getOwnCacheDirectory(getApplicationContext(), "imageloader/Cache"); ImageLoaderConfiguration config = new ImageLoaderConfiguration
.Builder(getApplicationContext())
.memoryCacheExtraOptions(480, 800) //即保存的每个缓存文件的最大长宽
.threadPoolSize(3) //线程池内加载的数量
.threadPriority(Thread.NORM_PRIORITY - 2)
//解释:当同一个Uri获取不同大小的图片,缓存到内存时,只缓存一个。默认会缓存多个不同的大小的相同图片
.denyCacheImageMultipleSizesInMemory() //拒绝缓存多个图片。
.memoryCache(new WeakMemoryCache()) //缓存策略你可以通过自己的内存缓存实现 ,这里用弱引用,缺点是太容易被回收了,不是很好!
.memoryCacheSize(2 * 1024 * 1024) //设置内存缓存的大小
.diskCacheSize(50 * 1024 * 1024) //设置磁盘缓存大小 50M
.diskCacheFileNameGenerator(new Md5FileNameGenerator()) //将保存的时候的URI名称用MD5 加密
.tasksProcessingOrder(QueueProcessingType.LIFO) //设置图片下载和显示的工作队列排序
.diskCacheFileCount(100) //缓存的文件数量
.diskCache(new UnlimitedDiskCache(cacheDir)) //自定义缓存路径
.defaultDisplayImageOptions(defaultOptions) //显示图片的参数,默认:DisplayImageOptions.createSimple()
.imageDownloader(new BaseImageDownloader(this, 5 * 1000, 30 * 1000)) // connectTimeout (5 s), readTimeout (30 s)超时时间
.writeDebugLogs() //打开调试日志
.build();//开始构建 return config;
}

刚开始别被吓跑了,其实看起来多,我们一般只需要知道这是做什么的,然后根据自己的需求配置即可。

常用配置:

    /**
* 比较常用的配置方案
* @return
*/
private ImageLoaderConfiguration getSimpleConfig() {
//设置缓存的路径
File cacheDir = StorageUtils.getOwnCacheDirectory(getApplicationContext(), "imageloader/Cache"); ImageLoaderConfiguration config = new ImageLoaderConfiguration
.Builder(getApplicationContext())
.memoryCacheExtraOptions(480, 800) //即保存的每个缓存文件的最大长宽
.threadPriority(Thread.NORM_PRIORITY - 2) //线程池中线程的个数
.denyCacheImageMultipleSizesInMemory() //禁止缓存多张图片
.memoryCache(new LRULimitedMemoryCache(40*1024*1024)) //缓存策略
.memoryCacheSize(50 * 1024 * 1024) //设置内存缓存的大小
.diskCacheFileNameGenerator(new Md5FileNameGenerator()) //缓存文件名的保存方式
.diskCacheSize(200 * 1024 * 1024) //磁盘缓存大小
.tasksProcessingOrder(QueueProcessingType.LIFO) //工作队列
.diskCacheFileCount(200) //缓存的文件数量
.diskCache(new UnlimitedDiskCache(cacheDir)) //自定义缓存路径
//.writeDebugLogs() // Remove for release app
.build();
return config;
}

注:这里面有多个参数是有待商榷的,自己根据需求配置即可!

在Activity中清除缓存的方法:

        //清除缓存
ImageLoader.getInstance().clearDiskCache();
ImageLoader.getInstance().clearMemoryCache();

Manifest.xml 中加入权限,并且配置Application!

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.kale.universalimageloadertest"
android:versionCode="1"
android:versionName="1.0" > <!-- 访问internet的权限 -->
<uses-permission android:name="android.permission.INTERNET" />
<!-- Include next permission if you want to allow UIL to cache images on SD card -->
<!-- 写入sd卡的权限 -->
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> <uses-sdk
android:minSdkVersion="8"
android:targetSdkVersion="18" /> <!-- 添加进自己的Application -->
<application
android:name="com.kale.universalimageloadertest.application.MyApplication"
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<activity
android:name=".MainActivity"
android:label="@string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name="com.kale.universalimageloadertest.UILListActivity"/>
</application> </manifest>

MyApplication.JAVA

package com.kale.universalimageloadertest.application;

import java.io.File;

import android.app.Application;

import com.nostra13.universalimageloader.cache.disc.impl.UnlimitedDiskCache;
import com.nostra13.universalimageloader.cache.disc.naming.Md5FileNameGenerator;
import com.nostra13.universalimageloader.cache.memory.impl.FIFOLimitedMemoryCache;
import com.nostra13.universalimageloader.cache.memory.impl.LRULimitedMemoryCache;
import com.nostra13.universalimageloader.cache.memory.impl.WeakMemoryCache;
import com.nostra13.universalimageloader.core.DisplayImageOptions;
import com.nostra13.universalimageloader.core.ImageLoader;
import com.nostra13.universalimageloader.core.ImageLoaderConfiguration;
import com.nostra13.universalimageloader.core.assist.QueueProcessingType;
import com.nostra13.universalimageloader.core.download.BaseImageDownloader;
import com.nostra13.universalimageloader.utils.StorageUtils; /**
* @author:Jack Tony
* @tips :新建一个MyApplication继承Application,并在onCreate()
* 中创建ImageLoader的配置参数,并初始化到ImageLoader中代码
* @date :2014-10-15
*/
public class MyApplication extends Application{ @Override
public void onCreate() {
// TODO 自动生成的方法存根
super.onCreate(); //通过配置方案来初始化ImageLoader
ImageLoader.getInstance().init(getSimpleConfig());
} /**
* 创建默认的ImageLoader配置参数,这里创建了一个默认的配置方案
* @return
*/
private ImageLoaderConfiguration getDefaultConfig() {
ImageLoaderConfiguration config = ImageLoaderConfiguration
.createDefault(getApplicationContext());
return config;
} /**
* 所有的配置参数举例
* @return
*/
private ImageLoaderConfiguration getWholeConfig() {
//设置默认的配置,设置缓存,这里不设置可以到别的地方设置
DisplayImageOptions defaultOptions = new DisplayImageOptions.Builder()
.cacheInMemory(true)
.cacheOnDisk(true)
.build(); //设置缓存的路径
File cacheDir = StorageUtils.getOwnCacheDirectory(getApplicationContext(), "imageloader/Cache"); ImageLoaderConfiguration config = new ImageLoaderConfiguration
.Builder(getApplicationContext())
.memoryCacheExtraOptions(480, 800) //即保存的每个缓存文件的最大长宽
.threadPoolSize(3) //线程池内加载的数量
.threadPriority(Thread.NORM_PRIORITY - 2)
//解释:当同一个Uri获取不同大小的图片,缓存到内存时,只缓存一个。默认会缓存多个不同的大小的相同图片
.denyCacheImageMultipleSizesInMemory() //拒绝缓存多个图片。
.memoryCache(new WeakMemoryCache()) //缓存策略你可以通过自己的内存缓存实现 ,这里用弱引用,缺点是太容易被回收了,不是很好!
.memoryCacheSize(2 * 1024 * 1024) //设置内存缓存的大小
.diskCacheSize(50 * 1024 * 1024) //设置磁盘缓存大小 50M
.diskCacheFileNameGenerator(new Md5FileNameGenerator()) //将保存的时候的URI名称用MD5 加密
.tasksProcessingOrder(QueueProcessingType.LIFO) //设置图片下载和显示的工作队列排序
.diskCacheFileCount(100) //缓存的文件数量
.diskCache(new UnlimitedDiskCache(cacheDir)) //自定义缓存路径
.defaultDisplayImageOptions(defaultOptions) //显示图片的参数,默认:DisplayImageOptions.createSimple()
.imageDownloader(new BaseImageDownloader(getApplicationContext(), 5 * 1000, 30 * 1000)) // connectTimeout (5 s), readTimeout (30 s)超时时间
.writeDebugLogs() //打开调试日志
.build();//开始构建
return config;
} /**
* 比较常用的配置方案
* @return
*/
private ImageLoaderConfiguration getSimpleConfig() {
//设置缓存的路径
File cacheDir = StorageUtils.getOwnCacheDirectory(getApplicationContext(), "imageloader/Cache"); ImageLoaderConfiguration config = new ImageLoaderConfiguration
.Builder(getApplicationContext())
.memoryCacheExtraOptions(480, 800) //即保存的每个缓存文件的最大长宽
.threadPriority(Thread.NORM_PRIORITY - 2) //线程池中线程的个数
.denyCacheImageMultipleSizesInMemory() //禁止缓存多张图片
.memoryCache(new LRULimitedMemoryCache(50 * 1024 * 1024)) //缓存策略
.memoryCacheSize(50 * 1024 * 1024) //设置内存缓存的大小
.diskCacheFileNameGenerator(new Md5FileNameGenerator()) //缓存文件名的保存方式
.diskCacheSize(200 * 1024 * 1024) //磁盘缓存大小
.tasksProcessingOrder(QueueProcessingType.LIFO) //工作队列
.diskCacheFileCount(200) //缓存的文件数量
.diskCache(new UnlimitedDiskCache(cacheDir)) //自定义缓存路径
//.writeDebugLogs() // Remove for release app
.build();
return config;
} /* ImageLoaderConfiguration config = new ImageLoaderConfiguration.Builder(context)
.memoryCacheExtraOptions(480, 800) // default = device screen dimensions
.diskCacheExtraOptions(480, 800, CompressFormat.JPEG, 75, null)
.taskExecutor(...)
.taskExecutorForCachedImages(...)
.threadPoolSize(3) // default
.threadPriority(Thread.NORM_PRIORITY - 1) // default
.tasksProcessingOrder(QueueProcessingType.FIFO) // default
.denyCacheImageMultipleSizesInMemory()
.memoryCache(new LruMemoryCache(2 * 1024 * 1024))
.memoryCacheSize(2 * 1024 * 1024)
.memoryCacheSizePercentage(13) // default
.diskCache(new UnlimitedDiscCache(cacheDir)) // default
.diskCacheSize(50 * 1024 * 1024)
.diskCacheFileCount(100)
.diskCacheFileNameGenerator(new HashCodeFileNameGenerator()) // default
.imageDownloader(new BaseImageDownloader(context)) // default
.imageDecoder(new BaseImageDecoder()) // default
.defaultDisplayImageOptions(DisplayImageOptions.createSimple()) // default
.writeDebugLogs()
.build(); */
}

Universal-Image-Loader的内存缓存策略

详细的缓存策略可以移步:http://blog.csdn.net/xiaanming/article/details/27525741,下方是总结的结果:

1.强引用缓存 
LruMemoryCache(这个类就是这个开源框架默认的内存缓存类,缓存的是bitmap的强引用)

好处:滑动时图片不会容易被清除,体验好;坏处:容易出现OOM

2.使用强引用和弱引用相结合的缓存有
UsingFreqLimitedMemoryCache(如果缓存的图片总量超过限定值,先删除使用频率最小的bitmap)
LRULimitedMemoryCache(这个也是使用的lru算法,和LruMemoryCache不同的是,他缓存的是bitmap的引用)
FIFOLimitedMemoryCache(先进先出的缓存策略,当超过设定值,先删除最先加入缓存的bitmap)
LargestLimitedMemoryCache(当超过缓存限定值,先删除最大的bitmap对象)
LimitedAgeMemoryCache(当 bitmap加入缓存中的时间超过我们设定的值,将其删除)

3.只使用弱引用缓存
WeakMemoryCache(这个类缓存bitmap的总大小没有限制,唯一不足的地方就是不稳定,缓存的图片容易被回收掉)

好处:对缓存的bitmap总大小无限制;坏处:使得图片不稳定,图片极其容易被回收

注意:不要使用.cacheInMemory();

Universal-Image-Loader的硬盘缓存策略

详细的硬盘缓存策略可以移步:http://blog.csdn.net/xiaanming/article/details/27525741,下方是总结的结果:

FileCountLimitedDiscCache(可以设定缓存图片的个数,当超过设定值,删除掉最先加入到硬盘的文件)
LimitedAgeDiscCache(设定文件存活的最长时间,当超过这个值,就删除该文件)
TotalSizeLimitedDiscCache(设定缓存bitmap的最大值,当超过这个值,删除最先加入到硬盘的文件)
UnlimitedDiscCache(这个缓存类没有任何的限制)

在ImageLoaderConfiguration中配置了diskCacheSize和diskCacheFileCount,他就使用的是LruDiscCache,否则使用的是UnlimitedDiscCache

在最新的源码中还有一个硬盘缓存类可以配置,那就是LimitedAgeDiscCache,可以在ImageLoaderConfiguration.diskCache(...)配置

避免OOM

为了避免OOM,可以修改下面的配置方案:

.memoryCacheExtraOptions(480, 800) //即保存的每个缓存文件的最大长宽,大小自行配制

.threadPriority(Thread.NORM_PRIORITY - 2) //线程池中线程的个数,一般配置1-5,这里配的是3

.memoryCache(new LRULimitedMemoryCache(40*1024*1024)) //改变缓存策略,可以用弱引用

参考自:

http://blog.csdn.net/xiaanming/article/details/26810303

http://blog.csdn.net/xiaanming/article/details/27525741

http://blog.csdn.net/vipzjyno1/article/details/23206387

Universal-Image-Loader解析(一)——ImageLoaderConfiguration的详细配置的更多相关文章

  1. 【Android应用开发】 Universal Image Loader ( 使用简介 | 示例代码解析 )

    作者 : 韩曙亮 转载请注明出处 : http://blog.csdn.net/shulianghan/article/details/50824912 相关地址介绍 : -- Universal I ...

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

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

  3. Android中Universal Image Loader开源框架的简单使用

    UIL (Universal Image Loader)aims to provide a powerful, flexible and highly customizable instrument ...

  4. universal image loader自己使用的一些感受

    1.全局入口的Application定义初始化: ImageLoaderConfiguration configuration = new ImageLoaderConfiguration.Build ...

  5. 【译】UNIVERSAL IMAGE LOADER. PART 3---ImageLoader详解

    在之前的文章,我们重点讲了Android-Universal-Image-Loader的三个主要组件,现在我们终于可以开始使用它了. Android-Universal-Image-Loader有四个 ...

  6. universal image loader在listview/gridview中滚动时重复加载图片的问题及解决方法

    在listview/gridview中使用UIL来display每个item的图片,当图片数量较多需要滑动滚动时会出现卡顿,而且加载过的图片再次上翻后依然会重复加载(显示设置好的加载中图片) 最近在使 ...

  7. 开源项目Universal Image Loader for Android 说明文档 (1) 简介

     When developing applications for Android, one often facesthe problem of displaying some graphical ...

  8. 开源项目Universal Image Loader for Android 说明文档 (1) 简单介绍

     When developing applications for Android, one often facesthe problem of displaying some graphical ...

  9. Android开源库--Universal Image Loader通用图片加载器

    如果说我比别人看得更远些,那是因为我站在了巨人的肩上.   github地址:https://github.com/nostra13/Android-Universal-Image-Loader 介绍 ...

随机推荐

  1. 有关redis相关的性能优化及内存说明

    本篇文章不涉及redis的安装配置,百度或谷歌即可,很简单. 首先,我来说说redis的应用场景,大部分公司都是将redis作为缓存服务器,或者作为ELK日志收集里面的缓存角色(其他这里就不做介绍,比 ...

  2. js中怎么为同级元素添加点击事件

    事件件是javascript脚本语言的重要组成部分,因为有事件才使用户页面的体验更加的美好.元素添加事件是js语言中最基础的.我们可以为元素本身添加事件,也可以通过事件绑定和事件监听为元素的父元素和子 ...

  3. 利用Httponly提升web应用程序安全性(转)

    原文:http://kb.cnblogs.com/page/115136/ 随着www服务的兴起,越来越多的应用程序转向了B/S结构,这样只需要一个浏览器就可以访问各种各样的web服务,但是这样也越来 ...

  4. Javascript中DOM详解与学习

    DOM(文档对象模型)是针对html和XML文档的一个API(应用程序编程接口).DOM描绘了一个层次化的节点树,允许开发人员添加,移除和修改页面的某一部分.下面将从这几个层次来学习. 一.节点层次 ...

  5. CF1065E Side Transmutations

    link 题意: 给你一个长为m的序列$b_i$,定义两个字符串a,b相同当前仅当a执行以下操作后能变成b:($\rm{prefix}(x,y)$及$\rm{suffix}(x,y)$定义为串x的前/ ...

  6. C语言sscanf和sprintf输入输出使用及Strlen、Memset解释

    sscanf() - 从一个字符串中读进与指定格式相符的数据.   swscanf()- 用于处理宽字符字符串,和sscanf功能相同    通过学习和使用个人认为,在字符串格式不是很复杂,但是也并不 ...

  7. BZOJ4045 : [Cerc2014] bricks

    首先求出B和W的个数,如果只出现了一种那么直接输出sum(k). 否则依次扫描,能割就割,时间复杂度$O(n)$. #include<cstdio> #define N 100010 ty ...

  8. Codeforces Round #258 (Div. 2) A. Game With Sticks 水题

    A. Game With Sticks 题目连接: http://codeforces.com/contest/451/problem/A Description After winning gold ...

  9. spring-boot parent变更为依赖方式

    原parent继承方式 <parent> <groupId>org.springframework.boot</groupId> <artifactId> ...

  10. DMA Stream/Channel Outputting via GPIOC[0..7]

    Ok, so quickly mashing up another example using a different TIM, DMA Stream/Channel for illustration ...