Fresco 源碼分析(二) Fresco客戶端與服務端交互(3) 前後臺打通

4.2.1.2.4 PipelineDraweeControllerBuilder.obtainController()源碼分析 續

上節中我們提到兩個核心的步驟
1. obtainDataSourceSupplier()獲取到了一個DataSourceSupplier
2. 然後mPipelineDraweeControllerFactory類new了一個controller

還是先從廣度分析,然後再深度分析
* PipelineDraweeController.newController()源碼 *

在這裏無非新創建了一個PipelineDraweeController

  public PipelineDraweeController newController(
      Supplier<DataSource<CloseableReference<CloseableImage>>> dataSourceSupplier,
      String id,
      Object callerContext) {
    return new PipelineDraweeController(
        mResources,
        mDeferredReleaser,
        mAnimatedDrawableFactory,
        mUiThreadExecutor,
        dataSourceSupplier,
        id,
        callerContext);
  }

那廣度就先看到這裏,這時就要再從深度開始看
這時我們要看以下的幾個方法
1. PipelineDraweeControllerBuilder.obtainDataSourceSupplier()的過程
2. 新建PipelineDraweeController的過程

* AbstractDraweeControllerBuilder.obtainDataSourceSupplier() *

 /** Gets the top-level data source supplier to be used by a controller. */
  protected Supplier<DataSource<IMAGE>> obtainDataSourceSupplier() {
    if (mDataSourceSupplier != null) {
      return mDataSourceSupplier;
    }

    Supplier<DataSource<IMAGE>> supplier = null;

    // final image supplier;
    if (mImageRequest != null) {
      supplier = getDataSourceSupplierForRequest(mImageRequest);
    } else if (mMultiImageRequests != null) {
      supplier = getFirstAvailableDataSourceSupplier(mMultiImageRequests);
    }

    // increasing-quality supplier; highest-quality supplier goes first
    if (supplier != null && mLowResImageRequest != null) {
      List<Supplier<DataSource<IMAGE>>> suppliers = new ArrayList<>(2);
      suppliers.add(supplier);
      suppliers.add(getDataSourceSupplierForRequest(mLowResImageRequest));
      supplier = IncreasingQualityDataSourceSupplier.create(suppliers);
    }

    // no image requests; use null data source supplier
    if (supplier == null) {
      supplier = DataSources.getFailedDataSourceSupplier(NO_REQUEST_EXCEPTION);
    }

    return supplier;
  }

老的分析思路繼續,我們以第一次請求爲例
先判斷圖片請求的信息,如果只是簡單的mImageRequest,那麼獲取到getDataSourceSupplierForRequest()即可,然後,如果發現有漸進式的請求,那麼supplier便基於目前的supplier創建新的supplier

* AbstractDraweeControllerBuilder類的相關方法 *
從下面的方法,便可知,創建了一個對應的Supplier而已,用於獲取請求數據的supplier,注意在獲取到的匿名的supplier的get方法中,我們看到調用的是getDataSourceForRequest方法,這個我們先備註一下: mark爲Q3,便於我們插敘後,繼續分析的入口點

  /** Creates a data source supplier for the given image request. */
  protected Supplier<DataSource<IMAGE>> getDataSourceSupplierForRequest(REQUEST imageRequest) {
    return getDataSourceSupplierForRequest(imageRequest, /* bitmapCacheOnly */ false);
  }



  /** Creates a data source supplier for the given image request. */
  protected Supplier<DataSource<IMAGE>> getDataSourceSupplierForRequest(
      final REQUEST imageRequest,
      final boolean bitmapCacheOnly) {
    final Object callerContext = getCallerContext();
    return new Supplier<DataSource<IMAGE>>() {
      @Override
      public DataSource<IMAGE> get() {
        return getDataSourceForRequest(imageRequest, callerContext, bitmapCacheOnly);
      }
      @Override
      public String toString() {
        return Objects.toStringHelper(this)
            .add("request", imageRequest.toString())
            .toString();
      }
    };
  }

