简介

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. vue框架及其

    Vue常用UI框架 PC端: 1. ElementUI:http://element-cn.eleme.io/#/zh-CN 2. iView:https://www.iviewui.com/ 3. ...

  2. linux mysql添加用户名并实现远程访问

    第一步:登陆linux,在终端登陆mysql #mysql -u root -p 第二步:查询系统用户列表并进行添加用户 mysql>select host,user,password from ...

  3. 临远的activiti教程

    1. 简介 协议 下载 源码 必要的软件 JDK 6+ Eclipse Indigo 和 Juno 报告问题 试验性功能 内部实现类 2. 开始学习 一分钟入门 安装Activiti 安装Activi ...

  4. GDB调试多线程程序

    gdb有thread相关命令,如info thread(简写成info th)显示线程消息,b xx thread yy可以针对某个thread设置断点,thread xx(简写成thr xx)切换到 ...

  5. Cucumber+Rest Assured快速搭建api自动化测试平台

    转载:http://www.jianshu.com/p/6249f9a9e9c4 什么是Cucumber?什么是BDD?这里不细讲,不懂的直接查看官方:https://cucumber.io/ 什么是 ...

  6. ios 清理缓存(EGO)

    一段清理缓存的代码例如以下: dispatch_async( dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,) , ^{ NSSt ...

  7. 兔子--html,js,php,ASP,ASP.NET,JSP的关系

    html是超文本链接语言.是静态的.显示在client.仅仅用HTML做出来的网页是静态网页.没不论什么交互功能. JS是一种基于对象和事件驱动的脚本语言,执行在client.是一种比較简单的编程语言 ...

  8. JavaScript 工厂模式和订阅模式

    设计模式的好处: 代码规范 // 例如表单验证,两个 input ,一个用户名,一个密码 // 通常做法是 function checkUser(){ //..... } function check ...

  9. GTK入门学习:布局练习之计算器

    接下来,我们做一个布局练习.例如以下图: 我们用表格布局实现,表格布局參考坐标例如以下: 这里我们用到行编辑控件( GtkEntry ). 行编辑的创建: GtkWidget * gtk_entry_ ...

  10. 模式识别之分类器knn---c语言实现带训练数据---反余弦匹配

    邻近算法   KNN算法的决策过程 k-Nearest Neighbor algorithm是K最邻近结点算法(k-Nearest Neighbor algorithm)的缩写形式,是电子信息分类器算 ...