简介

Android上最让人头疼的莫过于从网络获取图片、显示、回收,任何一个环节有问题都可能直接OOM,这个项目或许能帮到你。Universal Image Loader for Android的目的是为了实现异步的网络图片加载、缓存及显示,支持多线程异步加载。它最初来源于Fedor Vlasov的项目,且自此之后,经过大规模的重构和改进

imageloader 加载图片的一般流程是先判断内存中是否有对应的Bitmap,再判断磁盘(disk)中是否有,如果没有就从网络中加载。最后根据原先在UIL中的配置判断是否需要缓存Bitmap到内存或磁盘中。Bitmap加载完后,就对它进行解析,然后显示到特定的ImageView中,

加载过程分析简图:

使用imageLoader可以实现

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

初始化imageloader

方式一:

  1. //创建默认的ImageLoader配置参数
  2. ImageLoaderConfiguration configuration = ImageLoaderConfiguration
  3. .createDefault(this);
  4. //Initialize ImageLoader with configuration.
  5. ImageLoader.getInstance().init(configuration);

方式二:

  1. File cacheDir =getExternalStoragePath()+imageloader/Cache");  //获取自定义缓存路径
  2. ImageLoaderConfigurationconfig = new ImageLoaderConfiguration
  3. .Builder(this)
  4. .memoryCacheExtraOptions(480, 800) // maxwidth, max height,即保存的每个缓存文件的最大长宽
  5. .threadPoolSize(3)//线程池内加载的数量
  6. .threadPriority(Thread.NORM_PRIORITY -2)
  7. .denyCacheImageMultipleSizesInMemory()
  8. .memoryCache(new UsingFreqLimitedMemoryCache(2* 1024 * 1024)) // You can pass your own memory cache implementation/你可以通过自己的内存缓存实现
  9. .memoryCacheSize(2 * 1024 * 1024)
  10. .discCacheSize(50 * 1024 * 1024)
  11. .discCacheFileNameGenerator(newMd5FileNameGenerator())//将保存的时候的URI名称用MD5 加密
  12. .tasksProcessingOrder(QueueProcessingType.LIFO)
  13. .discCacheFileCount(100) //缓存的文件数量
  14. .discCache(new UnlimitedDiscCache(cacheDir))//自定义缓存路径   ,这里是缓存到sd卡上
  15. .defaultDisplayImageOptions(DisplayImageOptions.createSimple())
  16. .imageDownloader(new BaseImageDownloader(this,5 * 1000, 30 * 1000)) // connectTimeout (5 s), readTimeout (30 s)超时时间
  17. .writeDebugLogs() // Remove for releaseapp
  18. .build();//开始构建
  19. ImageLoader.getInstance().init(config);
  1. // 获取SD卡路径
  2. public  String getExternalStoragePath() {
  3. // 获取SdCard状态
  4. String state = android.os.Environment.getExternalStorageState();
  5. // 判断SdCard是否存在并且是可用的
  6. if (android.os.Environment.MEDIA_MOUNTED.equals(state)) {
  7. if (android.os.Environment.getExternalStorageDirectory().canWrite()) {
  8. return android.os.Environment.getExternalStorageDirectory()
  9. .getPath();
  10. }
  11. }
  12. return null;
  13. }

方式三:

  1. // 获取最大内存
  2. int maxMemorySize = (int) (Runtime.getRuntime().maxMemory());
  3. ImageLoaderConfiguration.Builder config = new ImageLoaderConfiguration.Builder(
  4. context);
  5. config.threadPriority(Thread.NORM_PRIORITY - 2);
  6. config.denyCacheImageMultipleSizesInMemory();// 不会在内存中缓存多个大小的图片
  7. config.diskCacheFileNameGenerator(new Md5FileNameGenerator());// 为了保证图片名称唯一
  8. config.diskCacheSize(maxMemorySize / 10);// 内存缓存大小默认是:app可用内存的1/8,这里设为1/10
  9. config.tasksProcessingOrder(QueueProcessingType.LIFO);
  10. config.writeDebugLogs(); // Remove for release app
  11. // Initialize ImageLoader with configuration.
  12. ImageLoader.getInstance().init(config.build());

