Android图片加载框架 Universal-Image-Loader 妙用

Android开源框架Universal-Image-Loader就像图片加载守护者,为我们提供了丰富的功能特性:

(1)多线程加载图像(异步或同步);

(2)高度可定制化imageloader配置(线程池、图片下载器、解码器、内存和磁盘缓存、显示图像选项等);

(3)每一个显示图像有许多自定义选项(存根图片,缓存开关,解码选项,位图处理和显示等);

(4)支持内存和磁盘上的图像缓存(设备的文件系统和SD卡);

(5)监听加载过程(包括下载进度);

下来我们详解如何配置使用Universal-Image-Loader来加载网络图片

1.下载Universal-Image-Loader

Github下载:

https://github.com/nostra13/Android-Universal-Image-Loader

Maven下载:

http://central.maven.org/maven2/com/nostra13/universalimageloader/universal-image-loader/

2.使用Universal-Image-Loader

(1)首先关联Universal-Image-Loader的库文件。然后在Application的onCreate中初始化ImageLoader

public class MyApplication extends Application{
    @Override
    public void onCreate() {
        super.onCreate();
        initImageLoader(this);
    }

    public static void initImageLoader(Context context) {
        // This configuration tuning is custom. You can tune every option, you may tune some of them,
        // or you can create default configuration by
        ImageLoaderConfiguration.Builder config = new ImageLoaderConfiguration.Builder(context);
        config.threadPriority(Thread.NORM_PRIORITY - 2);
        config.denyCacheImageMultipleSizesInMemory(); // 不会在内存中缓存多个大小的图片
        config.diskCacheFileNameGenerator(new Md5FileNameGenerator()); // 为了保证图片名称唯一
        config.diskCacheSize(50 * 1024 * 1024); // 50 MiB
        // 内存缓存大小默认是:app可用内存的1/8
        config.tasksProcessingOrder(QueueProcessingType.LIFO);
        config.writeDebugLogs(); // Remove for release app
        // Initialize ImageLoader with configuration.
        ImageLoader.getInstance().init(config.build());
    //ImageLoader.getInstance().init(ImageLoaderConfiguration.createDefault(this));
    }
}

(2)在AndroidManifest中配置Application

(3)在MyImageApadter中加载图片,初始化DisplayImageOptions(为了方便使用,我们将其抽取成一个类)

/**
 * Universal-Image-Loader-master options参数
 */
public interface ImageLoaderOptions {
    DisplayImageOptions options = new DisplayImageOptions.Builder()
        .showImageOnLoading(R.drawable.ic_default)// 加载图片过程中显示哪张图片
        .showImageForEmptyUri(R.drawable.ic_default)// url为空的话显示哪张图片
        .showImageOnFail(R.drawable.ic_default)// 加载图片失败显示哪张图片
        .cacheInMemory(true)// 在内存中缓存该图片
        .cacheOnDisk(true)// 在硬盘中缓存该图片
        .imageScaleType(ImageScaleType.EXACTLY)// 将会对图片进一步缩放,缩放的程度参考ImageVIew的宽高
        .bitmapConfig(Bitmap.Config.RGB_565)// 该种渲染模式也是比较节省内存的
        .considerExifParams(true)// 会识别图片的方向信息
        // .displayer(new FadeInBitmapDisplayer(800)).build();//渐渐显示的动画效果
        .displayer(new RoundedBitmapDisplayer(28)).build();// 圆角的效果
    // 显示大图的options
    DisplayImageOptions pager_options = new DisplayImageOptions.Builder()
        .showImageOnLoading(R.drawable.ic_default)// 加载图片过程中显示哪张图片
        .showImageForEmptyUri(R.drawable.ic_default)// url为空的话显示哪张图片
        .showImageOnFail(R.drawable.ic_default)// 加载图片失败显示哪张图片
        .cacheInMemory(false)// 不在内存中缓存该图片
        .cacheOnDisk(true)// 在硬盘中缓存该图片
        .imageScaleType(ImageScaleType.EXACTLY)// 将会对图片进一步缩放,缩放的程度参考ImageVIew的宽高
        .bitmapConfig(Bitmap.Config.RGB_565)// 该种渲染模式也是比较节省内存的
        .considerExifParams(true)// 会识别图片的方向信息
        .displayer(new FadeInBitmapDisplayer(500)).build();// 渐渐显示的动画效果
    // .displayer(new RoundedBitmapDisplayer(28)).build();// 圆角的效果
}

(4)在getView方法中调用加载图片

/**
 * displayImage(uri, imageView, options, listener, progressListener);
 * 参数解析:
 *      imageUrl : 图片的URL地址
 *      imageView : 显示图片的ImageView控件
 *      options : DisplayImageOptions配置信息
 *      listener : 图片下载情况的监听
 *      progressListener : 图片下载进度的监听
 */
//加载图片
ImageLoader.getInstance().displayImage(Url.IMAGE, holder.iv_icon, ImageLoaderOptions.options);

–>拓展

