美文网首页
Android-Fresco系列1 初始化

Android-Fresco系列1 初始化

作者: cg1991 | 来源:发表于2019-06-04 17:59 被阅读0次

    文章将会被同步至微信公众号:Android部落格

    先看流程图:


    image

    一、开始使用

    • 在工程的app目录下的build.gradle添加引用:
    implementation 'com.facebook.fresco:fresco:1.12.0'
    
    • Application类中的onCreate方法中添加初始化:
    Fresco.initialize(this)
    
    • layout xml文件中添加控件定义
    <com.facebook.drawee.view.SimpleDraweeView
            android:id="@+id/my_image_view"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            fresco:placeholderImage="@drawable/ic_launcher_background"
    
    • Activity中添加图片展示
    val uri = Uri.parse("http://ww1.sinaimg.cn/large/610dc034ly1fjaxhky81vj20u00u0ta1.jpg")
    val draweeView = findViewById<SimpleDraweeView>(R.id.my_image_view)
    draweeView.setImageURI(uri)
    

    二、初始化

    1、Fresco

    从Fresco.initialize开始说起。

    public static void initialize(Context context) {
    initialize(context, null, null);
    }
    
    public static void initialize(
      Context context,
      @Nullable ImagePipelineConfig imagePipelineConfig,
      @Nullable DraweeConfig draweeConfig) {
        try {
          SoLoader.init(context, 0);
        } catch (IOException e) {
        }
        // we should always use the application context to avoid memory leaks
        context = context.getApplicationContext();
        if (imagePipelineConfig == null) {
          ImagePipelineFactory.initialize(context);
        } else {
          ImagePipelineFactory.initialize(imagePipelineConfig);
        }
        initializeDrawee(context, draweeConfig);
        if (FrescoSystrace.isTracing()) {
          FrescoSystrace.endSection();
        }
    }
    

    从初始化代码引申出两个配置类ImagePipelineConfig和DraweeConfig。

    2、ImagePipelineFactory

    ImagePipeline工厂类

    1) ImagePipelineConfig

    这个类为ImagePipeline配置参数,是核心的类。
    配置的参数主要有:Bitmap参数,内存缓存相关参数,磁盘缓存相关参数等。
    不设置这个参数的时候sdk会默认初始化:

    //ImagePipelineFactory:initialize
    public static synchronized void initialize(Context context) {
        initialize(ImagePipelineConfig.newBuilder(context).build());
    }
    //ImagePipelineConfig.Builder
    public ImagePipelineConfig build() {
      return new ImagePipelineConfig(this);
    }
    //ImagePipelineConfig
    private ImagePipelineConfig(Builder builder) {
        DefaultBitmapMemoryCacheParamsSupplier//内存缓存
        BitmapMemoryCacheTrimStrategy//内存缓存清理策略
        CacheKeyFactory//缓存数据key,默认DefaultCacheKeyFactory
        FileCacheFactory//文件缓存,默认DiskStorageCacheFactory(DynamicDefaultDiskStorageFactory)
        MemoryCacheParams//内存缓存配置,默认DefaultEncodedMemoryCacheParamsSupplier
        ImageDecoder//图片解码,创建一个CloseableImage对象
        ImageTranscoderFactory//图片变换,resize,如果设置resizeable为true才有效
        DiskCacheConfig//磁盘缓存配置,不设置的话,sdk默认配置一个
        MemoryTrimmableRegistry//注册系统内存剩余容量通知
        NetworkFetcher//在线图片下载类,默认初始化为HttpUrlConnectionNetworkFetcher,使用HttpUrlConnection下载
        PlatformBitmapFactory//依据Bitmap参数生成优化后的bitmao
        PoolFactory//参数配置池,定义一些对象池
        ProgressiveJpegConfig//jpeg配置进度
        ImageDecoderConfig//图片解码配置
        ExecutorSupplier//不同场景下的线程池提供者,默认配置DefaultExecutorSupplier
        ...
    }
    

    在此会创建一个ImagePipelineConfig类,包含各种图片的配置信息。
    接下来初始化一个ImagePipelineFactory类:

    //ImagePipelineFactory
    public static synchronized void initialize(ImagePipelineConfig imagePipelineConfig) {
        sInstance = new ImagePipelineFactory(imagePipelineConfig);
    }
    
    public ImagePipelineFactory(ImagePipelineConfig config) {
        mConfig = Preconditions.checkNotNull(config);
        mThreadHandoffProducerQueue =
            new ThreadHandoffProducerQueue(
                config.getExecutorSupplier().forLightweightBackgroundTasks());
    }
    

    config.getExecutorSupplier()是DefaultExecutorSupplier对象,这个ThreadHandoffProducerQueue类用来管理线程池队列,管理队列的开始停止,执行线程池。

    3、DraweeConfig

    //Fresco
    private static void initializeDrawee(Context context, @Nullable DraweeConfig draweeConfig) {
        sDraweeControllerBuilderSupplier =
            new PipelineDraweeControllerBuilderSupplier(context, draweeConfig);
        SimpleDraweeView.initialize(sDraweeControllerBuilderSupplier);
    }
    
    1) PipelineDraweeControllerBuilderSupplier

    在这个类中初始化了ImagePipeline,并剔除部分不关心的代码:

    public PipelineDraweeControllerBuilderSupplier(
          Context context,
          ImagePipelineFactory imagePipelineFactory,
          Set<ControllerListener> boundControllerListeners,
          @Nullable DraweeConfig draweeConfig) {
        mImagePipeline = imagePipelineFactory.getImagePipeline();
    
        if (draweeConfig != null && draweeConfig.getPipelineDraweeControllerFactory() != null) {
          mPipelineDraweeControllerFactory = draweeConfig.getPipelineDraweeControllerFactory();
        } else {
          mPipelineDraweeControllerFactory = new PipelineDraweeControllerFactory();
        }
        mPipelineDraweeControllerFactory.init();
    }
    
    2) ImagePipelineFactory

    初始化ImagePipeline的过程在ImagePipelineFactory类中:

    public getImagePipeline() {
        if (mImagePipeline == null) {
          mImagePipeline =
              new ImagePipeline(
                  getProducerSequenceFactory(),
                  mConfig.getRequestListeners(),
                  mConfig.getIsPrefetchEnabledSupplier(),
                  getBitmapMemoryCache(),
                  getEncodedMemoryCache(),
                  getMainBufferedDiskCache(),
                  getSmallImageBufferedDiskCache(),
                  mConfig.getCacheKeyFactory(),
                  mThreadHandoffProducerQueue,
                  Suppliers.of(false),
                  mConfig.getExperiments().isLazyDataSource(),
                  mConfig.getCallerContextVerifier());
        }
        return mImagePipeline;
    }
    
    3) PipelineDraweeControllerFactory

    接下来初始化一个PipelineDraweeControllerFactory类,并调用其init方法:

    mPipelineDraweeControllerFactory = new PipelineDraweeControllerFactory();
    mPipelineDraweeControllerFactory.init(Resources,DeferredReleaser,DrawableFactory,UiThreadImmediateExecutorService,MemoryCache,DrawableFactory);
    
    4) ImagePipeline

    在getImagePipeline函数的参数中初始化了几个类,分别是:

    • ProducerSequenceFactory//(getProducerSequenceFactory)
    • ProducerFactory//(getProducerSequenceFactory 方法中初始化ProducerSequenceFactory类获取该对象)
    • ContentResolver(初始化ProducerSequenceFactory类获取该对象)
    • ProducerFactor(在初始化ProducerSequenceFactory类时调用getProducerFactory方法)
    • BitmapMemoryCacheFactory(InstrumentedMemoryCache<CountingMemoryCache>)
    • EncodedMemoryCacheFactory(InstrumentedMemoryCache<CountingMemoryCache>)
    • BufferedDiskCache(mMainBufferedDiskCache<DiskCacheConfig>)
    • BufferedDiskCache(mSmallImageFileCache<DiskCacheConfig>)

    这个类的初始化牵涉到很多工作类的初始化,Producer是生产者,主要生产编解码类,缓存处理类,Bitmap生产类等。

    3、SimpleDraweeView

    这个类在初始化的时候只初始化了一个对象:

    SimpleDraweeView.initialize(sDraweeControllerBuilderSupplier);
    public static void initialize(
      Supplier<? extends AbstractDraweeControllerBuilder> draweeControllerBuilderSupplier) {
        sDraweecontrollerbuildersupplier = draweeControllerBuilderSupplier;
    }
    

    三、SimpleDraweeView初始化

    1) 构造函数

    当在xml中定义了SimpleDraweeView,在Activity的onCreate方法中开始加载图片的时候,首先会初始化这个View控件:

    //SimpleDraweeView
    @TargetApi(Build.VERSION_CODES.LOLLIPOP)
    public SimpleDraweeView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
        super(context, attrs, defStyleAttr, defStyleRes);
        init(context, attrs);
    }
    

    2) super

    先调用父类构造函数,父类的继承关系是GenericDraweeView -> DraweeView -> ImageView.

    • DraweeView

    在构造函数中,先调用父类ImageView的构造函数,再执行自己的init函数:

    //DraweeView
    private void init(Context context) {
        mDraweeHolder = DraweeHolder.create(null, context);
    }
    //DraweeHolder
    public static <DH extends DraweeHierarchy> DraweeHolder<DH> create(
      @Nullable DH hierarchy,
      Context context) {
        DraweeHolder<DH> holder = new DraweeHolder<DH>(hierarchy);
        holder.registerWithContext(context);
        return holder;
    }
    

    3) GenericDraweeView

    在构造函数中,先调用父类DraweeView的构造函数,再运行自己的inflateHierarchy方法:

    //GenericDraweeView
    protected void inflateHierarchy(Context context, @Nullable AttributeSet attrs) {
        GenericDraweeHierarchyBuilder builder =
            GenericDraweeHierarchyInflater.inflateBuilder(context, attrs);
        setAspectRatio(builder.getDesiredAspectRatio());
        setHierarchy(builder.build());
    }
    
    //GenericDraweeHierarchyInflater
    public static GenericDraweeHierarchyBuilder inflateBuilder(
      Context context, @Nullable AttributeSet attrs) {
        Resources resources = context.getResources();
        GenericDraweeHierarchyBuilder builder = new GenericDraweeHierarchyBuilder(resources);
        builder = updateBuilder(builder, context, attrs);
        return builder;
    }
    

    创建一个GenericDraweeHierarchyBuilder对象,然后执行updateBuilder方法,在这个方法中,读取所有xml文件中设置的参数,并将参数统一封装到GenericDraweeHierarchyBuilder对象中。

    4) GenericDraweeHierarchy

    Hierarchy意思是等级制度,阶层的意思

    接下来执行builder.build()生成一个GenericDraweeHierarchy对象:

    public GenericDraweeHierarchy build() {
        validate();
        return new GenericDraweeHierarchy(this);
    }
    

    GenericDraweeHierarchy的继承关系是:GenericDraweeHierarchy -> SettableDraweeHierarchy -> DraweeHierarchy。

    GenericDraweeHierarchy构造函数中做了以下几件事情:

    • RoundingParams 圆形图片参数
    • ForwardingDrawable 图片Drawable加载状态回调
    • layers,Drawable数组类型,从下到上定义了六层:
    private static final int BACKGROUND_IMAGE_INDEX = 0;//背景
    private static final int PLACEHOLDER_IMAGE_INDEX = 1;//占位
    private static final int ACTUAL_IMAGE_INDEX = 2;//实际展示图
    private static final int PROGRESS_BAR_IMAGE_INDEX = 3;//进度
    private static final int RETRY_IMAGE_INDEX = 4;//重试
    private static final int FAILURE_IMAGE_INDEX = 5;//失败
    private static final int OVERLAY_IMAGES_INDEX = 6;//图片覆盖
    
    • FadeDrawable 渐变Drawable,构造函数参数是layers
    • RootDrawable 根Drawable,可以回调Drawable visiable变化,在Drawable不可见时不调用绘制方法

    接下来执行setHierarchy将DraweeHierarchy对象设置到父类DraweeView中:

    //DraweeView
    public void setHierarchy(DH hierarchy) {
        mDraweeHolder.setHierarchy(hierarchy);
        super.setImageDrawable(mDraweeHolder.getTopLevelDrawable());
    }
    

    mDraweeHolder对象在DraweeView构造函数中初始化。

    5) init

    SimpleDraweeView中

    init方法中判断当前是否是编辑模式,isInEditMode,例如在Android Studio中设计布局的时候,View的这个方法可以返回true,此时可以自定义一个画布,避免开发的过程中无法实时预览到自定义控件的轮廓。

    另外还读取了在视图xml文件中对SimpleDraweeView设置的一些参数。

    同时如果不是编辑模式的时候,初始化了一个:

    mControllerBuilder = sDraweecontrollerbuildersupplier.get();
    

    这个sDraweecontrollerbuildersupplier对象对应的是PipelineDraweeControllerBuilderSupplier类,get方法如下:

    @Override
    public PipelineDraweeControllerBuilder get() {
        PipelineDraweeControllerBuilder pipelineDraweeControllerBuilder =
            new PipelineDraweeControllerBuilder(
                mContext, mPipelineDraweeControllerFactory, mImagePipeline, mBoundControllerListeners);
        return pipelineDraweeControllerBuilder.setPerfDataListener(mDefaultImagePerfDataListener);
    }
    

    这里新建了一个PipelineDraweeControllerBuilder类,封装了ImagePipeline和PipelineDraweeControllerFactory对象。这个类继承自AbstractDraweeControllerBuilder,该类实现了SimpleDraweeControllerBuilder接口。

    此时初始化控件完毕,接下来开始设置图片资源并开始加载。

    微信公众号二维码:


    image

    相关文章

      网友评论

          本文标题:Android-Fresco系列1 初始化

          本文链接:https://www.haomeiwen.com/subject/stprxctx.html