博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Fresco 源码分析(二) Fresco客户端与服务端交互(1) 解决遗留的Q1问题
阅读量:4319 次
发布时间:2019-06-06

本文共 9586 字,大约阅读时间需要 31 分钟。

4.2 Fresco客户端与服务端的交互(一) 解决Q1问题

从这篇博客开始,我们开始讨论客户端与服务端是如何交互的,这个交互的入口,我们从Q1问题入手(博客按照这样的问题入手,是因为当时我也是从这里好奇,才开始分析如何交互的,这样避免了思维的跳跃性)

既然我们想从这里入手,那么还是以controller的请求入手,因为请求是从这里发出去的,那么肯定入口就存在于AbstractDraweeController.submitRequest()方法,上源码: 在刚刚查看源码时,我们并没有提及到getDataSource()方法是如何实现的,我们先再浏览一遍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
dataSubscriber = new BaseDataSubscriber
() { @Override public void onNewResultImpl(DataSource
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
dataSource) { onFailureInternal(id, dataSource, dataSource.getFailureCause(), /* isFinished */ true); } @Override public void onProgressUpdate(DataSource
dataSource) { boolean isFinished = dataSource.isFinished(); float progress = dataSource.getProgress(); onProgressUpdateInternal(id, dataSource, progress, isFinished); } }; mDataSource.subscribe(dataSubscriber, mUiThreadImmediateExecutor); }

在看到getDataSource方法时,我们查看其方法,发现是抽象方法,查看类的继承关系图,得知,实现类有两个PipelineDraweeController和VolleyDraweeController,这个就遇到点困难了,到底采用的是哪个呢?到这里就卡壳了,那么如何处理呢?我们要回到我们起点了,就是在写demo的时候,我们一般在Application 的实现类中的onCreate方法中,调用Fresco.initialize()方法,不得不从这里开始看,因为所有的初始化信息,是在这里实现的(这可不是步步高打火机,那里不会点哪里,哈哈哈)

4.2.1 Fresco初始化的过程

为了要了解getDataSource()方法使用的是哪个实现类,我们从Fresco.initialize()方法入手,分析Fresco初始化的过程

在书写demo的时候,从官方的说明中,已经得知,一般是在Application的onCreate()方法中调用Fresco.initialize()方法,那么这里做了什么样的操作呢?从方法名也可知,这是做了初始化,但是具体需要初始化那些信息呢?
*** Fresco.initialize() 源码 ***

/** Initializes Fresco with the default config. */  public static void initialize(Context context) {    ImagePipelineFactory.initialize(context);    initializeDrawee(context);  }

从上边的源码可知,初始化了两部分信息

  1. ImagePipelineFactory做了初始化
  2. 初始化了Drawee组件信息

note: 个人查看他人代码,可将这个过程当做图来处理,可以做广度查看,也可以按照深度查看,个人建议,广度做了解,了解当前方法的大致流程(对于书写比较规范的框架,一般是见名知意的)然后做每个方法的深度遍历,便了解,边做笔记。

上述已经得知,先做ImagePipelineFactory的初始化,然后初始化Drawee组件,那么就先查看ImagePipelineFactory的初始化

4.2.1.1 ImagePipelineFactory的初始化

*** ImagePipelineFactory.initialize() 源码 ***

/** Initializes {@link ImagePipelineFactory} with default config. */  public static void initialize(Context context) {    initialize(ImagePipelineConfig.newBuilder(context).build());  }  /** Initializes {@link ImagePipelineFactory} with the specified config. */  public static void initialize(ImagePipelineConfig imagePipelineConfig) {    sInstance = new ImagePipelineFactory(imagePipelineConfig);  }  public ImagePipelineFactory(ImagePipelineConfig config) {    mConfig = Preconditions.checkNotNull(config);  }

初始化过程,构造了一个ImagePipelineConfig,然后将创建的ImagePipelineConfig用于初始化ImagePipelineFactory,即新建了一个ImagePipelineFactory,新创建的ImagePipelineFactory保存了ImagePipelineConfig的实例