渐渐显示的动画效果和圆角的效果不能同时设置,解决方法:我们在(3)中设置圆角效果,然后舍弃(4)的方法加载图片,而采用下面方法,到此,我们鱼与熊掌兼得。

//加载图片
ImageLoader.getInstance().displayImage(Url.IMAGE,holder.iv_icon, options
        ,new SimpleImageLoadingListener(){
    @Override
    public void onLoadingComplete(String imageUri, View view,
            Bitmap loadedImage) {
        super.onLoadingComplete(imageUri, view, loadedImage);
        FadeInBitmapDisplayer.animate(view, 800);//渐渐显示的效果
    }
});

3.使用中常见问题与解决方法

(1)遇到横屏大图(width>height),低配置的手机或有的手机无法显示图片的问题

解决方法:在应用中配置ImageLoaderConfiguration参数,最好在Application中进行设置和配置(如上的MyApplication.java中),只能配置一次,如多次配置,则系统默认第一次的配置参数。

ImageLoaderConfiguration config = new ImageLoaderConfiguration.Builder(
    getApplicationContext())
        .memoryCacheExtraOptions(480, 800) // 保存每个缓存图片的最大长和宽
        .threadPoolSize(3) // 线程池的大小 这个其实默认就是3
        .threadPriority(Thread. NORM_PRIORITY - 2) //设置线程优先级
        .denyCacheImageMultipleSizesInMemory() // 当同一个Uri获取不同大小的图片,缓存到内存时,只缓存一个。默认会缓存多个不同的大小的相同图片
        .memoryCache( new UsingFreqLimitedMemoryCache(2 * 1024 * 1024))
        .memoryCacheSize(2 * 1024 * 1024) // 设置缓存的最大字节
        .tasksProcessingOrder(QueueProcessingType. LIFO) //设置图片下载和显示的工作队列排序
        .defaultDisplayImageOptions(DisplayImageOptions. createSimple())
        .imageDownloader(new BaseImageDownloader(getApplicationContext(),
                5 * 1000, 30 * 1000))// connectTimeout : 超时时间
        .writeDebugLogs().build(); // 开始构建
ImageLoader. getInstance().init(config); // 全局初始化此配置

按上面的设置和配置就解决了横屏大图在某些手机上不显示的问题,建议在Application中进行设置和配置,代码中配置的缺点:用一次配一次。

(2)低配置手机中大量图片时经常发生OOM的问题

项目中图片数量大、大小也大,在后台收集到的crash信息中看到发生了大量的OOM现象。

解决方法:

1)禁用在内存中缓存cacheInMemory(false)

2)减少配置的线程池的大小(.threadPoolSize(…)),建议1~5

3)在显示选项中使用 .bitmapConfig(Bitmap.Config.RGB_565) 因为RGB_565模式消耗的内存比ARGB_8888模式少两倍

4)配置中使用 .memoryCache(newWeakMemoryCache()) 或者完全禁用在内存中缓存

5)在显示选项中使用.imageScaleType(ImageScaleType.EXACTLY) 或 .imageScaleType(ImageScaleType.IN_SAMPLE_INT)

6)避免使用 RoundedBitmapDisplayer. 调用的时候它使用ARGB-8888模式创建了一个新的Bitmap对象来显示

上面的条件,不一定都这样设置,可能改变其中的一些选项进行设置就能解决问题,对此要灵活运用

4.相关使用技巧

(1)只有在你需要让Image的尺寸比当前设备的尺寸大的时候,你才需要配置maxImageWidthForMemoryCache( )和maxImageHeightForMemoryCache( )这两个参数,比如缩放图片的时候。其他情况下,不需要做这些配置,因为默认的配置会根据屏幕尺寸以最节约内存的方式处理Bitmap。

(2)在设置中配置线程池的大小。一个大的线程池会允许多条线程同时工作,但是也会显著的影响到UI线程的速度。但是可以通过设置一个较低的优先级来解决:当ImageLoader在使用的时候,可以降低它的优先级,这样UI线程会更加流畅。在使用ListView的时候,UI 线程经常会不太流畅,所以在你的程序中最好设置threadPoolSize( )和threadPriority( )这两个参数来优化你的应用。

(3)memoryCache( )和memoryCacheSize( )这两个参数会互相覆盖,所以在ImageLoaderConfiguration中使用一个即可。

(4)diskCacheSize( )、diskCache( )和diskCacheFileCount( )这三个参数会互相覆盖,只使用一个即可。

特别注意:不要使用discCacheSize( )、discCache( )和discCacheFileCount( )这三个参数,因为他们已经弃用了。

时间: 2024-10-30 13:56:38

Android图片加载框架 Universal-Image-Loader 妙用的相关文章

Android图片加载框架最全解析(二),从源码的角度理解Glide的执行流程

转载请注明出处:http://blog.csdn.net/guolin_blog/article/details/53939176 本文同步发表于我的微信公众号,扫一扫文章底部的二维码或在微信搜索 郭霖 即可关注,每天都有文章更新. 在本系列的上一篇文章中,我们学习了Glide的基本用法,体验了这个图片加载框架的强大功能,以及它非常简便的API.还没有看过上一篇文章的朋友,建议先去阅读 Android图片加载框架最全解析(一),Glide的基本用法 . 在多数情况下,我们想要在界面上加载并展示一

