Android之Fresco框架(四)--ImagePipeline的调用和使用

本文深入解析了Android Fresco框架中ImagePipeline的调用过程,从SimpleDraweeView的setImageURI()方法开始,详细阐述了请求如何传递给ImagePipeline,以及如何直接操作ImagePipeline进行图片请求。同时介绍了DataSource、DataSubscriber的概念以及它们在异步操作中的作用。此外,还概述了ImagePipeline的关键方法,如fetchDecodedImage、prefetchToBitmapCache等,并展示了如何自定义ImageRequest并使用ImagePipeline进行图像请求。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

之前大致把ImagePipeline的配置和底层实现都讲了一下,这一篇来重点讲一下我们在发送图片请求的时候是怎么把请求传给ImagePipeline的,以及我们如何自己直接对ImagePipeline实例进行请求,内存管理等操作。

SimpleDraweeView中ImagePipeline的调用

在第一篇的时候,我们当时只需要对SimpleDraweeView进行setImageURI()方法,setController()方法之后,都能够成功发起图片请求,那底层是怎么实现的呢。先来看一下SimpleDraweeView中的相关代码:

/**
   * Displays an image given by the uri.
   *
   * @param uri uri of the image
   * @undeprecate
   */
  @Override
  public void setImageURI(Uri uri) {
    setImageURI(uri, null);
  }

  /**
   * Displays an image given by the uri string.
   *
   * @param uriString uri string of the image
   */
  public void setImageURI(@Nullable String uriString) {
    setImageURI(uriString, null);
  }

  /**
   * Displays an image given by the uri.
   *
   * @param uri uri of the image
   * @param callerContext caller context
   */
  //最终都会执行该方法
  public void setImageURI(Uri uri, @Nullable Object callerContext) {
    DraweeController controller = mSimpleDraweeControllerBuilder
        .setCallerContext(callerContext)
        .setUri(uri)
        .setOldController(getController())
        .build();
    //所有setImageURI最终调用方法
    setController(controller);
  }

  /**
   * Displays an image given by the uri string.
   *
   * @param uriString uri string of the image
   * @param callerContext caller context
   */
  public void setImageURI(@Nullable String uriString, @Nullable Object callerContext) {
    Uri uri = (uriString != null) ? Uri.parse(uriString) : null;
    setImageURI(uri, callerContext);
  }

可以看出,不管用的是哪一个重载的setImageURI,最终都是会调用到同一个方法中,而该方法中又会执行setController()方法。那我们来看一下setController()方法,所以我们用不管setImageURI()还是setController()最终都是殊途同归。setController()在父类DraweeView()中。DraweeView是一个继承于ImageView的子类:

private DraweeHolder<DH> mDraweeHolder;
public void setController(@Nullable DraweeController draweeController) {
    mDraweeHolder.setController(draweeController);
    super.setImageDrawable(mDraweeHolder.getTopLevelDrawable());
}

所以方法又调用了DraweeHolder里面的setController()方法,对于DraweeHolder,个人感觉是起到了适配器的作用,也使得我们的代码更加易读吧。先不瞎扯看下DraweeHolder中的代码:

  public void setController(@Nullable DraweeController draweeController) {
    boolean wasAttached = mIsControllerAttached;
    if (wasAttached) {
      detachController();
    }

    //清除掉旧的Controller
    if (isControllerValid()) {
      //mEventTracker起到一个纪录的作用
      mEventTracker.recordEvent(Event.ON_CLEAR_OLD_CONTROLLER);
      mController.setHierarchy(null);
    }
    mController = draweeController;
    if (mController != null) {
      mEventTracker.recordEvent(Event.ON_SET_CONTROLLER);
      mController.setHierarchy(mHierarchy);
    } else {
      mEventTracker.recordEvent(Event.ON_CLEAR_CONTROLLER);
    }

    if (wasAttached) {
      //调用到该方法
      attachController();
    }
  }


  private void attachController() {
    if (mIsControllerAttached) {
      return;
    }
    mEventTracker.recordEvent(Event.ON_ATTACH_CONTROLLER);
    mIsControllerAttached = true;
    if (mController != null &&
        mController.getHierarchy() != null) {
          //调用Controller的onAttach()方法
          mController.onAttach();
    }
  }

接下来就是看Controller的onAttach方法,在SimpleDraweeView中设置的PipelineDraweeController实例,onAttach方法定义于它的父类AbstractDraweeController中:

  @Override
  public void onAttach() {
    if (FLog.isLoggable(FLog.VERBOSE)) {
      FLog.v(
          TAG,
          "controller %x %s: onAttach: %s",
          System.identityHashCode(this),
          mId,
          mIsRequestSubmitted ? "request already submitted" : "request needs submit");
    }
    mEventTracker.recordEvent(Event.ON_ATTACH_CONTROLLER);
    Preconditions.checkNotNull(mSettableDraweeHierarc
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值