note:这里再次使用了构造者模式

下面需要关注的就变为了ImagePipelineConfig.newBuilder(context).build()的操作

*** ImagePipelineConfig.newBuilder(context).build()的源码 ***

public static Builder newBuilder(Context context) {    return new Builder(context);  } public static class Builder {    ......    private Builder(Context context) {      // Doesn't use a setter as always required.      mContext = Preconditions.checkNotNull(context);    }    ......         public ImagePipelineConfig build() {      return new ImagePipelineConfig(this);    }  }

从查看ImagePipelineConfig的上述源码,得知,核心的初始化方法,在Builder.build()方法中,而在builder中创建了一个ImagePipelineConfig对象,而依附的对象为builder,这就到了ImagePipelineConfig的核心处

private ImagePipelineConfig(Builder builder) {    mBitmapMemoryCacheParamsSupplier =        builder.mBitmapMemoryCacheParamsSupplier == null ?            new DefaultBitmapMemoryCacheParamsSupplier(                (ActivityManager) builder.mContext.getSystemService(Context.ACTIVITY_SERVICE)) :            builder.mBitmapMemoryCacheParamsSupplier;    mCacheKeyFactory =        builder.mCacheKeyFactory == null ?            DefaultCacheKeyFactory.getInstance() :            builder.mCacheKeyFactory;    mContext = Preconditions.checkNotNull(builder.mContext);    mEncodedMemoryCacheParamsSupplier =        builder.mEncodedMemoryCacheParamsSupplier == null ?            new DefaultEncodedMemoryCacheParamsSupplier() :            builder.mEncodedMemoryCacheParamsSupplier;    mExecutorSupplier =        builder.mExecutorSupplier == null ?            new DefaultExecutorSupplier() :            builder.mExecutorSupplier;    mImageCacheStatsTracker =        builder.mImageCacheStatsTracker == null ?            NoOpImageCacheStatsTracker.getInstance() :            builder.mImageCacheStatsTracker;    mIsPrefetchEnabledSupplier =          builder.mIsPrefetchEnabledSupplier == null ?              new Supplier
() { @Override public Boolean get() { return true; } } : builder.mIsPrefetchEnabledSupplier; mMainDiskCacheConfig = builder.mMainDiskCacheConfig == null ? getDefaultMainDiskCacheConfig(builder.mContext) : builder.mMainDiskCacheConfig; mMemoryTrimmableRegistry = builder.mMemoryTrimmableRegistry == null ? NoOpMemoryTrimmableRegistry.getInstance() : builder.mMemoryTrimmableRegistry; mPoolFactory = builder.mPoolFactory == null ? new PoolFactory(PoolConfig.newBuilder().build()) : builder.mPoolFactory; mProgressiveJpegConfig = builder.mProgressiveJpegConfig == null ? new SimpleProgressiveJpegConfig() : builder.mProgressiveJpegConfig; mRequestListeners = builder.mRequestListeners == null ? new HashSet
() : builder.mRequestListeners; mResizeAndRotateEnabledForNetwork = builder.mResizeAndRotateEnabledForNetwork; mSmallImageDiskCacheConfig = builder.mSmallImageDiskCacheConfig == null ? mMainDiskCacheConfig : builder.mSmallImageDiskCacheConfig; mAnimatedDrawableUtil = new AnimatedDrawableUtil(); AnimatedDrawableBackendProvider animatedDrawableBackendProvider = new AnimatedDrawableBackendProvider() { @Override public AnimatedDrawableBackend get(AnimatedImageResult imageResult, Rect bounds) { return new AnimatedDrawableBackendImpl(mAnimatedDrawableUtil, imageResult, bounds); } }; GingerbreadBitmapFactory factoryGingerbread = new GingerbreadBitmapFactory(); DalvikBitmapFactory factoryICS = new DalvikBitmapFactory( new EmptyJpegGenerator(mPoolFactory.getPooledByteBufferFactory()), mPoolFactory.getSharedByteArray()); ArtBitmapFactory factoryLollipop = new ArtBitmapFactory(mPoolFactory.getBitmapPool()); mPlatformBitmapFactory = new PlatformBitmapFactory( factoryGingerbread, factoryICS, factoryLollipop); mAnimatedImageFactory = builder.mAnimatedImageFactory == null ? new AnimatedImageFactory(animatedDrawableBackendProvider, mPlatformBitmapFactory) : builder.mAnimatedImageFactory; mImageDecoder = builder.mImageDecoder == null ? new ImageDecoder(mAnimatedImageFactory, mPlatformBitmapFactory) : builder.mImageDecoder; mNetworkFetcher = builder.mNetworkFetcher == null ? new HttpUrlConnectionNetworkFetcher() : builder.mNetworkFetcher; }

上述源码是ImagePipelineConfig的构造,发现此处初始化涉及的信息比较多,为了方便理解,我们先从名称上做一下理解,一会儿用到的时候,再反过来查看相关的详情信息

此类的名称特别形象,就是ImagePipleline的配置类,这其中配置了比较核心的几项

  1. mBitmapMemoryCacheParamsSupplier 内存缓存数据的策略
  2. mCacheKeyFactory 缓存键值对的获取
  3. mExecutorSupplier 获取本地读写线程池,网络数据线程池,解码线程池,以及后台线程池
  4. mImageDecoder 解码器
  5. 网络数据获取器
    ......

ImagePipeLineConfig是一个比较核心的类,通过这个,我们可以得知,Freco初始化时,配置了大量的策略,可配置项很多,也就让我们的使用更加灵活和易于拓展

4.2.1.2 Fresco.initializeDrawee()的过程

private static void initializeDrawee(Context context) {    sDraweeControllerBuilderSupplier = new PipelineDraweeControllerBuilderSupplier(context);    SimpleDraweeView.initialize(sDraweeControllerBuilderSupplier);  }

从上述可知,构造了一个sDraweeControllerBuilderSupplier,然后将这个supplier用于初始化SimpleDraweeView

哎!找到了,发现使用的是PipelineDraweeControllerBuilderSupplier,是不是分析到这里我们就可以结束了?答案是我们只是找到了用于初始化SimpleDraweeView的supplier是PipelineDraweeControllerBuilderSupplier,但是这个做的是怎么样的一个操作呢?我们下节再讨论
下篇链接: Fresco 源码分析(二) Fresco.initializeDrawee()分析 续 http://www.cnblogs.com/pandapan/p/4659960.html

安卓源码分析群: Android源码分析QQ1群号:164812238

转载于:https://www.cnblogs.com/pandapan/p/4646786.html

你可能感兴趣的文章
java开发操作系统内核:由实模式进入保护模式之32位寻址
查看>>
第五讲:单例模式
查看>>
Python编程语言的起源
查看>>
Azure ARMTemplate模板,VM扩展命令
查看>>
在腾讯云上创建您的SQL Cluster(4)
查看>>
linux ping命令
查看>>
Activiti源码浅析:Activiti的活动授权机制
查看>>
数位dp整理
查看>>
UNIX基础知识
查看>>
bzoj 1179: [Apio2009]Atm
查看>>
利用LDA进行文本聚类(hadoop, mahout)
查看>>
第三周作业
查看>>
js添加删除行
查看>>
浏览器性能测试网址
查看>>
[MTK FP]用Python把图片资源image.rar中为.pbm后缀的文件更改为.bmp后缀的方法
查看>>
实验二
查看>>
[LeetCode]203. Remove Linked List Elements 解题小结
查看>>
测试一下
查看>>
vue base64
查看>>
【Django实战开发】案例一:创建自己的blog站点-1.安装及搭建开发环境
查看>>