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项目:
- dependencies {
- ......
- compile 'com.facebook.fresco:fresco:0.9.0+'
- ......
其中0.9.0是fresco的版本;
2.在程序显示图片之前调用init接口,一般会在Application的onCreate方法中调用Fresco.initialize()方法,该方法有两种传参方式:
- /** Initializes Fresco with the default config. */
- public static void initialize(Context context)
- /** Initializes Fresco with the specified config. */
- public static void initialize(Context context, ImagePipelineConfig imagePipelineConfig)
其中不对ImagePipeline进行配置的话,Fresco将采用默认的配置。ImagePipelineConfig可以进行如下配置:
- public ImagePipelineConfig getImagePipelineConfig() {
- ImagePipelineConfig config = ImagePipelineConfig.newBuilder(App.getAppContext())
- .setWebpSupportEnabled(true)
- /**
- * 必须和ImageRequest的ResizeOptions一起使用,作用就是在图片解码时根据ResizeOptions所设的宽高的像素进行解码,这样解码出来可以得到一个更小的Bitmap。ResizeOptions和DownsampleEnabled参数都不影响原图片的大小,影响的是EncodeImage的大小,进而影响Decode出来的Bitmap的大小,ResizeOptions须和此参数结合使用是因为单独使用ResizeOptions的话只支持JPEG图,所以需支持png、jpg、webp需要先设置此参数。
- */
- .setDownsampleEnabled(true)
- /**
- * 最终影响的是mDownsampleEnabledForNetwork参数。 这个参数的作用是在mDownsampleEnabled为true的情况下,设置是否当这次请求是从网络中加载图片时,来对三级缓存中的编码图片重新改变大小。
- */
- .setResizeAndRotateEnabledForNetwork(true)
- /**
- * 是否根据不同的平台来构建相应的解码器
- */
- .setDecodeMemoryFileEnabled(true)
- /**
- * 所加载图片的配置,默认为Bitmap.Config.ARGB_8888
- */
- .setBitmapsConfig(Bitmap.Config config)
- /**
- * 三级缓存中已解码图片的内存缓存配置
- */
- .setBitmapMemoryCacheParamsSupplier(bitmapCacheParamsSupplier)
- /**
- * 三级缓存中编码图片的内存缓存
- */
- .setEncodedMemoryCacheParamsSupplier(encodedCacheParamsSupplier)
- /**
- * 三级缓存中硬盘缓存的配置,默认缓存目录在app自身CacheDir的image_cache目录下
- */
- .setMainDiskCacheConfig(mainDiskCacheConfig)
- /**
- * 执行各个任务的线程池配置,包括配置执行IO任务、后台任务、优先级低的后台任务、Decode任务的线程池的配置。
- */
- .setExecutorSupplier(executorSupplier)
- /**
- * 缓存的统计数据追踪器。它是一个接口,提供了各个缓存中图片Hit与Miss的回调方法,通常可以使用它来统计缓存命中率
- */
- .setImageCacheStatsTracker(imageCacheStatsTracker)
- /**
- * 注册一个内存调节器,它将根据不同的MemoryTrimType回收类型在需要降低内存使用时候进行回收一些内存缓存资源(Bitmap和Encode)。数值越大,表示要回收的资源越多。
- */
- .setMemoryTrimmableRegistry(memoryTrimmableRegistry)
- /**
- * 网络图片下载请求类
- */
- .setNetworkFetchProducer(networkFetchProducer)
- /**
- * 渐进式显示网络的JPEG图的配置,不过要使用渐进式显示图片,需要在ImageRequest中显示的设置是否支持渐进式显示:setProgressiveRenderingEnabled(true)
- */
- .setProgressiveJpegConfig(progressiveJpegConfig)
- /**
- * 小图的硬盘缓存配置,默认是和主硬盘缓存目录是共用的。如果需要把小图和普通图片分开,则需重新配置。
- */
- .setSmallImageDiskCacheConfig(smallImageDiskCacheConfig)
- .build();
- return config;
- }
这里要介绍一下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效果、默认图片、加载失败图片等显示效果,在布局中可以如下配置(以圆形效果为例):
- <com.facebook.drawee.view.SimpleDraweeView
- android:id="@+id/iv_user_avatar"
- android:layout_width="@dimen/common_big_user_portrait_height"
- android:layout_height="@dimen/common_big_user_portrait_height"
- android:layout_centerInParent="true"
- /** 正常图片的ScaleType*/
- fresco:actualImageScaleType="centerCrop"
- /**图片加载失败时的图片及其ScaleType*/
- fresco:failureImage="@drawable/default_user_portrait"
- fresco:failureImageScaleType="centerCrop"
- /** 默认图片及其ScaleType*/
- fresco:placeholderImage="@drawable/default_user_portrait"
- fresco:placeholderImageScaleType="centerCrop"
- /**pressed效果,一般是通过布局shape一种色值*/
- fresco:pressedStateOverlayImage="@drawable/common_circle_image_pressed"
- /**圆形 */
- fresco:roundAsCircle="true"
- />
如果是圆角的话,可以在上面的基础上增加如下特殊配置,其中fresco:roundedCornerRadius根据需要具体设置值:
- fresco:roundAsCircle="false"
- fresco:roundBottomLeft="true"
- fresco:roundBottomRight="true"
- fresco:roundTopLeft="true"
- fresco:roundTopRight="true"
- fresco:roundedCornerRadius="xdp"
然后在代码中,调用如下语句即可显示网络或者本地图片:
- String uri = bean.getUrl();
- if (!uri.startsWith("http")) {
- uri = "file://" + bean.getUrl();
- }
如果就是想让view显示默认的图片,则调用语句:
- simpleDraweeView.setImageURI(Uri.parse(“”));
如果想修改默认的ImageRequest、DraweeController等的配置,则可以在代码中这样配置和显示图片(以显示圆形图片为例):
- public void displayCirclePortraitImage(Context context, String picUrl, SimpleDraweeView iv_pic) {
- if (iv_pic == null) {
- return;
- }
- Context tempContext = context;
- if (tempContext == null) {
- tempContext = App.getAppContext();
- }
- if (!StringUtil.isEmpty(picUrl)) {
- Uri uri = Uri.parse(picUrl);
- ImageRequest request = ImageRequestBuilder.newBuilderWithSource(uri)
- .setLocalThumbnailPreviewsEnabled(true)
- .setAutoRotateEnabled(true)
- .setLowestPermittedRequestLevel(ImageRequest.RequestLevel.FULL_FETCH)
- .setProgressiveRenderingEnabled(false)
- .build();
- DraweeController controller = Fresco.newDraweeControllerBuilder()
- .setImageRequest(request)
- .setAutoPlayAnimations(true)
- .setOldController(iv_pic.getController())
- .build();
- iv_pic.setController(controller);
- } else {
- iv_pic.setImageURI(Uri.parse(""));
- }
- // GenericDraweeHierarchy ghy = iv_pic.getHierarchy();
- // if (ghy == null) {
- GenericDraweeHierarchyBuilder gbulder = new GenericDraweeHierarchyBuilder(tempContext.getResources());
- ghy = gbulder.setActualImageScaleType(ScalingUtils.ScaleType.CENTER_CROP)
- .setPlaceholderImage(tempContext.getResources().getDrawable(R.drawable.default_user_portrait), ScalingUtils.ScaleType.CENTER_CROP)
- .setFailureImage(tempContext.getResources().getDrawable(R.drawable.default_user_portrait), ScalingUtils.ScaleType.CENTER_CROP)
- .setRoundingParams(RoundingParams.asCircle())
- .setPressedStateOverlay(tempContext.getResources().getDrawable(R.drawable.common_circle_image_pressed))
- .build();
- iv_pic.setHierarchy(ghy);
- // } else {
- // ghy.setActualImageScaleType(ScalingUtils.ScaleType.CENTER_CROP);
- // ghy.setRoundingParams(RoundingParams.asCircle());
- // }
- float scaleRadio = 1.0f;
- iv_pic.setAspectRatio(scaleRadio);
- }
如果只想下载图片,不使用SimpleDraweeView控件,则可以通过如下方法:
- public void loadImage(Context context, String picUrl, ResizeOptions resizeOptions, BaseBitmapDataSubscriber bitmapDataSubscriber) {
- if (StringUtil.isEmpty(picUrl)) {
- return;
- }
- Uri uri = Uri.parse(picUrl);
- ImageRequest imageRequest = ImageRequestBuilder.newBuilderWithSource(uri)
- .setLocalThumbnailPreviewsEnabled(true)
- .setAutoRotateEnabled(true)
- .setResizeOptions(resizeOptions)
- .setLowestPermittedRequestLevel(ImageRequest.RequestLevel.FULL_FETCH)
- .setProgressiveRenderingEnabled(false)
- .build();
- ImagePipeline imagePipeline = Fresco.getImagePipeline();
- DataSource<CloseableReference<CloseableImage>>
- dataSource = imagePipeline.fetchDecodedImage(imageRequest, context);
- dataSource.subscribe(bitmapDataSubscriber, CallerThreadExecutor.getInstance());
- }
其中回调接口BaseBitmapDataSubscriber实现如下:
- FrescoImageLoader.getInstance().loadImage(ViewSinglePhotoActivity.this, picUrl, resizeOptions, new
- BaseBitmapDataSubscriber() {
- @Override
- protected void onNewResultImpl(Bitmap bitmap) {
- ViewSinglePhotoActivity.this.runOnUiThread(new Runnable() {
- @Override
- public void run() {
- loadPb.setVisibility(View.GONE);
- }
- });
- if (bitmap != null && photoView != null) {
- final Bitmap arg2 = Bitmap.createBitmap(bitmap);
- ImageCache.getInstance().put(picUrl, arg2);
- ViewSinglePhotoActivity.this.runOnUiThread(new Runnable() {
- @Override
- public void run() {
- photoView.setImageBitmap(arg2);
- }
- });
- }
- }
- @Override
- protected void onFailureImpl(DataSource<CloseableReference<CloseableImage>> dataSource) {
- ViewSinglePhotoActivity.this.runOnUiThread(new Runnable() {
- @Override
- public void run() {
- loadPb.setVisibility(View.GONE);
- photoView.setImageResource(R.drawable.default_pic);
- }
- });
- }
- });
注意事项:
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.在低内存的情况下或者退出多图页面的情况下,手动释放内存缓存:
- ImagePipeline imagePipeline = Fresco.getImagePipeline();
- //清空内存缓存(包括Bitmap缓存和未解码图片的缓存)
- imagePipeline.clearMemoryCaches();
- //清空硬盘缓存,一般在设置界面供用户手动清理
- imagePipeline.clearDiskCaches();
- //同时清理内存缓存和硬盘缓存
- 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的手机上图片会加载失败。
Fresco-Facebook的图片加载框架的使用的更多相关文章
- 强大的图片加载框架Fresco的使用
前面在卓新科技有限公司实习的时候,在自己的爱吖头条APP中,在图片异步加载的时候和ListView的滑动中,总会出现卡顿,这是因为图片的缓存做的不是足够到位,在项目监理的帮助下,有使用Xutils框架 ...
- Fresco从配置到使用(最高效的图片加载框架)
Frescoj说明: facebook开源的针对android应用的图片加载框架,高效和功能齐全. 支持加载网络,本地存储和资源图片: 提供三级缓存(二级memory和一级internal ...
- Android之图片加载框架Fresco基本使用(一)
PS:Fresco这个框架出的有一阵子了,也是现在非常火的一款图片加载框架.听说内部实现的挺牛逼的,虽然自己还没研究原理.不过先学了一下基本的功能,感受了一下这个框架的强大之处.本篇只说一下在xml中 ...
- 主流图片加载框架 ImageLoader、Glide、Picasso、Fresco 对比
图片缓存库主页: Glidehttps://github.com/bumptech/glide fresco - An Android library for managing images and ...
- 图片加载框架之fresco
FaceBook推出的图片处理框架主页: https://github.com/facebook/fresco中文文档:http://fresco-cn.org/docs/index.html 功能 ...
- Android中常见的图片加载框架
图片加载涉及到图片的缓存.图片的处理.图片的显示等.而随着市面上手机设备的硬件水平飞速发展,对图片的显示要求越来越高,稍微处理不好就会造成内存溢出等问题.很多软件厂家的通用做法就是借用第三方的框架进行 ...
- Android项目框架之图片加载框架的选择
本文来自http://blog.csdn.net/liuxian13183/ ,引用必须注明出处! 从Android爆发以后,自定义的控件如EditTextWithDelete.ActionBar.P ...
- Android图片加载框架最全解析(一),Glide的基本用法
现在Android上的图片加载框架非常成熟,从最早的老牌图片加载框架UniversalImageLoader,到后来Google推出的Volley,再到后来的新兴军Glide和Picasso,当然还有 ...
- android-------非常好的图片加载框架和缓存库(Picasso)
Picasso是Square公司开源的一个Android图形缓存库, 可以实现图片加载(本地和网络)和缓存功能. 地址:http://square.github.io/picasso/ jar包下载: ...
- android--------Universal-Image-Loader图片加载框架和结合LruCache缓存图片
本博客包含包含Android-Universal-Image-Loader 网络图片加载框架实现图片加载和结合universal-image-loader与LruCache来自定义缓存图片,可以设置缓 ...
随机推荐
- $config['base_url'] BASE_URL
/*|------------------------------------------------| Base Site URL|--------------------------------- ...
- 【Ajax 1】Ajax与传统Web开发的区别
导读:从用户体验度的角度来说,利用Ajax进行开发的网站,其体验度高于利用传统Web开发技术,那么,是什么因素导致了这一现象呢?难道说Ajax开发,就一定优于传统Web技术吗?本篇文章,将主要介绍Aj ...
- 按WSDL信息手动生成代理类
命令行: wsdl /language:c# /n:Entity /out:C:\Users\mengxianming\Desktop\Centrex_IMS_Client.cs C:\Users\m ...
- CodeForces - 43B Letter
字符串的处理 统计已有字符的个数 和需求字符比较 #include <iostream> #include <stdio.h> #include <string.h> ...
- hdu5608:function
$n^2-3n+2=\sum_{d|i}f(i)$,问$f(i)$前$n$项和. 方法一:直接切入! $S(n)=\sum_{i=1}^{n}f(i)=\sum_{i=1}^{n}(i^2-3i+2- ...
- gridview读取Excel文件中的数据,并将其导入数据库
原文发布时间为:2008-10-16 -- 来源于本人的百度文章 [由搬家工具导入] //将需要导入的文件上传到服务器 string filePath = "" ...
- Python基础教程笔记——第2章:列表和元组
python shell 里重复上一次的命令:Alt+p 2.3 列表:Python的苦力 (1)list函数 (2)列表赋值,不蹦蹦为一个元素不存在的位置赋值 (3)删除元素,del name[1] ...
- Visual Studio Code Edit
微软的跨平台编辑器~~ 下载地址(官网):https://code.visualstudio.com/ 下载地址(网盘):http://pan.baidu.com/s/1ntLy8Tr 使用技巧: c ...
- 最长上升子序列(LIS)长度的O(nlogn)算法
最长上升子序列(LIS)的典型变形,熟悉的n^2的动归会超时.LIS问题可以优化为nlogn的算法.定义d[k]:长度为k的上升子序列的最末元素,若有多个长度为k的上升子序列,则记录最小的那个最末元素 ...
- androidstudio Cannot resolve symbol 'xxx'
Android Studio 无法识别同一个 package 里的其他类,将其显示为红色,但是 compile 没有问题.鼠标放上去后显示 “Cannot resolve symbol XXX”,重启 ...