Fresco-Facebook的图片加载框架的使用

目前常用的开源图片加载框架有:1.Universal-Image-Loader,该项目存在于Github上面https://github.com/nostra13/Android-Universal-Image-Loader

2.fresco,该项目的中文网站是:http://www.fresco-cn.org/,在Github上面是:https://github.com/facebook/fresco

之前一直用的是Universal-Image-Loader,改用fresco之后,在有大图展示的页面,能明显感觉到fresco在渲染速度和图片呈现效果上更胜一筹。fresco与Universal-Image-Loader比起来,最直观的几个优点是:

1.在显示圆形、圆角图片时,不需要另行引入CircleImageView等第三方或者自定义控件;

2.更容易实现图片View的点击效果;

3.默认的渐入显示效果;

下面来说一下fresco的使用:

1.如果使用的是Android Studio,则需要在build.gradle中引入fresco项目:

[java] view plain copy

  1. dependencies {
  2. ......
  3. compile ‘com.facebook.fresco:fresco:0.9.0+‘
  4. ......

其中0.9.0是fresco的版本;

2.在程序显示图片之前调用init接口,一般会在Application的onCreate方法中调用Fresco.initialize()方法,该方法有两种传参方式:

[java] view plain copy

  1. /** Initializes Fresco with the default config. */
  2. public static void initialize(Context context)
  3. /** Initializes Fresco with the specified config. */
  4. public static void initialize(Context context, ImagePipelineConfig imagePipelineConfig)

其中不对ImagePipeline进行配置的话,Fresco将采用默认的配置。ImagePipelineConfig可以进行如下配置:

[java] view plain copy

  1. public ImagePipelineConfig getImagePipelineConfig() {
  2. ImagePipelineConfig config = ImagePipelineConfig.newBuilder(App.getAppContext())
  3. .setWebpSupportEnabled(true)
  4. /**
  5. * 必须和ImageRequest的ResizeOptions一起使用,作用就是在图片解码时根据ResizeOptions所设的宽高的像素进行解码,这样解码出来可以得到一个更小的Bitmap。ResizeOptions和DownsampleEnabled参数都不影响原图片的大小,影响的是EncodeImage的大小,进而影响Decode出来的Bitmap的大小,ResizeOptions须和此参数结合使用是因为单独使用ResizeOptions的话只支持JPEG图,所以需支持png、jpg、webp需要先设置此参数。
  6. */
  7. .setDownsampleEnabled(true)
  8. /**
  9. * 最终影响的是mDownsampleEnabledForNetwork参数。 这个参数的作用是在mDownsampleEnabled为true的情况下,设置是否当这次请求是从网络中加载图片时,来对三级缓存中的编码图片重新改变大小。
  10. */
  11. .setResizeAndRotateEnabledForNetwork(true)
  12. /**
  13. * 是否根据不同的平台来构建相应的解码器
  14. */
  15. .setDecodeMemoryFileEnabled(true)
  16. /**
  17. * 所加载图片的配置,默认为Bitmap.Config.ARGB_8888
  18. */
  19. .setBitmapsConfig(Bitmap.Config config)
  20. /**
  21. * 三级缓存中已解码图片的内存缓存配置
  22. */
  23. .setBitmapMemoryCacheParamsSupplier(bitmapCacheParamsSupplier)
  24. /**
  25. * 三级缓存中编码图片的内存缓存
  26. */
  27. .setEncodedMemoryCacheParamsSupplier(encodedCacheParamsSupplier)
  28. /**
  29. * 三级缓存中硬盘缓存的配置,默认缓存目录在app自身CacheDir的image_cache目录下
  30. */
  31. .setMainDiskCacheConfig(mainDiskCacheConfig)
  32. /**
  33. * 执行各个任务的线程池配置,包括配置执行IO任务、后台任务、优先级低的后台任务、Decode任务的线程池的配置。
  34. */
  35. .setExecutorSupplier(executorSupplier)
  36. /**
  37. * 缓存的统计数据追踪器。它是一个接口,提供了各个缓存中图片Hit与Miss的回调方法,通常可以使用它来统计缓存命中率
  38. */
  39. .setImageCacheStatsTracker(imageCacheStatsTracker)
  40. /**
  41. * 注册一个内存调节器,它将根据不同的MemoryTrimType回收类型在需要降低内存使用时候进行回收一些内存缓存资源(Bitmap和Encode)。数值越大,表示要回收的资源越多。
  42. */
  43. .setMemoryTrimmableRegistry(memoryTrimmableRegistry)
  44. /**
  45. * 网络图片下载请求类
  46. */
  47. .setNetworkFetchProducer(networkFetchProducer)
  48. /**
  49. * 渐进式显示网络的JPEG图的配置,不过要使用渐进式显示图片,需要在ImageRequest中显示的设置是否支持渐进式显示:setProgressiveRenderingEnabled(true)
  50. */
  51. .setProgressiveJpegConfig(progressiveJpegConfig)
  52. /**
  53. * 小图的硬盘缓存配置,默认是和主硬盘缓存目录是共用的。如果需要把小图和普通图片分开,则需重新配置。
  54. */
  55. .setSmallImageDiskCacheConfig(smallImageDiskCacheConfig)
  56. .build();
  57. return config;
  58. }

这里要介绍一下fresco的三级缓存:Bitmap缓存+编码/未解码图片缓存+硬盘缓存。Fresco的加载图片的流程为:查找Bitmap缓存中是否存在,存在则直接返回Bitmap直接使用,不存在则查找未解码图片的缓存,如果存在则进行Decode成Bitmap然后直接使用并加入Bitmap缓存中,如果未解码图片缓存中查找不到,则进行硬盘缓存的检查,如有,则进行IO、转化、解码等一系列操作,最后成Bitmap供我们直接使用,并把未解码(Encode)的图片加入未解码图片缓存,把Bitmap加入Bitmap缓存中,如硬盘缓存中没有,则进行Network操作下载图片,然后加入到各个缓存中。ImagePipelineConfig及fresco的缓存原理详见:http://blog.csdn.net/u010687392/article/details/50266633

3.使用com.facebook.drawee.view.SimpleDraweeView替换掉ImageView。SimpleDraweeView可以通过配置实现圆形、圆角、pressed效果、默认图片、加载失败图片等显示效果,在布局中可以如下配置(以圆形效果为例):

[java] view plain copy

  1. <com.facebook.drawee.view.SimpleDraweeView
  2. android:id="@+id/iv_user_avatar"
  3. android:layout_width="@dimen/common_big_user_portrait_height"
  4. android:layout_height="@dimen/common_big_user_portrait_height"
  5. android:layout_centerInParent="true"
  6. /** 正常图片的ScaleType*/
  7. fresco:actualImageScaleType="centerCrop"
  8. /**图片加载失败时的图片及其ScaleType*/
  9. fresco:failureImage="@drawable/default_user_portrait"
  10. fresco:failureImageScaleType="centerCrop"
  11. /** 默认图片及其ScaleType*/
  12. fresco:placeholderImage="@drawable/default_user_portrait"
  13. fresco:placeholderImageScaleType="centerCrop"
  14. /**pressed效果,一般是通过布局shape一种色值*/
  15. fresco:pressedStateOverlayImage="@drawable/common_circle_image_pressed"
  16. /**圆形 */
  17. fresco:roundAsCircle="true"
  18. />

如果是圆角的话,可以在上面的基础上增加如下特殊配置,其中fresco:roundedCornerRadius根据需要具体设置值:

[java] view plain copy

  1. fresco:roundAsCircle="false"
  2. fresco:roundBottomLeft="true"
  3. fresco:roundBottomRight="true"
  4. fresco:roundTopLeft="true"
  5. fresco:roundTopRight="true"
  6. fresco:roundedCornerRadius="xdp"

然后在代码中,调用如下语句即可显示网络或者本地图片:

[java] view plain copy

  1. String uri = bean.getUrl();
  2. if (!uri.startsWith("http")) {
  3. uri = "file://" + bean.getUrl();
  4. }

如果就是想让view显示默认的图片,则调用语句:

[java] view plain copy

  1. simpleDraweeView.setImageURI(Uri.parse(“”));

如果想修改默认的ImageRequest、DraweeController等的配置,则可以在代码中这样配置和显示图片(以显示圆形图片为例):

[java] view plain copy

  1. public void displayCirclePortraitImage(Context context, String picUrl, SimpleDraweeView iv_pic) {
  2. if (iv_pic == null) {
  3. return;
  4. }
  5. Context tempContext = context;
  6. if (tempContext == null) {
  7. tempContext = App.getAppContext();
  8. }
  9. if (!StringUtil.isEmpty(picUrl)) {
  10. Uri uri = Uri.parse(picUrl);
  11. ImageRequest request = ImageRequestBuilder.newBuilderWithSource(uri)
  12. .setLocalThumbnailPreviewsEnabled(true)
  13. .setAutoRotateEnabled(true)
  14. .setLowestPermittedRequestLevel(ImageRequest.RequestLevel.FULL_FETCH)
  15. .setProgressiveRenderingEnabled(false)
  16. .build();
  17. DraweeController controller = Fresco.newDraweeControllerBuilder()
  18. .setImageRequest(request)
  19. .setAutoPlayAnimations(true)
  20. .setOldController(iv_pic.getController())
  21. .build();
  22. iv_pic.setController(controller);
  23. } else {
  24. iv_pic.setImageURI(Uri.parse(""));
  25. }
  26. //        GenericDraweeHierarchy ghy = iv_pic.getHierarchy();
  27. //        if (ghy == null) {
  28. GenericDraweeHierarchyBuilder gbulder = new GenericDraweeHierarchyBuilder(tempContext.getResources());
  29. ghy = gbulder.setActualImageScaleType(ScalingUtils.ScaleType.CENTER_CROP)
  30. .setPlaceholderImage(tempContext.getResources().getDrawable(R.drawable.default_user_portrait), ScalingUtils.ScaleType.CENTER_CROP)
  31. .setFailureImage(tempContext.getResources().getDrawable(R.drawable.default_user_portrait), ScalingUtils.ScaleType.CENTER_CROP)
  32. .setRoundingParams(RoundingParams.asCircle())
  33. .setPressedStateOverlay(tempContext.getResources().getDrawable(R.drawable.common_circle_image_pressed))
  34. .build();
  35. iv_pic.setHierarchy(ghy);
  36. //        } else {
  37. //            ghy.setActualImageScaleType(ScalingUtils.ScaleType.CENTER_CROP);
  38. //            ghy.setRoundingParams(RoundingParams.asCircle());
  39. //        }
  40. float scaleRadio = 1.0f;
  41. iv_pic.setAspectRatio(scaleRadio);
  42. }

如果只想下载图片,不使用SimpleDraweeView控件,则可以通过如下方法:

[java] view plain copy

  1. public void loadImage(Context context, String picUrl, ResizeOptions resizeOptions, BaseBitmapDataSubscriber bitmapDataSubscriber) {
  2. if (StringUtil.isEmpty(picUrl)) {
  3. return;
  4. }
  5. Uri uri = Uri.parse(picUrl);
  6. ImageRequest imageRequest = ImageRequestBuilder.newBuilderWithSource(uri)
  7. .setLocalThumbnailPreviewsEnabled(true)
  8. .setAutoRotateEnabled(true)
  9. .setResizeOptions(resizeOptions)
  10. .setLowestPermittedRequestLevel(ImageRequest.RequestLevel.FULL_FETCH)
  11. .setProgressiveRenderingEnabled(false)
  12. .build();
  13. ImagePipeline imagePipeline = Fresco.getImagePipeline();
  14. DataSource<CloseableReference<CloseableImage>>
  15. dataSource = imagePipeline.fetchDecodedImage(imageRequest, context);
  16. dataSource.subscribe(bitmapDataSubscriber, CallerThreadExecutor.getInstance());
  17. }

其中回调接口BaseBitmapDataSubscriber实现如下:

[java] view plain copy

  1. FrescoImageLoader.getInstance().loadImage(ViewSinglePhotoActivity.this, picUrl, resizeOptions, new
  2. BaseBitmapDataSubscriber() {
  3. @Override
  4. protected void onNewResultImpl(Bitmap bitmap) {
  5. ViewSinglePhotoActivity.this.runOnUiThread(new Runnable() {
  6. @Override
  7. public void run() {
  8. loadPb.setVisibility(View.GONE);
  9. }
  10. });
  11. if (bitmap != null && photoView != null) {
  12. final Bitmap arg2 = Bitmap.createBitmap(bitmap);
  13. ImageCache.getInstance().put(picUrl, arg2);
  14. ViewSinglePhotoActivity.this.runOnUiThread(new Runnable() {
  15. @Override
  16. public void run() {
  17. photoView.setImageBitmap(arg2);
  18. }
  19. });
  20. }
  21. }
  22. @Override
  23. protected void onFailureImpl(DataSource<CloseableReference<CloseableImage>> dataSource) {
  24. ViewSinglePhotoActivity.this.runOnUiThread(new Runnable() {
  25. @Override
  26. public void run() {
  27. loadPb.setVisibility(View.GONE);
  28. photoView.setImageResource(R.drawable.default_pic);
  29. }
  30. });
  31. }
  32. });

注意事项:

1.布局中如果使用了fresco的属性,则需要引入命名空间:

xmlns:fresco="http://schemas.android.com/apk/res-auto"

2.SimpleDraweeView不支持wrap_content属性,必须给出具体的宽高值,如果width或者height其中有一个值为wrap_content,则可以通过设置宽高比的方法setAspectRatio间接指定其值;

3.使用SimpleDraweeView后,facebook官方建议不要再使用ImageView的任何属性,如setImageResource、setBackground、setScaleType等;后续版本SimpleDraweeView旨在改为直接继承View;

4.GenericDraweeHierarchy的属性配置要么在布局中设置完,要么在代码中设置完;simpleDraweeView.getHierarchy()的值一直都不为空,所以不要用这个判断条件来做区分;

5.关于OOM,1.请给ImageRequest默认配置上setResizeOptions(resizeOptions)属性;对于照片墙等含有大量图片的页面,必须要对图片的大小做限制;网络图片可以通过服务端来对图片的尺寸、质量、图片类型做处理后再返给客户端,但是对于手机本地的图片,就只能通过setResizeOptions来有效降低内存缓存的开销;2.在低内存的情况下或者退出多图页面的情况下,手动释放内存缓存:

[java] view plain copy

  1. ImagePipeline imagePipeline = Fresco.getImagePipeline();
  2. //清空内存缓存(包括Bitmap缓存和未解码图片的缓存)
  3. imagePipeline.clearMemoryCaches();
  4. //清空硬盘缓存,一般在设置界面供用户手动清理
  5. imagePipeline.clearDiskCaches();
  6. //同时清理内存缓存和硬盘缓存
  7. imagePipeline.clearCaches();

6.BaseBitmapDataSubscriber的方法onNewResultImpl中返回的Bitmap会很快被系统回收掉,所以需要再复制一份自行保存;保存时可以采用LruCache方法。

7.对于webp格式的网络图片内容,如果引入的是fresco:0.6.0;则在安卓4.2.2的手机上没有问题,如果引入的是fresco:0.8.0或者fresco:0.9.0,则在安卓4.2.2的手机上图片会加载失败。

原文地址:https://www.cnblogs.com/Free-Thinker/p/8618772.html

时间: 2024-10-02 08:31:46

Fresco-Facebook的图片加载框架的使用的相关文章

Fresco从配置到使用(最高效的图片加载框架)

Frescoj说明: facebook开源的针对android应用的图片加载框架,高效和功能齐全. 支持加载网络,本地存储和资源图片: 提供三级缓存(二级memory和一级internal storage): 支持JPEGs,PNGs,GIFs,WEBPs等,还支持Progressive JPEG,优秀的动画支持: 图片圆角,scale,自定义背景,overlays等等: 优秀的内存管理: 2.3(Gingerbread)或以上. --------------------------------

Android之图片加载框架Fresco基本使用(一)

PS:Fresco这个框架出的有一阵子了,也是现在非常火的一款图片加载框架.听说内部实现的挺牛逼的,虽然自己还没研究原理.不过先学了一下基本的功能,感受了一下这个框架的强大之处.本篇只说一下在xml中设置属性的相关用法. 0.引入Fresco以及相关注意事项. 1.PlaceHolderImage占位图 2.FailureImage加载失败时显示的图片 3.RetryImage重新加载的图片 4.ProgressBarImage加载时显示的进度图片 5.BackgroundImage背景图 6.

强大的图片加载框架Fresco的使用

前面在卓新科技有限公司实习的时候,在自己的爱吖头条APP中,在图片异步加载的时候和ListView的滑动中,总会出现卡顿,这是因为图片的缓存做的不是足够到位,在项目监理的帮助下,有使用Xutils框架下的图片加载,也有使用ImageLoader来实现,在今天在威哥的微信公众号了gank到了一个当前最强大的图片加载框架——Fresco. Fresco是Facebook发布的一款开源框架,号称是目前最强的Android图片加载库,在内存方面的表现极为优秀,既然有如此信心,对于Fresco的一些介绍,

主流图片加载框架ImageLoader、Glide、Picasso、Fresco性能分析---图片加载速度比较

图片加载这种实现繁琐,可复用性又极强的东西,自然是选择使用图片加载框架来快速实现. 像是Android-Universal-Image-Loader.Glide.Picasso.Fresco之类, 但是这时候的烦恼在于,这么多图片加载框架到底谁最实用? 有说Fresco,因为支持WebP,还是用了NDK来加载图片,减少JavaHeap的使用 有Picasso,简洁高效 有说Glide,Picasso升级,可以加载Gif,在Picasso基础上扩展了很多方法 ImageLoader 使用最广,因为

常用图片加载框架

我们在项目中使用的是Picasso.其实现在的主流图片加载框架除了Picasso还有ImageLoader,Glide,以及Fresco.ImageLoader是比较老的框架了,稳定, 加载速度适中, 缺点在于不支持GIF图片加载, 使用稍微繁琐, 并且缓存机制没有和http的缓存很好的结合, 完全是自己的一套缓存机制.Glide是谷歌的一位工程师开发的,它可以说是Picasso的升级版, 有Picasso的优点, 并且支持GIF图片加载显示, 图片缓存也会自动缩放, 默认使用RGB_565格式

Android中常见的图片加载框架

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

关于图片加载框架

接上篇,这篇开始对现在比较的流行的第三方图片加载框架做一个对比总结. 这篇文章介绍内容如下: 1.目前流行的图片加载框架有什么? 2.各自的使用方法 3.各自的优缺点 4.优化问题 一.目前流行的图片加载框架有什么? ImageLoader   Glide  Picasso  Fresso(2015年) 注:由于现在ImageLoader使用较少,本篇博文将不再对它进行阐述.主要以其它三个框架为主,有兴趣的同学可以自行学习. 二.各自的使用方法 Picasso:  Picasso .with(t

Universal-Image-Loader(UIL)图片加载框架使用简单介绍

这个也是最近项目中使用到的第三方图片加载框架,在这里也自己总结一下,简单的介绍一些使用的方式. UIL图片加载框架特点 简介: 项目地址:https://github.com/nostra13/Android-Universal-Image-Loader 异步加载图片或者加载大量图片经常会遇到图片错乱或者OOM等相关问题.UIL图片缓存,目前使用最广泛的图片缓存,支持主流图片缓存的绝大多数特性. 我们看下该图片加载的三级缓存原理 特点: 1.多线程下载图片,图片可以来源于网络,文件系统,项目文件

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

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