Android图片加载框架介绍

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_21983189/article/details/76636977

在Android开发中,图片绝对是个然不开的话题,那么在图片的加载展示和davik内存的管理上,我们的管理策略就显得格外重要,稍不严谨就会出现OOM。图片的加载包括图片的缓存、图片的处理、图片的显示等,而通常大家都会使用三方框架,第三方框架的使用较为方便,这大大的减少了工作量、提高了开发效率, 大部分框架其实都差不多,配置稍微麻烦点,但是使用时一般只需要一行,显示方法一般会提供多个重载方法,支持不同需要, 这样会减少很不必要的麻烦 。 今天我们来一起认识一下目前最流行的几个图片加载框架吧!方便大家在平常的开发中根据具体项目特点进行选择使用!分别是Fresco、ImageLoader、 Picasso、 Glide,包括他们各自的优缺点、使用步骤等等。

Fresco

Fresco是Facebook 推出的开源图片缓存工具,主要特点:两块内存缓存加上 Native 缓存构成了三级缓存,支持流式,可以类似网页上模糊渐进式显示图片,对多帧动画图片支持更好,如 Gif、WebP。它的优点是其他几个框架没有的, 或者说是其他几个框架的短板。
优点:
1. 图片存储在安卓系统的匿名共享内存, 而不是虚拟机的堆内存中, 图片的中间缓冲数据也存放在本地堆内存, 所以, 应用程序有更多的内存使用, 不会因为图片加载而导致oom, 同时也减少垃圾回收器频繁调用回收 Bitmap 导致的界面卡顿, 性能更高。
2. 图片可以以任意的中心点显示在 ImageView, 而不仅仅是图片的中心。
3. JPEG 图片改变大小也是在 native 进行的, 不是在虚拟机的堆内存, 同样减少 OOM。
4. 支持JPEG渐进的加载方式,在线图片可以由模糊到清晰展示。
5. 很好的支持 GIF 图片的显示。

缺点
1. 框架较大, 影响 Apk 体积
2. 使用较繁琐

使用步骤:
1.引入 Fresco,包括两种方式,在线和离线。
在线引入依赖脚本形式,在dependencies中添加依赖:

compile 'com.facebook.fresco:fresco:latest.release'

引入离线引入,需要导入的arr包较多,包括:

compile(name: 'drawee-latest.release', ext: 'aar')
compile(name: 'fbcore-latest.release', ext: 'aar')
compile(name: 'imagepipeline-latest.release', ext: 'aar')
compile(name: 'imagepipeline-base-latest.release', ext: 'aar')
compile files('libs/bolts-android-latest.release.jar') 

还需要来到project build.gradle里面, 在allprojects方法体加入:

allprojects {
    repositories {
       jcenter()
        //add begin
        flatDir {
          dirs 'libs'
        } 
       //add end
     }

2.需要在程序入口方法里面进行初始化。在oncreate方法中添加初始化语句:

Fresco.initialize(context);

3.在布局文件中,需要使用图片展示地方,使用它定义的控件:

<com.facebook.drawee.view.SimpleDraweeView
     android:id="@+id/iv_img"
     android:layout_width="150dp"
     android:layout_height="150dp"
     android:src="@mipmap/ic_launcher"
     fresco:fadeDuration="300"
     fresco:roundingBorderColor="#ccc"
     fresco:roundingBorderWidth="2dp"/>

4.设置静态图片,在代码中具体写如下代码 :

// 图片加载
Uri uri = Uri.parse(data.url);
iv_img.setImageURI(uri); 

5.设置gif图片,在代码中具体写如下代码:

DraweeController gifController =Fresco.newDraweeControllerBuilder().setUri(uri).setAutoPlayAnimations(true).build();
iv_img.setController(gifController);

ImageLoader

结构:
ImageLoader是一个比较老的成熟框架,国内主要使用的应用有淘宝、京东、聚划算等,整个库分为 ImageLoaderEngine,Cache 及 ImageDownloader,ImageDecoder,BitmapDisplayer,BitmapProcessor 五大模块,Cache 分为 MemoryCache 和 DiskCache 两部分。

加载原理:
ImageLoader接收到任务后通过ImageLoaderEngine分发给线程池执行,然后通过 Cache 及 ImageDownloader 获取图片,中间可能经过 BitmapProcessor 和 ImageDecoder 处理,最终转换为Bitmap 交给 BitmapDisplayer 在 ImageAware中显示。

特点:稳定, 加载速度适中

优点:
1.支持下载进度监听。
2.可以在 View 滚动中暂停图片加载,通过 PauseOnScrollListener 接口可以在 View 滚动中暂停图片加载。
3.默认实现多种内存缓存算法 这几个图片缓存都可以配置缓存算法,不过 ImageLoader 默认实现了较多缓存算法,如 Size 最大先删除、使用最少先删除、最近最少使用、先进先删除、时间最长先删除等。
4.支持本地缓存文件名规则定义

缺点:
不支持GIF图片加载, 使用稍微繁琐, 并且缓存机制没有和 http 的缓存很好的结合, 完全是自己的一套缓存机制

使用步骤:
1. 在Application子类中的onCreate方法中初始化ImageLoaderConfiguration:

ImageLoaderConfiguration config = new ImageLoaderConfiguration.Builder(context)//
  .threadPriority(Thread.NORM_PRIORITY - 2)//
  .denyCacheImageMultipleSizesInMemory()//
  .diskCacheFileNameGenerator(new Md5FileNameGenerator())//
  .diskCacheSize(50 * 1024 * 1024) // 50 Mb
  .memoryCache(new LruMemoryCache(4 * 1024 * 1024)).tasksProcessingOrder(QueueProcessingType.LIFO)//
  .writeDebugLogs() // Remove for release app
  .build();
 // Initialize ImageLoader with configuration.
 ImageLoader.getInstance().init(config);

2.在具体的地方直接使用:

//图片加载
// ImageLoader.getInstance().displayImage(url, image);
DisplayImageOptions option = new DisplayImageOptions.Builder()
        .resetViewBeforeLoading(true)
        .cacheOnDisk(true)
        .imageScaleType(ImageScaleType.EXACTLY)
        .bitmapConfig(Bitmap.Config.RGB_565)
        .considerExifParams(true)
        .displayer(new FadeInBitmapDisplayer(300))
        .build();
ImageLoader.getInstance().displayImage(url, image,option);

3.加载各种格式图片:
// 网络图片
String imageUri = “http://site.com/image.png“;
//SD卡图片
String imageUri = “file:///mnt/sdcard/image.png”;
// 媒体文件夹
String imageUri = “content://media/external/audio/albumart/13”;
// assets
String imageUri = “assets://image.png”;
// drawable文件
String imageUri = “drawable://” + R.drawable.image;

4.丰富的缓存策略
强引用缓存: LruMemoryCache(默认缓存);
强引用和弱引用相结合的缓存:
UsingFreqLimitedMemoryCache(如果缓存的图片总量超过限定值,先删除使用频率最小的bitmap)
LRULimitedMemoryCache(这个也是使用的lru算法,和LruMemoryCache不同的是,他缓存的是bitmap的弱引用)
FIFOLimitedMemoryCache(先进先出的缓存策略,当超过设定值,先删除最先加入缓存的bitmap)
LargestLimitedMemoryCache(当超过缓存限定值,先删除最大的bitmap对象)
LimitedAgeMemoryCache(当 bitmap加入缓存中的时间超过我们设定的值,将其删除)
弱引用缓存:
WeakMemoryCache(这个类缓存bitmap的总大小没有限制,唯一不足的地方就是不稳定,缓存的图片容易被回收硬盘缓存)
FileCountLimitedDiscCache(可以设定缓存图片的个数,当超过设定值,删除掉最先加入到硬盘的文件)
LimitedAgeDiscCache(设定文件存活的最长时间,当超过这个值,就删除该文件)
TotalSizeLimitedDiscCache(设定缓存bitmap的最大值,当超过这个值,删除最先加入到硬盘的文件)
UnlimitedDiscCache(这个缓存类没有任何的限制)

Picasso

Picasso 是 Square公司开源的项目,且他的主导者是 JakeWharton,这个公司还有著名的开源框架android-times-square、leakcanary、okhttp、retrofit,这些个个都是非常流行的!

优点
1.自带统计监控功能。支持图片缓存使用的监控,包括缓存命中率、已使用内存大小、节省的流量等。
2.支持优先级处理。每次任务调度前会选择优先级高的任务,比如 App 页面中 Banner 的优先级高于 Icon 时就很适用。
3.支持延迟到图片尺寸计算完成加载
4.支持飞行模式、并发线程数根据网络类型而变。 手机切换到飞行模式或网络类型变换时会自动调整线程池最大并发数,比如 wifi 最大并发为 4,4g 为 3,3g 为 2。 这里 Picasso 根据网络类型来决定最大并发数,而不是 CPU 核数。
5.“无”本地缓存。无”本地缓存,不是说没有本地缓存,而是 Picasso 自己没有实现,交给了 Square 的另外一个网络库 okhttp 去实现,这样的好处是可以通过请求 Response Header 中的 Cache-Control 及 Expired 控制图片的过期时间。

缺点:
1.原始框架不支持 GIF;
2. 它缓存的图片是未缩放的,;
3. 并且默认使用 ARGB_8888 格式缓存图片, 缓存体积大

使用步骤:
1.添加依赖库:

compile 'com.squareup.picasso:picasso:2.5.2'

2.加载图片

//图片加载
Picasso.with(mContext)    //创建Picasso 
      .load(data.url)    //传入路径 
      .fade(300)      //淡化效果时长
      .into(holder.ivIcon); //图片加载到那个位置

Glide

谷歌为我们介绍了一个名叫 Glide 的图片加载库,作者是bumptech。这个库被广泛的运用在google的开源项目中,包括2014年google I/O大会上发布的官方app。 Glide可以说是 Picasso 的升级版, 有 Picasso 的优点, 并且支持 GIF 图片加载显示, 图片缓存也会自动缩放, 默认使用 RGB_565 格式缓存图片, 是 Picasso 缓存体积的一半。

结构:
整个库分为 RequestManager(请求管理器),Engine(数据获取引擎)、 Fetcher(数据获取器)、MemoryCache(内存缓存)、DiskLRUCache、Transformation(图片处理)、Encoder(本地缓存存储)、Registry(图片类型及解析器配置)、Target(目标) 等模块。

加载原理:
Glide 收到加载及显示资源的任务,创建 Request 并将它交给RequestManager,Request 启动 Engine 去数据源获取资源(通过 Fetcher ),获取到后 Transformation 处理后交给 Target。Glide 依赖于 DiskLRUCache、GifDecoder 等开源库去完成本地缓存和 Gif 图片解码工作。

优点:
1.不仅仅可以进行图片缓存还可以缓存媒体文件。Glide 不仅是一个图片缓存,它支持 Gif、WebP、缩略图。甚至是 Video,所以更该当做一个媒体缓存。
2.支持优先级处理。
3.与 Activity/Fragment 生命周期一致,支持 trimMemory。Glide 对每个 context 都保持一个 RequestManager,通过 FragmentTransaction 保持与 Activity/Fragment 生命周期一致,并且有对应的 trimMemory 接口实现可供调用。
4.支持 okhttp、Volley。Glide 默认通过 UrlConnection 获取数据,可以配合 okhttp 或是 Volley 使用。实际 ImageLoader、Picasso 也都支持 okhttp、Volley。
5.内存友好。Glide 的内存缓存有个 active 的设计,从内存缓存中取数据时,不像一般的实现用 get,而是用 remove,再将这个缓存数据放到一个 value 为软引用的 activeResources map 中,并计数引用数,在图片加载完成后进行判断,如果引用计数为空则回收掉。内存缓存更小图片,Glide 以 url、view_width、view_height、屏幕的分辨率等做为联合 key,将处理后的图片缓存在内存缓存中,而不是原始图片以节省大小与 Activity/Fragment 生命周期一致,支持 trimMemory。
图片默认使用默认 RGB_565 而不是 ARGB_888,虽然清晰度差些,但图片更小,也可配置到 ARGB_888。
6.Glide 可以通过 signature 或不使用本地缓存支持 url 过期
7.通过参数类DiskCacheStrategy可以指定缓存的图片是否是缩略图
8.支持网络图片加载、本地资源ID加载、byte[]数据格式转换、File文件转换

使用步骤:
1.添加依赖库:

compile 'com.github.bumptech.glide:glide:3.7.0'

2.使用

//根据id加载本地资源
Glide.with(context).load(localImgId).crossFade(300).into(view);
//根据URL加载资源
Glide.with(context).load(url).crossFade().into(view);
//根据指定的file加载资源
Glide.with(context).load(file).crossFade().into(view);
//根据byte[]加载图片
Glide.with(context).load(byte).crossFade(300).into(view);
//加载gif图,这里用SimpleTarget是防治有的图片第一次加载的时候只显示占位图,第二次才显示正常的图片,非gif图的话参数就是GlideDrawable
Glide.with(context).load(localImgId).asGif().placeholder(defaultSrc).error(defaultSrc).into(new SimpleTarget<GifDrawable>() {
            @Override
            public void onResourceReady(GifDrawable resource, GlideAnimation<? super GifDrawable> glideAnimation) {
                view.setImageDrawable(resource);
            }
        });

原文链接:http://www.cnblogs.com/huangjie123/p/6171011.html

猜你喜欢

转载自blog.csdn.net/qq_21983189/article/details/76636977
今日推荐