一起写一个Android图片加载框架

本文会从内部原理到具体实现来详细介绍如何开发一个简洁而实用的Android图片加载缓存框架,并在内存占用与加载图片所需时间这两个方面与主流图片加载框架之一Universal Image Loader做出比较,来帮助我们量化这个框架的性能.通过开发这个框架,我们可以进一步深入了解Android中的Bitmap操作.LruCache.LruDiskCache,让我们以后与Bitmap打交道能够更加得心应手.若对Bitmap的大小计算及inSampleSize计算还不太熟悉,请参考这里:高效加载Bit

Android图片异步加载框架Universal Image Loader的源码分析

项目地址:https://github.com/nostra13/android-universal-image-loader 1. 功能介绍 1.1 Android Universal Image Loader Android Universal Image Loader 是一个强大的.可高度定制的图片缓存,本文简称为UIL. 简单的说 UIL 就做了一件事--获取图片并显示在相应的控件上. 1.2 基本使用 1.2.1 初始化 添加完依赖后在Application或Activity中初始化I

Android 图片加载框架Universal-Image-Loader源码解析

Universal-Image-Loader(项目地址)可以说是安卓知名图片开源框架中最古老.使用率最高的一个了.一张图片的加载对于安卓应用的开发也许是件简单的事,但是如果要同时加载大量的图片,并且图片用于ListView.GridView.ViewPager等控件,如何防止出现OOM.如何防止图片错位(因为列表的View复用功能).如何更快地加载.如何让客户端程序员用最简单的操作完成本来十分复杂的图片加载工作,成了全世界安卓应用开发程序员心头的一大难题,所幸有了Universal-Image-

初探Google推荐Android图片加载框架Glide

简介 运行Demo 安装依赖包 现在编译好的依赖 Gradle Maven Proguard 简单使用 设置暂未图和加载失败图 加载封面图 从其他路径加载图片 加载图片到其他控件 调试信息 开启请求响应信息 开启工作流日志 简介 现在在Android上加载图片的框架都已经烂大街了,所以我们这里也不说谁好谁坏,当然也不做比较了,因为得出的结果都是片面的,没有谁好谁坏只有适不适合需求罢了 起因是在泰国举行的谷歌开发者论坛上,谷歌为我们介绍了一个叫Glide 的图片加载库,作者是bumptech.这个

Android 使用图片异步加载框架Universal Image Loader的问题

使用的Jar包 问题:        optionsm = new DisplayImageOptions.Builder() .displayer(new RoundedBitmapDisplayer(20)) .build();   这里.displayer(new RoundedBitmapDisplayer(20))的时候设置圆角报错,.displayer(new SimpleBitmapDisplayer())这样正常显示图片就不报错. 版权声明:本文为博主原创文章,未经博主允许不得转

Android中图片加载框架Glide解析2----从源码的角度理解Glide的执行流程

转载地址:http://blog.csdn.net/guolin_blog/article/details/53939176 在本系列的上一篇文章中,我们学习了Glide的基本用法,体验了这个图片加载框架的强大功能,以及它非常简便的API.还没有看过上一篇文章的朋友,建议先去阅读 Android图片加载框架最全解析(一),Glide的基本用法 . 在多数情况下,我们想要在界面上加载并展示一张图片只需要一行代码就能实现,如下所示: Glide.with(this).load(url).into(i

优雅地实现Android主流图片加载框架封装,可无侵入切换框架

项目开发中,往往会随着需求的改变而切换到其它图片加载框架上去.如果最初代码设计的耦合度太高,那么恭喜你,成功入坑了.至今无法忘却整个项目一行行去复制粘贴被支配的恐惧.:) 那么是否存在一种方式 能够一劳永逸地解决这个痛点呢?下面我们来分析一下图片加载框架面对的现状和解决思路. 问题现状 一个优秀的框架一般在代码设计的时候已经封装很不错了,对于开发者而言框架的使用也是很方便,但是为什么说我们往往还要去做这方面的框架封装呢?原因很简单,实际项目开发中,我们不得不面对着日新月异的需求变化,想要在这个变

Android中常见的图片加载框架

图片加载涉及到图片的缓存.图片的处理.图片的显示等.而随着市面上手机设备的硬件水平飞速发展,对图片的显示要求越来越高,稍微处理不好就会造成内存溢出等问题.很多软件厂家的通用做法就是借用第三方的框架进行图片加载. 开源框架的源码还是挺复杂的,但使用较为简单.大部分框架其实都差不多,配置稍微麻烦点,但是使用时一般只需要一行,显示方法一般会提供多个重载方法,支持不同需要.这样会减少很不必要的麻烦.同时,第三方框架的使用较为方便,这大大的减少了工作量.提高了开发效率.本文主要介绍四种常用的图片加载框架,