最好是使用用方式三,这里是动态获取内存的大小 ,可以有效的避免一些内存溢出的效果  。。。。

当然要将图片缓存到本地自定义的路径中,可以使用用方式二与方式三相结合使用

特别说明:

1、ImageLoaderConfiguration 配置中的.discCacheFileNameGenerator()方法是将缓存下来的文件以什么方式命名

里面可以调用的方法有  1.new Md5FileNameGenerator() //使用MD5对UIL进行加密命名

2.new HashCodeFileNameGenerator()//使用HASHCODE对UIL进行加密命名

使用中的图像操作

配制一 
  1. DisplayImageOptions options = new DisplayImageOptions.Builder()
  2. .showImageOnLoading(R.drawable.ic_stub)            //加载图片时的图片
  3. .showImageForEmptyUri(R.drawable.ic_empty)         //没有图片资源时的默认图片
  4. .showImageOnFail(R.drawable.ic_error)              //加载失败时的图片
  5. .cacheInMemory(true)                               //启用内存缓存
  6. .cacheOnDisk(true)                                 //启用外存缓存
  7. .considerExifParams(true)                          //启用EXIF和JPEG图像格式
  8. .displayer(new RoundedBitmapDisplayer(20))         //设置显示风格这里是圆角矩形
  9. .build();

配制二:

  1. DisplayImageOptions options = new DisplayImageOptions.Builder()
  2. .showImageOnLoading(R.drawable.ic_launcher) //设置图片在下载期间显示的图片
  3. .showImageForEmptyUri(R.drawable.ic_launcher)//设置图片Uri为空或是错误的时候显示的图片
  4. .showImageOnFail(R.drawable.ic_launcher)  //设置图片加载/解码过程中错误时候显示的图片
  5. .cacheInMemory(true)//设置下载的图片是否缓存在内存中
  6. .cacheOnDisc(true)//设置下载的图片是否缓存在SD卡中
  7. .considerExifParams(true)  //是否考虑JPEG图像EXIF参数(旋转,翻转)
  8. .imageScaleType(ImageScaleType.EXACTLY_STRETCHED)//设置图片以如何的编码方式显示
  9. .bitmapConfig(Bitmap.Config.RGB_565)//设置图片的解码类型//
  10. .decodingOptions(android.graphics.BitmapFactory.Options decodingOptions)//设置图片的解码配置
  11. //.delayBeforeLoading(int delayInMillis)//int delayInMillis为你设置的下载前的延迟时间
  12. //设置图片加入缓存前,对bitmap进行设置
  13. //.preProcessor(BitmapProcessor preProcessor)
  14. .resetViewBeforeLoading(true)//设置图片在下载前是否重置,复位
  15. .displayer(new RoundedBitmapDisplayer(20))//是否设置为圆角,弧度为多少
  16. .displayer(new FadeInBitmapDisplayer(100))//是否图片加载好后渐入的动画时间
  17. .build();//构建完成

特别说明:

1、imageScaleType(ImageScaleType imageScaleType) 是设置 图片的缩放方式
     缩放类型mageScaleType:

EXACTLY :图像将完全按比例缩小的目标大小
              EXACTLY_STRETCHED:图片会缩放到目标大小完全
              IN_SAMPLE_INT:图像将被二次采样的整数倍
              IN_SAMPLE_POWER_OF_2:图片将降低2倍,直到下一减少步骤,使图像更小的目标大小
              NONE:图片不会调整
  2、.displayer(BitmapDisplayer displayer)   是设置 图片的显示方式
      显示方式displayer:
             RoundedBitmapDisplayer(int roundPixels)设置圆角图片
             FakeBitmapDisplayer()这个类什么都没做
             FadeInBitmapDisplayer(int durationMillis)设置图片渐显的时间
SimpleBitmapDisplayer()正常显示一张图片

