`
ch_kexin
  • 浏览: 899100 次
  • 性别: Icon_minigender_2
  • 来自: 青岛
社区版块
存档分类
最新评论

那些我们用过的Android开源图片加载框架

 
阅读更多

一、UniversalImageLoader

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

UIL可以算是老牌最火的图片加载库了,使用过这个框架的项目可以说多到教你做人,我第一次把第三方开源图片加载框架加入项目中的就是这个了,当时感觉瞬间逼格上涨,妈妈再也不用担心出现OOM和ListView图片错乱了。可惜的是该作者在项目中说明已经停止了对该项目的维护。这就意味着以后任何的 bug 都不会修复,任何的新特性都不会再继续开发,所以毫无疑问 UIL 不推荐在项目中使用了。

使用方法:

1、在Application全局变量中的进行配置ImageLoaderConfiguration,有选择性的进行配置,具体代码如下:

File cacheDir = StorageUtils.getCacheDirectory(context);  //缓存文件夹路径  
ImageLoaderConfiguration config = new ImageLoaderConfiguration.Builder(context)  
        .memoryCacheExtraOptions(480, 800) // default = device screen dimensions 内存缓存文件的最大长宽  
        .diskCacheExtraOptions(480, 800, null)  // 本地缓存的详细信息(缓存的最大长宽),最好不要设置这个   
        .taskExecutor(...)  
        .taskExecutorForCachedImages(...)  
        .threadPoolSize(3) // default  线程池内加载的数量  
        .threadPriority(Thread.NORM_PRIORITY - 2) // 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) // 50 Mb sd卡(本地)缓存的最大值  
        .diskCacheFileCount(100)  // 可以缓存的文件数量   
        // default为使用HASHCODE对UIL进行加密命名, 还可以用MD5(new Md5FileNameGenerator())加密  
        .diskCacheFileNameGenerator(new HashCodeFileNameGenerator())   
        .imageDownloader(new BaseImageDownloader(context)) // default  
        .imageDecoder(new BaseImageDecoder()) // default  
        .defaultDisplayImageOptions(DisplayImageOptions.createSimple()) // default  
        .writeDebugLogs() // 打印debug log  
        .build(); //开始构建  
     //全局初始化此配置
        ImageLoader.getInstance().init(config);

 

 2、针对每次加载任务进行配置DisplayImageOptions

DisplayImageOptions options = new DisplayImageOptions.Builder()  
        .showImageOnLoading(R.drawable.ic_stub) // 设置图片下载期间显示的图片  
        .showImageForEmptyUri(R.drawable.ic_empty) // 设置图片Uri为空或是错误的时候显示的图片  
        .showImageOnFail(R.drawable.ic_error) // 设置图片加载或解码过程中发生错误显示的图片  
        .resetViewBeforeLoading(false)  // default 设置图片在加载前是否重置、复位  
        .delayBeforeLoading(1000)  // 下载前的延迟时间  
        .cacheInMemory(false) // default  设置下载的图片是否缓存在内存中  
        .cacheOnDisk(false) // default  设置下载的图片是否缓存在SD卡中  
        .preProcessor(...)  
        .postProcessor(...)  
        .extraForDownloader(...)  
        .considerExifParams(false) // default  
        .imageScaleType(ImageScaleType.IN_SAMPLE_POWER_OF_2) // default 设置图片以如何的编码方式显示  
        .bitmapConfig(Bitmap.Config.ARGB_8888) // default 设置图片的解码类型  
        .decodingOptions(...)  // 图片的解码设置  
        .displayer(new SimpleBitmapDisplayer()) // default  还可以设置圆角图片new RoundedBitmapDisplayer(20)  
        .handler(new Handler()) // default  
        .build(); 

 UIL支持的图片加载格式如下:

String imageUri ="http://site.com/image.png"; // from Web

String imageUri ="file:///mnt/sdcard/image.png"; // from SD card

String imageUri ="content://media/external/audio/albumart/13";
 // from content provider

String imageUri ="assets://image.png"; // from assets

String imageUri ="drawable://"+ R.drawable.image; // from drawables (only images, non-9patch)

 下面简单分析一下,UIL框架的加载原理:

1、ImageLoader图片加载器,对外的主要 API,采取了单例模式,用于图片的加载和显示。

2、MemoryCache图片内存换成。默认使用了 LRU 算法。 LRU: Least Recently Used 近期最少使用算法, 选用了基于链表结构的 LinkedHashMap 作为存储结构。假设情景:内存缓存设置的阈值只够存储两个 bitmap 对象,当 put 第三个 bitmap 对象时,将近期最少使用的 bitmap 对象移除。

3、DiskCache图片磁盘缓存,默认使用LruDiskCache算法,在缓存满时删除最近最少使用的图片;缓存目录下名为journal的文件记录缓存的所有操作

4、图片加载流程

1.判断图片的内存缓存是否存在,若存在直接执行步骤 8;

2.判断图片的磁盘缓存是否存在,若存在直接执行步骤 5;

3.ImageDownloader从网络上下载图片;

4.将图片缓存在磁盘上;

5.ImageDecoder将图片 decode 成 bitmap 对象;

6.BitmapProcessor根据DisplayImageOptions配置对图片进行预处理(Pre-process Bitmap);

7.将 bitmap 对象缓存到内存中;

8.根据DisplayImageOptions配置对图片进行后处理(Post-process Bitmap);

9.执行DisplayBitmapTask将图片显示在相应的控件上。

二、Picasso

 项目地址:https://github.com/square/picasso

Picasso是Square公司开源的一个Android平台上的图片加载框架,简单易用,一句话搞定项目中的图片加载,好用到令人发指。

使用一句话:Picasso.with(this).load("url").placeholder(R.mipmap.ic_default).into(imageView);

原理简要分析:

1、Picasso.with(Context):入手

public static Picasso with(Contextcontext){
           if(singleton==null){
                   synchronized(Picasso.class){
                      if(singleton==null){
                         singleton=newBuilder(context).build();
                      }
                   }
           }
return singleton;}

 单列模式,保证多线程情况下,也只有一个实例。

/** Create the {@link Picasso} instance. 创建Picasso的实例 */

public Picassobuild(){
Context context=this.context;
if(downloader==null){
downloader=Utils.createDefaultDownloader(context);
}
if(cache==null){
cache=new LruCache(context);
}
if(service==null){
service=new PicassoExecutorService();
}
if(transformer==null){
transformer=RequestTransformer.IDENTITY;
}
Stats stats=newStats(cache);
Dispatcher dispatcher=new Dispatcher(context,service,HANDLER,downloader,cache,stats);
return new Picasso(context,dispatcher,cache,listener,transformer,
requestHandlers,stats,indicatorsEnabled,loggingEnabled);
}

 默认初始化了以下的参数:

Downloader

DownLoader就是下载用的工具类,在Picasso当中,如果OKHttp可以使用的话,就会默认使用OKHttp,如果无法使用的话,就会使用UrlConnectionDownloader(默认使用HttpURLConnection实现)。

Cache

默认实现为LruCache,就是使用LinkedHashMap实现的一个Cache类,注意的一个地方就是,在其他的地方,我们一般默认的是限制的capacity,但是这个地方我们是限制的总共使用的内存空间。因此LruCache在实现的时候,其实简单理解就是将LinkedHashMap封装,然后基于LinkedHashMap的方法实现Cache的方法,在Cache的set()方法的时候,会不断计算当前还可以使用的空间大小,要是超出范围,则删除之前保存的数据。

ExecutorService

默认的实现为PicassoExecutorService,该类也比较简单,其实就是ThreadPoolExecutor,在其功能的基础上继续封装,在其中有一个比较细心的功能就是,Picasso通过PicassoExecutorService设置线程数量,来调整在2G/3G/4G/WiFi不同网络情况下的不同表现。

RequestTransformer

ReqeustTransformer是一个接口,用来预处理Reqeust,可以用来将请求进行预先处理,比如改个域名啥的。

Stats

主要是一些统计信息,比如cache hit/miss,总共下载的文件大小,下载过的图片数量,转换的图片数量等等。

Dispatcher

Picasso当中,分发任务的线程,这是我们以后要重点研究的一个类,先标记一下,这个Dispatcher主要做了以下的事情:

启动了一个DispatcherThread线程初始化了一个用来处理消息的DispatcherHandler,注意,根据Dispatcher中默认配置,该Handler所有数据的处理是在DispatcherThread之上。初始化并注册了一个网络状态广播接收器。

 

2、图片加载流程:

1.初始化Picasso,实例化其唯一的对象。

2.根据传入的Url、File、resource Id,构建ReqeustCreator对象

3.根据ReqeustCreator构建Request对象,同时根据Reqeust属性,尝试从Cache中访问数据

4.Cache Hit,则通过回调,设置Target或者ImageView,完成该Reqeust

5.如果Cache Miss,那么则构建相应的Action,并提交到DispatcherThread当中。

6.Dispatcher中的Handler接收到相应的Message,调用dispatcher.performSubmit(action)进行处理。

7.创建BitmapHunter对象,并提交到PicassoExecutorService线程池

8.再次检查Memory Cache中已经有缓存,如果Hit,则读取缓存中的Bitmap

9.如果Cache miss,则交给Action对应的ReqeustHandler进行处理,比如网络请求,或者从File读取图片

10.返回结果之后,通知Dispatcher中的Handler处理结果。

11.DispatcherThread中将BitmapHunter的结果打包(batch),最快200ms打包一次。通知主线程HANDLER进行处理

12.主线程HANDLER接收打包的BitmapHunter,对最后的结果进行分发。

注意:Picasso框架没有实现磁盘缓存,配合OkHttp进行实现。

三、Glide

项目地址:https://github.com/bumptech/glide

Glide 是 Google 一位员工的大作,他完全是基于 Picasso 的,沿袭了 Picasso 的简洁风格,但是在此做了大量优化与改进。

Glide 默认的 Bitmap 格式是 RGB_565 格式,而 Picasso 默认的是 ARGB_8888 格式,这个内存开销要小一半。

在磁盘缓存方面,Picasso 只会缓存原始尺寸的图片,而 Glide 缓存的是多种规格,也就意味着 Glide 会根据你 ImageView 的大小来缓存相应大小的图片尺寸,比如你 ImageView 大小是200*200,原图是 400*400 ,而使用 Glide 就会缓存 200*200 规格的图,而 Picasso 只会缓存 400*400 规格的。这个改进就会导致 Glide 比 Picasso 加载的速度要快,毕竟少了每次裁剪重新渲染的过程。

最重要的一个特性是 Glide 支持加载 Gif 动态图,而 Picasso 不支持该特性。

除此之外,还有很多其他配置选项的增加。

总体来说,Glide 是在 Picasso 基础之上进行的二次开发,各个方面做了不少改进,不过这也导致他的包比 Picasso 大不少,不过也就不到 500k,Picasso 是100多k,方法数也比 Picasso 多不少,不过毕竟级别还是蛮小的,影响不是很大。

四、Fresco

项目地址:https://github.com/facebook/fresco

Fresco 是 Facebook 出品,他是新一代的图片加载库,我们知道 Android 应用程序可用的内存有限,经常会因为图片加载导致 OOM,虽然我们有各种手段去优化,尽量减少出现 OOM 的可能性,但是永远没法避免,尤其某些低端手机 OOM 更是严重。而 Facebook 就另辟蹊径,既然没法在 Java 层处理,我们就在更底层的 Native 堆做手脚。于是 Fresco 将图片放到一个特别的内存区域叫 Ashmem 区,就是属于 Native 堆,图片将不再占用 App 的内存,Java 层对此无能为力,这里是属于 C++ 的地盘,所以能大大的减少 OOM。

本人四个库都使用了一遍,对比到Fresco确实强大,加载大图Fresco最屌,有的图Glide和Picasso加载不出来,换上Fresco妥妥的,不过Fresco比较庞大,推荐在主要都是图片的app中使用,一般的app使用Glide和Picasso就够了!

五、ion

项目地址:https://github.com/koush/ion

 

 

 

分享到:
评论

相关推荐

    Android之Fresco(facebook的强大Android图片加载的框架)

    **Android之Fresco:Facebook的强大Android图片加载框架** 在Android应用开发中,图片加载和管理是一个常见的挑战。图片资源不仅占用大量内存,还可能导致UI卡顿,尤其是在处理大量或者高分辨率图片时。为了解决...

    Android图片加载框架

    本篇文章将深入探讨“Android图片加载框架”,以"Android-Universal-Image-Loader"为例,这是一个广泛使用的开源库,具有轻量级、适应性强的特点。 "Android-Universal-Image-Loader"(简称UIL)是一个强大的图片...

    Android第三方开源框架ImageLoader的完美Demo

    在Android应用开发中,图片加载是一个非常重要的环节,特别是在处理大量图片或者网络图片时,高效、内存友好的图片加载框架显得尤为关键。`ImageLoader`就是这样一个被广泛使用的第三方开源框架,它为开发者提供了...

    Android Fresco图片加载框架demo

    Android Fresco图片加载框架是一款强大的图像处理库,尤其在处理大量和复杂图片显示时表现出色。这个框架由Facebook开发并开源,旨在解决Android平台上图片加载、缓存和显示的一系列问题。Fresco的设计理念是优化...

    android加载刷新框架

    本篇将深入探讨“android加载刷新框架”,以及如何使用开源库实现这一功能。 首先,Android加载刷新框架主要解决的问题是当用户滚动到列表底部时自动加载更多数据,或者在初次打开应用时显示加载动画直到数据加载...

    Android开源框架中GIF格式图片加载模块的应用与移植.pdf

    Android开源框架中GIF格式图片加载模块的应用与移植.pdf 本文档主要讨论了Android开源框架中GIF格式图片加载模块的应用与移植。Fresco是Facebook公司出品的一款优秀的图片处理框架,但其结构复杂、不适合自行维护,...

    安卓(Android)平台用于SVG文件处理的开源框架

    为了应对这一需求,开发者社区推出了一些开源框架,这些框架使得Android应用能够轻松地处理SVG文件。本文将详细介绍一个名为“svg-android”的开源框架,它为Android提供了SVG支持。 首先,svg-android框架允许...

    Android 图片加载框架

    Android 图片加载框架是Android应用开发中的重要组成部分,主要用于优化图片的加载、缓存和显示,以提升用户体验并减少内存消耗。"Android-Universal-Image-Loader-master" 是一个广泛使用的开源项目,提供了完整的...

    Android非常实用的开源项目框架

    虽然具体的项目信息不足,但根据常规的Android开源项目框架,我们可以列举一些常见的类别和它们涉及的技术点: 1. **网络请求框架**:如Retrofit、Volley、OkHttp,它们简化了网络通信,支持HTTP/HTTPS协议,提供...

    facebook android 图片开源框架Fresco 示例apk

    里面将现在主流的集中图片开源框架的图片加载时间,内存消耗等做了对比,eclipse (别人已经明确说了不支持了)和编译没通过的(墙内的)攻城狮们,来看看大婶Facebook 的开源框架Fresco 的示例吧

    各种开源框架Android

    图片加载框架如`Glide`和`Picasso`,能够优化内存管理并流畅地加载和显示网络或本地图片。`Glide`以其强大的内存和磁盘缓存策略著称,支持动态占位符和错误图,以及视频帧的加载。`Picasso`则以其简洁的API和自动...

    android中使用afinal开源框架一行代码显示网络图片

    android快速开发框架afinal的特点: 使用简单,无需配置但可配置 在listview和gridview等容器加载图片的时候快速滑动无错误现象 支持线程池并发数量配置 支持内存缓存大小配置 支持磁盘大小缓存配置,和缓存...

    安卓 图片加载框架

    本教程将详细讲解“安卓 图片加载框架”,并聚焦于“Android-Universal-Image-Loader”这一开源库。 首先,我们需要理解为什么需要图片加载框架。在Android原生的API中,直接加载网络图片可能导致内存溢出、应用...

    支持Eclipse的fresco图片加载框架

    Fresco是一款由Facebook开源的高性能图片加载框架,它专为Android平台设计,旨在解决在处理大量图片时可能出现的内存管理问题。本项目是为在Eclipse开发环境中使用Fresco而准备的一个示例,通过对比其他图片加载库如...

    android开源项目各类框架大全

    三、图片加载框架 1. **Glide**:用于加载和显示网络或本地的图片,性能优秀,支持多种图片格式,内存管理出色。 2. **Picasso**:Square公司的另一款图片加载库,简洁易用,支持图片的缩放、裁剪等操作。 四、...

    android加载动态图片框架

    本文将深入探讨Android平台上的动态图片加载技术,以及如何利用一个名为GifView的开源框架实现这一功能。 一、Android动态图片格式 动态图片主要有两种常见格式:GIF和WebP。GIF是一种古老的无损压缩格式,支持多帧...

    ImageLoader开源框架加载图片,完整例子包括ListView的图片加载、GridView的图片加载、Gallery画廊的图片加载

    ImageLoader是一款广泛应用于Android开发中的开源图片加载框架,它的核心目标是高效且平滑地在各种UI组件(如ListView、GridView、Gallery等)中加载网络图片。本篇将详细介绍ImageLoader框架及其在不同场景下的应用...

    Android开源开发框架

    对于图片加载,这个框架可能采用了Glide、Picasso或者Universal Image Loader等库,它们能实现图片的加载、缓存和内存管理,避免因图片过大导致的内存溢出问题,同时提供图片的预加载和懒加载策略,优化用户体验。...

    Android图片加载&使用介绍

    #### 一、加载框架Glide与Picasso 在Android开发过程中,图片加载是一项常见的需求。为了提高应用性能并优化用户体验,开发者通常会选择使用专门的图片加载库。其中,**Glide** 和 **Picasso** 是最常用的两个库。 ...

    图片加载框架Fresco源码,Eclipse源码,Android4.4以上

    Fresco是一款专门为Android平台设计的高性能图片加载库,由Facebook开发并开源。它在Android 4.4(KitKat)及以上版本中表现出色,优化了内存管理,避免了Bitmap对象频繁地在内存和磁盘之间交换,从而提升了应用的...

Global site tag (gtag.js) - Google Analytics