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. python程序后台运行的实现

    后台运行work()方法. work.py # -*- coding:utf-8 -*- def work(): print "running" import time time. ...

  2. pageHelper 排序 +- 字符串处理

    自己记录一下. 前端要把sort参数传过来, 1. 如果约定是下面这种形式: sort=id-name+age+ 直接在java后台进行替换就行,连正则都不用. sort = sort.replace ...

  3. 应用Mongoose开发MongoDB(1)数据库连接

    最近因为项目,接触了MongoDB,因为是分工合作,我负责的部分主要是实现前端对数据库增删查改的需求,因此以下内容只着重于针对不同问题如何进行解决. 整个工程的最终目的是通过mongoose编写数据库 ...

  4. Zookeeper项目开发环境搭建(Eclipse\MyEclipse + Maven)

    写在前面的话 可详细参考,一定得去看 HBase 开发环境搭建(Eclipse\MyEclipse + Maven) 我这里,相信,能看此博客的朋友,想必是有一定基础的了.我前期写了大量的基础性博文. ...

  5. sublime安装package control 的方法

    1.安装sublime3后,点击菜单 view>show console,复制以下代码按回车即可,安装时稍微有些卡,需要耐心等待. import urllib.request,os; pf = ...

  6. [转]C++中vector使用详细说明

    一.向量的介绍    向量 vector 是一种对象实体, 能够容纳许多其他类型相同的元素, 因此又被称为容器. 与string相同, vector 同属于STL(Standard Template ...

  7. 在VC++中怎样改变控件间的TAB切换顺序?

    在编辑界面按下ctrl+D键,就会出现所有控件的Tab键顺序,按照自己想要的顺序依次点击控件,就可以重新安排顺序.

  8. 在mac中调试网页

    一.谷歌浏览器 //打开控制台 option + command + j 二.safari浏览器 safari > 偏好设置 > 勾选开发菜单 1.打开控制台 A.可以在网页中右键,检查元 ...

  9. BZOJ.2660.[BJOI2012]最多的方案(DP)

    题目链接 首先我们知道: 也很好理解.如果相邻两项出现在斐波那契表示法中,那它们显然可以合并. 所以我们能得到\(n\)的斐波那契表示,记\(pos[i]\)为\(n\)的斐波那契表示法中,第\(i\ ...

  10. NOI 2002 荒岛野人

    人生第一次做NOI的题祭!!! 大概是NOI最简单的一道题 克里特岛以野人群居而著称.岛上有排列成环行的M个山洞.这些山洞顺时针编号为1,2,…,M.岛上住着N个野人,一开始依次住在山洞C1,C2,… ...