Fresco源码之DraweeController

本文深入探讨了Fresco库中的DraweeController,这是一个用于图像加载和显示的关键组件。它作为抽象接口,主要负责设置图像层级结构、处理附加事件和触摸交互。在DraweeController的实现类AbstractDraweeController中,我们发现了构造函数,初始化了线程池和重试逻辑。在onAttach()方法中,执行了图片请求并控制其在UI层的显示。PipelineDraweeController作为子类,是后续进一步研究Fresco数据请求和接收机制的起点。

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

DraweeController源码查看

首先看类的继承体系:
DraweeController
–| AbstractDraweeController
—-| PipelineDraweeController

DraweeController源码

DraweeController是一个接口,主要获取设置hierarchy,处理ontach,onTouch等事件
AbstractDraweeController:

构造主要设置线程池,重试手势相关的东西

public AbstractDraweeController(
DeferredReleaser deferredReleaser,
Executor uiThreadImmediateExecutor,
String id,
Object callerContext) {
mDeferredReleaser = deferredReleaser;
mUiThreadImmediateExecutor = uiThreadImmediateExecutor;
init(id, callerContext);
}

具体方法,在这里做分析时,我们重点关注图片如何获取,因而我们关注的核心方法是onAttach(),在这里实现了图片请求的机制,以及图片获取到如何回调,如何显示到UI层的控制,在下面的程序中,看到核心的设置的方法是submitRequest()

@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(mSettableDraweeHierarchy);
    mDeferredReleaser.cancelDeferredRelease(this);
    mIsAttached = true;
    if (!mIsRequestSubmitted) {
      //发送请求
      submitRequest();
    }
  }

// 提交请求
protected void submitRequest() {
    mEventTracker.recordEvent(Event.ON_DATASOURCE_SUBMIT);
    getControllerListener().onSubmit(mId, mCallerContext);
    mSettableDraweeHierarchy.setProgress(0, true);
    mIsRequestSubmitted = true;
    mHasFetchFailed = false;
    // 获取数据源,这个数据源怎么获取的,我们目前不得而知
    mDataSource = getDataSource();
    if (FLog.isLoggable(FLog.VERBOSE)) {
      FLog.v(
          TAG,
          "controller %x %s: submitRequest: dataSource: %x",
          System.identityHashCode(this),
          mId,
          System.identityHashCode(mDataSource));
    }
    final String id = mId;
    final boolean wasImmediate = mDataSource.hasResult();

    // 请求结果的回调
    final DataSubscriber<T> dataSubscriber =
        new BaseDataSubscriber<T>() {
          @Override
          public void onNewResultImpl(DataSource<T> dataSource) {
            // isFinished must be obtained before image, otherwise we might set intermediate result
            // as final image.
            boolean isFinished = dataSource.isFinished();
            float progress = dataSource.getProgress();
            T image = dataSource.getResult();
            if (image != null) {
              onNewResultInternal(id, dataSource, image, progress, isFinished, wasImmediate);
            } else if (isFinished) {
              onFailureInternal(id, dataSource, new NullPointerException(), /* isFinished */ true);
            }
          }
          @Override
          public void onFailureImpl(DataSource<T> dataSource) {
            onFailureInternal(id, dataSource, dataSource.getFailureCause(), /* isFinished */ true);
          }
          @Override
          public void onProgressUpdate(DataSource<T> dataSource) {
            boolean isFinished = dataSource.isFinished();
            float progress = dataSource.getProgress();
            onProgressUpdateInternal(id, dataSource, progress, isFinished);
          }
        };
    // 给数据源注册观察者
    mDataSource.subscribe(dataSubscriber, mUiThreadImmediateExecutor);
  }

下面我们再看看请求成功了干了些什么:onNewResultInternal

private void onNewResultInternal(
      String id,
      DataSource<T> dataSource,
      @Nullable T image,
      float progress,
      boolean isFinished,
      boolean wasImmediate) {
    // ignore late callbacks (data source that returned the new result is not the one we expected)

    // 判断是不是需要的数据,不是就释放资源
    if (!isExpectedDataSource(id, dataSource)) {
      logMessageAndImage("ignore_old_datasource @ onNewResult", image);
      releaseImage(image);
      dataSource.close();
      return;
    }
    mEventTracker.recordEvent(
        isFinished ? Event.ON_DATASOURCE_RESULT : Event.ON_DATASOURCE_RESULT_INT);
    // create drawable
    Drawable drawable;
    try {
      drawable = createDrawable(image);
    } catch (Exception exception) {
      logMessageAndImage("drawable_failed @ onNewResult", image);
      releaseImage(image);
      onFailureInternal(id, dataSource, exception, isFinished);
      return;
    }
    T previousImage = mFetchedImage;
    Drawable previousDrawable = mDrawable;
    mFetchedImage = image;
    mDrawable = drawable;
    try {
      // set the new image

     // 是想要的数据源,set image 同时释放之前缓存的图片
      if (isFinished) {
        logMessageAndImage("set_final_result @ onNewResult", image);
        mDataSource = null;
        mSettableDraweeHierarchy.setImage(drawable, 1f, wasImmediate);
        getControllerListener().onFinalImageSet(id, getImageInfo(image), getAnimatable());
        // IMPORTANT: do not execute any instance-specific code after this point
      } else {
        logMessageAndImage("set_intermediate_result @ onNewResult", image);
        mSettableDraweeHierarchy.setImage(drawable, progress, wasImmediate);
        getControllerListener().onIntermediateImageSet(id, getImageInfo(image));
        // IMPORTANT: do not execute any instance-specific code after this point
      }
    } finally {
      if (previousDrawable != null && previousDrawable != drawable) {
        releaseDrawable(previousDrawable);
      }
      if (previousImage != null && previousImage != image) {
        logMessageAndImage("release_previous_result @ onNewResult", previousImage);
        releaseImage(previousImage);
      }
    }
  }

PipelineDraweeController是AbstractDraweeController的子类也不需要过多打关注,我们现在有一个疑问点就是Fresco的数据请求是怎么发送出去的,又是怎么获取的,后面我们在一起读源代码。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值