第1部分的深度我們就分析到這裏
第2部分的深度分析:

4.2.1.2.5 插敘 –> AbstractDraweeController.submitRequest()分析 續

在我們分析的第二篇博客中,提到了AbstractDraweeController.submitRequest()方法,但是到了最後,我們只是留下了一個Q1問題,然後並沒有繼續分析下去,現在我們要插敘一段

  protected void submitRequest() {
    ......
    mDataSource = getDataSource();
    ......
    final String id = mId;
    final boolean wasImmediate = mDataSource.hasResult();
    final DataSubscriber<T> dataSubscriber......
    mDataSource.subscribe(dataSubscriber, mUiThreadImmediateExecutor);
  }

這次,我們關注的核心是getDataSource()方法,然而這裏是抽象類,具體使用的是哪個,當時我們無法分析,現在便可以知道,使用的是PipelineDraweeController類的方法

* PipelineDraweeController.getDataSource 源碼分析 *
從以下的代碼中,可以看出,只是從Supplier中獲取到了dataSource而已
@Override
protected DataSource

4.2.1.2.6 AbstractDraweeControllerBuilder是如何發送請求的 即分析Q3問題

在上面已經提到了,客戶端在DraweeController中發送請求的過程中,會調用Supplier的get方法,那麼在這裏邊調用到了AbstractDraweeControllerBuilder.getDataSourceSupplierForRequest()方法中生成的匿名supplier的get()方法

* AbstractDraweeControllerBuilder.getDataSourceSupplierForRequest()方法 *
在以下的方法中,我們看到,匿名的Supplier的get方法中,調用的是AbstractDraweeControllerBuilder自身的getDataSourceForRequest()方法返回的Supplier

  /** Creates a data source supplier for the given image request. */
  protected Supplier<DataSource<IMAGE>> getDataSourceSupplierForRequest(
      final REQUEST imageRequest,
      final boolean bitmapCacheOnly) {
    final Object callerContext = getCallerContext();
    return new Supplier<DataSource<IMAGE>>() {
      @Override
      public DataSource<IMAGE> get() {
        return getDataSourceForRequest(imageRequest, callerContext, bitmapCacheOnly);
      }
      @Override
      public String toString() {
        return Objects.toStringHelper(this)
            .add("request", imageRequest.toString())
            .toString();
      }
    };
  }

那麼就繼續跟蹤唄,發現其爲抽象方法,那麼跟蹤到子類,這時候,我們已經知道使用的是PipelineDraweeControllerBuilder,

* PipelineDraweeControllerBuilder.getDataSourceForRequest()方法 *

  @Override
  protected DataSource<CloseableReference<CloseableImage>> getDataSourceForRequest(
      ImageRequest imageRequest,
      Object callerContext,
      boolean bitmapCacheOnly) {
    if (bitmapCacheOnly) {
      return mImagePipeline.fetchImageFromBitmapCache(imageRequest, callerContext);
    } else {
      return mImagePipeline.fetchDecodedImage(imageRequest, callerContext);
    }
  }

我們模擬的請求是顯示到UI層,所以走的是else,即mImagePipeline.fetchDecodeImage();
那麼這時候就到了ImagePipeline了,這部分用到了包裝的設計模式,以及生產消費的設計模式,又屬於另外一部分了,其實到這裏,我們纔算接觸到ImagePipeline請求的核心,這也是Fresco設計的巧妙之處,很多知識不需要我們關心,我們一般來講,只需要用到SimpleDraweeView即可
到這裏,Fresco客戶端與服務端的交互分析完畢,下一章節便是,服務端的請求是如何發送出去的以及請求回來的數據如何通過回調通知客戶端的
下篇博客鏈接 : Fresco 源碼分析(三) Fresco服務端處理(1) ImagePipeline爲何物 (http://blog.csdn.net/ieyudeyinji/article/details/48251653

安卓源碼分析羣: Android源碼分析QQ1羣號:164812238

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章