加载中使用的地址

  1. String imageUri = "http://site.com/image.png"; // 网络图片
  2. String imageUri = "file:///mnt/sdcard/image.png"; //SD卡图片
  3. String imageUri = "content://media/external/audio/albumart/13"; // 媒体文件夹
  4. String imageUri = "assets://image.png"; // assets
  5. String imageUri = "drawable://" + R.drawable.image; //  drawable文件
  1. "http://site.com/image.png" // from Web
  2. "file:///mnt/sdcard/image.png" // from SD card
  3. "file:///mnt/sdcard/video.mp4" // from SD card (video thumbnail)
  4. "content://media/external/images/media/13" // from content provider
  5. "content://media/external/video/media/13" // from content provider (video thumbnail)
  6. "assets://image.png" // from assets
  7. "drawable://" + R.drawable.img // from drawables (non-9patch images)

设置显示图片

displayImage方法

可以根据需要使用不同的构造

  1. 1、ImageLoader.getInstance().displayImage(uri, imageView);
  2. 2、  ImageLoader.getInstance().displayImage(uri, imageView, options);
  3. 3、  ImageLoader.getInstance().displayImage(uri, imageView, listener);
  4. 4、  ImageLoader.getInstance().displayImage(uri, imageView, options, listener);
  5. 5、  ImageLoader.getInstance().displayImage(uri, imageView, options, listener, progressListener);
  1. imageUrl   图片的URL地址
  2. imageView  显示图片的ImageView控件
  3. options    DisplayImageOptions配置信息
  4. listener   图片下载情况的监听
  5. progressListener  图片下载进度的监听

loadImage方法

并常用的加载方法:

  1. ImageView mImageView = (ImageView) findViewById(R.id.image);
  2. String imageUrl = "";
  3. ImageLoader.getInstance().loadImage(imageUrl, new SimpleImageLoadingListener(){
  4. @Override
  5. public void onLoadingComplete(String imageUri, View view,
  6. Bitmap loadedImage) {
  7. super.onLoadingComplete(imageUri, view, loadedImage);
  8. mImageView.setImageBitmap(loadedImage);
  9. }
  10. });

初始化一个图片显示大小

  1. ImageView mImageView = (ImageView) findViewById(R.id.image);
  2. String imageUrl = "";
  3. ImageSize mImageSize = new ImageSize(100, 100);
  4. ImageLoader.getInstance().loadImage(imageUrl, mImageSize, new SimpleImageLoadingListener(){
  5. @Override
  6. public void onLoadingComplete(String imageUri, View view,
  7. Bitmap loadedImage) {
  8. super.onLoadingComplete(imageUri, view, loadedImage);
  9. mImageView.setImageBitmap(loadedImage);
  10. }
  11. });

设置options参数加载

  1. ImageView mImageView = (ImageView) findViewById(R.id.image);
  2. String imageUrl = "";
  3. ImageSize mImageSize = new ImageSize(100, 100);  //设置图片显示大小 为100 X 100
  4. //显示图片的配置
  5. DisplayImageOptions options = new DisplayImageOptions.Builder()
  6. .cacheInMemory(true)
  7. .cacheOnDisk(true)
  8. .bitmapConfig(Bitmap.Config.RGB_565)
  9. .build();
  10. ImageLoader.getInstance().loadImage(imageUrl, mImageSize, options, new SimpleImageLoadingListener(){
  11. @Override
  12. public void onLoadingComplete(String imageUri, View view,
  13. Bitmap loadedImage) {
  14. super.onLoadingComplete(imageUri, view, loadedImage);
  15. mImageView.setImageBitmap(loadedImage);
  16. }
  17. });

加载图片的监听

  1. imageLoader.displayImage(imageUrl, imageView, options, new ImageLoadingListener() {
  2. @Override
  3. public void onLoadingStarted() {
  4. //开始加载的时候执行
  5. }
  6. @Override
  7. public void onLoadingFailed(FailReason failReason) {
  8. //加载失败的时候执行
  9. }
  10. @Override
  11. public void onLoadingComplete(Bitmap loadedImage) {
  12. //加载成功的时候执行
  13. }
  14. @Override
  15. public void onLoadingCancelled() {
  16. //加载取消的时候执行
  17. }});

特别说明

