Android图片加载框架Fresco解析

Android图片加载框架Fresco解析

标签(空格分隔): Android 框架 图片


与ImageLoader不同,Facebook的开源框架的加载方式决定了,更低的内存使用,更高的可定制性。


Fresco原理

设计一个Image Pipeline的概念,负责先检查内存,磁盘文件,如果都不存在则从给的Url中下载。
Fresco有三个线程池,其中,三个线程用于网络下载图片,2个线程用于磁盘文件的读写,还有两个线程负责CPU相关操作(解码,转换)等。


Drawees模块
它会在图片加载完成前显示占位图,加载成功后自动替换为目标图片。当图片不再显示在屏幕上时,它会及时地释放内存和空间占用。
- 自定义居中焦点
- 圆角图
- 下载失败后,点击重新下载
- 自定义占位图
- 自定义overlay
- 自定义进度条
- 指定用户按压时的overlay


Fresco的Image Pipeline允许你用很多种方式来自定义图片加载过程,比如:

  • 可以先显示一个低清晰度的图片,等下载完之后再显示高清图
  • 加载完成后回调通知
  • 本地图,如果有EXIF缩略图,则先显示缩略图,图片加载完成后再显示大图
  • 支持缩放和旋转图片
  • 可以对已下载的图片再次处理
  • 支持WebP解码,即使在对WebPage支持不完善的Android系统上也能使用。

JPEG格式的渐进式呈现
Android 本身的图片库不支持此格式,但是Fresco支持。使用时,和往常一样,仅仅需要提供一个图片的URI即可,剩下的事情,Fresco会处理。


动图加载
加载Gif图和WebP动图在任何一个Android开发者眼里看来都是一件非常头疼的事情。每一帧都是一张很大的Bitmap,每一个动画都有很多帧。Fresco让你没有这些烦恼,它处理好每一帧并管理好你的内存。


如何使用

导入库

dependencies { 
compile 'com.squareup.picasso:picasso:2.5.2'
}  

初始化
在Application级别初始化Fresco

public class TestApplication extends Application {

    @Override
    public void onCreate() {
        super.onCreate();
        Fresco.initialize(this);
    }
}

Layout中添加命名空间

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

不添加命名空间则可以

Uri uri = Uri.parse(uri);
imageView.setImageURI(uri);

常用属性

"@+id/image_view"
        android:layout_width="300dp"
        android:layout_height="300dp"
        fresco:fadeDuration="300"
        fresco:actualImageScaleType="focusCrop"
        fresco:placeholderImage="@color/wait_color" // 未加载成功
        fresco:placeholderImageScaleType="fitCenter"
        fresco:failureImage="@drawable/error" // 失败显示的图片
        fresco:failureImageScaleType="centerInside"
        fresco:retryImage="@drawable/retrying" // 重试,可重复四次,而后是failureImage
        fresco:retryImageScaleType="centerCrop" // 缩放
        fresco:progressBarImage="@drawable/progress_bar" // 进度条图片
        fresco:progressBarImageScaleType="centerInside"
        fresco:progressBarAutoRotateInterval="1000"
        fresco:backgroundImage="@color/blue" // 首先被绘制的背景图
        fresco:overlayImage="@drawable/watermark" // 叠加图,xml中只能设置一张。代码可设置
        fresco:pressedStateOverlayImage="@color/red" // 点击状态叠加图
        fresco:roundAsCircle="false"
        fresco:roundedCornerRadius="1dp"
        fresco:roundTopLeft="true"
        fresco:roundTopRight="false"
        fresco:roundBottomLeft="false"
        fresco:roundBottomRight="true"
        fresco:roundWithOverlayColor="@color/corner_color"
        fresco:roundingBorderWidth="2dp"
        fresco:roundingBorderColor="@color/border_color"
        />

开始加载图片

Uri uri = Uri.parse("https://raw.githubusercontent.com/facebook/fresco/gh-pages/static/logo.png");
SimpleDraweeView draweeView = (SimpleDraweeView) findViewById(R.id.my_image_view);
draweeView.setImageURI(uri);

动态更改

setController(controller)方法加载图片

DraweeController controller = Fresco
                .newDraweeControllerBuilder()
                .setUri(uri).build();
        imageView.setController(controller);

监听加载过程ControllerListener

                ControllerListener listener = new ControllerListener() {

            /**
             * Called before the image request is submitted.
             * 

IMPORTANT: It is not safe to reuse the controller from within this callback! * * @param id controller id * @param callerContext caller context */ @Override public void onSubmit(String id, Object callerContext) { // 在图片加载之前调用 } /** * Called after the final image has been set. * * @param id controller id * @param imageInfo image info * @param animatable */ @Override public void onFinalImageSet(String id, Object imageInfo, Animatable animatable) { // 加载成功之后 } /** * Called after any intermediate image has been set. * * @param id controller id * @param imageInfo image info */ @Override public void onIntermediateImageSet(String id, Object imageInfo) { // 渐进式加载完成后 } /** * Called after the fetch of the intermediate image failed. * * @param id controller id * @param throwable failure cause */ @Override public void onIntermediateImageFailed(String id, Throwable throwable) { // 渐进加载失败 } /** * Called after the fetch of the final image failed. * * @param id controller id * @param throwable failure cause */ @Override public void onFailure(String id, Throwable throwable) { // 加载失败 } /** * Called after the controller released the fetched image. *

IMPORTANT: It is not safe to reuse the controller from within this callback! * * @param id controller id */ @Override public void onRelease(String id) { // 释放资源后的操作 } };

还有一个更简化的接口调用,为单例模式,默认的ControllerListener

ControllerListener controllerListener = BaseControllerListener.getNoOpListener();

如何使用ControllerListener

DraweeController controller = Fresco.newDraweeControllerBuilder()
                .setUri(uri)
                .setControllerListener(listener)
                .build();
        imageView.setController(controller);

动态生成,重复利用GenericDraweeHierarchy动态设置

GenericDraweeHierarchy hierarchy = new GenericDraweeHierarchyBuilder(getResources())
                .setFadeDuration(300)
                .setBackground(getDrawable(R.drawable.ic_launcher))
                .setPlaceholderImage(getDrawable(R.drawable.ic_launcher))
                .setFailureImage(getDrawable(R.drawable.ic_launcher))
                .build();
        imageView.setHierarchy(hierarchy);

复用GenericDraweeHierarchy

GenericDraweeHierarchy hierarchy1 = imageView.getHierarchy();

JPEG渐进式网络加载
渐进式加载是由模糊到清晰的渐进过程,在网络条件不好的时候,渐进式加载能提高用户体验。
渐进式加载也是可以控制的,下面是接口

public interface ProgressiveJpegConfig {

  /**
   * Gets the next scan-number that should be decoded after the given scan-number.
   */
  int getNextScanNumberToDecode(int scanNumber);

  /**
   * Gets the quality information for the given scan-number.
   */
  QualityInfo getQualityInfo(int scanNumber);
}

Fresco提供了简单的控制方式的范例

ProgressiveJpegConfig progressiveJpegConfig = new SimpleProgressiveJpegConfig(list, 2);

Fresco是非常全面而且强大的图片加载框架,可以通过阅读源代码进一步了解他的设计以及使用。


Fresco中文介绍
Github地址

你可能感兴趣的:(个人成长,读书笔记)