在图片加载成功之后(onlaodingComplete()方法中),可以对获取到的Bitmap进行各种大小设置,图形裁剪操作以及动画效果添加等,最后再加图片展示到控件上

  1. /**
  2. * 图片加载第一次显示监听器
  3. * @author Administrator
  4. *
  5. */
  6. private static class AnimateFirstDisplayListener extends SimpleImageLoadingListener {
  7. static final List<String> displayedImages = Collections.synchronizedList(new LinkedList<String>());
  8. @Override
  9. public void onLoadingComplete(String imageUri, View view, Bitmap loadedImage) {
  10. if (loadedImage != null) {
  11. ImageView imageView = (ImageView) view;
  12. // 是否第一次显示
  13. boolean firstDisplay = !displayedImages.contains(imageUri);
  14. if (firstDisplay) {
  15. // 图片淡入效果
  16. FadeInBitmapDisplayer.animate(imageView, 500);
  17. displayedImages.add(imageUri);
  18. }
  19. }
  20. }       @Override
  21. public void onLoadingStarted(String imageUri, View view) {
  22. spinner.setVisibility(View.VISIBLE);
  23. }
  24. @Override
  25. public void onLoadingFailed(String imageUri, View view, FailReason failReason) {
  26. String message = null;
  27. switch (failReason.getType()) {  // 获取图片失败类型
  28. case IO_ERROR:              // 文件I/O错误
  29. message = "Input/Output error";
  30. break;
  31. case DECODING_ERROR:        // 解码错误
  32. message = "Image can't be decoded";
  33. break;
  34. case NETWORK_DENIED:        // 网络延迟
  35. message = "Downloads are denied";
  36. break;
  37. case OUT_OF_MEMORY:         // 内存不足
  38. message = "Out Of Memory error";
  39. break;
  40. case UNKNOWN:               // 原因不明
  41. message = "Unknown error";
  42. break;
  43. }
  44. Toast.makeText(ImagePagerActivity.this, message, Toast.LENGTH_SHORT).show();
  45. }
  46. }

}

设置进度的方法

  1. imageLoader.displayImage(imageUrl, imageView, options, new ImageLoadingListener() {
  2. @Override
  3. public void onLoadingStarted() {
  4. //开始加载的时候执行
  5. }
  6. @Override
  7. public void onLoadingFailed(FailReason failReason) {
  8. //加载失败的时候执行
  9. }
  10. @Override
  11. public void onLoadingComplete(Bitmap loadedImage) {
  12. //加载成功的时候执行
  13. }
  14. @Override
  15. public void onLoadingCancelled() {
  16. //加载取消的时候执行
  17. },new ImageLoadingProgressListener() {
  18. @Override
  19. public void onProgressUpdate(String imageUri, View view, int current,int total) {
  20. //在这里更新 ProgressBar的进度信息
  21. }
  22. });

缓存的清理

  1. @Override
  2. public void onDestroy() {
  3. super.onDestroy();
  4. imageLoader.clearMemoryCache();
  5. imageLoader.clearDiskCache();
  6. }
  1. // 获取占用最大内存
  2. maxMemory = (int) Runtime.getRuntime().maxMemory();
  1. if (maxMemory < 40 * 1024 * 1024) {
  2. ImageLoader.getInstance().clearMemoryCache();
  3. ImageLoader.getInstance().clearDiskCache();

这里可以依据需求来设定,我这里采用的是检测 下内存,如果内存大小小于40M,那么在销毁的时候 ,清理缓存 ,这样处理可以有效的解决下加载图片过程中出现的内存溢出问题(例如 512M内存的手机)

在ListView与GridView中滑动过程中停止加载图片

  1. listView.setOnScrollListener(new PauseOnScrollListener(imageLoader, pauseOnScroll, pauseOnFling));
  2. gridView.setOnScrollListener(new PauseOnScrollListener(imageLoader, pauseOnScroll, pauseOnFling));

第一个参数就是我们的图片加载对象ImageLoader, 第二个是控制是否在滑动过程中暂停加载图片,如果需要暂停传true就行了,第三个参数控制猛的滑动界面的时候图片是否加载

补充说明

如果经常出现OOM(别人那边看到的,觉得很有提的必要)
   ①减少配置之中线程池的大小,(.threadPoolSize).推荐1-5;
   ②使用.bitmapConfig(Bitmap.config.RGB_565)代替ARGB_8888;
   ③使用.imageScaleType(ImageScaleType.IN_SAMPLE_INT)或者.imageScaleType(ImageScaleType.EXACTLY);
   ④避免使用RoundedBitmapDisplayer.他会创建新的ARGB_8888格式的Bitmap对象;
   ⑤使用.memoryCache(new WeakMemoryCache()),不要使用.cacheInMemory();

Android自定义控件ImageViwe(一)——依据控件的大小来设置缩放图片显示
    点击打开链接
    
 Android自定义ImageView(二)——实现双击放大与缩小图片
    点击打开链接
    
 Android自定义控件ImageViwe(三)——随手指进行图片的缩放
   点击打开链接
    
 Android自定义控件ImageViwe(四)——多点触控实现图片的自由移动  
    点击打开链接
    
 Android ListView分组排序显示数据
    点击打开链接
    
 Android自定义下拉刷新功能的ListView
   点击打开链接
    
 Android音乐播放器高级开发
    点击打开链接
    
 Android自定义控件之流式布局
 点击打开链接

Android-Universal-Image-Loader使用介绍的更多相关文章

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

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

  2. Android Universal Image Loader java.io.FileNotFoundException: http:/xxx/lxx/xxxx.jpg

    前段时间在使用ImageLoader异步加载服务端返回的图片时总是出现 java.io.FileNotFoundException: http://xxxx/l046/10046137034b1c0d ...

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

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

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

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

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

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

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

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

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

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

  8. eclipse android sdk content loader一直显示0%的问题解决

    今天上班启动eclipse,发现eclipse 一直卡在android sdk content loader的地方,一直显示为0%.百度后发现很多都是一下解决方法:  关闭Eclipse,删掉Ecli ...

  9. Android SDK content Loader has encountered a problem.parseSdkContent failed

    打开Eclipse,弹出Android SDK content Loader has encountered a problem.parseSdkContent failed,当点击detail按钮, ...

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

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

随机推荐

  1. libevent和libev的区别对比

    参考了这篇文章: http://www.cnblogs.com/Lifehacker/p/whats_the_difference_between_libevent_and_libev_chinese ...

  2. awk中的NR FNR

    shell编程中,awk简直就是一把利器,你能够把它看成shell的一部分,也能够看成一种单独的语言,功能十分强大.今天先来说一说NR与FNR 先准备两个文件: 1.txt,内容为: user pas ...

  3. ssh bitbucket github

    $ ssh-keygen -t rsa -C "mac" $ vi ~/.ssh/config Host bb User git HostName bitbucket.org Id ...

  4. javascript 高级编程系列 - 继承

    1. 原型链继承 (缺点:子类继承父类的引用类型的属性值会在各个实例中共享,创建子类实例时无法向父类构造函数传递参数) // 定义父类构造函数 function SuperClass(father, ...

  5. git clean

    使用git clean清除未加入版控的数据 作者:Level Up  发布日期:2012-12-21 10:48:10       笔者在使用版本控制软件时,不知为何常常会有些暂存的数据产生.像是下面 ...

  6. kubernetes容器编排之定义环境变量以及通过downwardapi把pod信息作为环境变量传入容器内

    系列目录 在学习docker的时候,大家可能经常看到不少示例在docker run的时候指定环境变量(比如wordpress的docker示例就是通过环境变量传入账户和密码到容器内).这里之所以经常用 ...

  7. caffe搭建以及初步学习--win7-vs2013-gtx650tiboost-cuda8.0-cifar10训练和测试-2-快速解决方案cifar10_quick_solver.prototxt

    首先安装好显卡----已经装好了?喜大普奔!没装好?那就用cpu,也是一样的. 拷贝cudnn v5.0 头文件和库文件以及执行文件到cuda8中 -------------------------- ...

  8. JSP 随记

    jstl <c:forEach> 遍历,多个<option>时显示"全部".单个 option时,默认选中! 引入:<%@ taglib prefix ...

  9. poj 3233 Matrix Power Series(矩阵二分,高速幂)

    Matrix Power Series Time Limit: 3000MS   Memory Limit: 131072K Total Submissions: 15739   Accepted:  ...

  10. Attempting to write a row[5] in the range [0,394] that is already written to disk.

    我用POI操作excel写数据,然后就报这个错了 XSSFWorkbook workbook = new XSSFWorkbook(); SXSSFWorkbook sxssfWorkbook = n ...