Fresco 源码分析(一) DraweeView-DraweeHierarchy-DraweeController(MVC) DraweeView的分析
来源:互联网 发布:苹果手机清楚应用数据 编辑:程序博客网 时间:2024/05/03 00:33
4. Fresco的内容
为了方便学习,我们先从使用结合官方的文档来分析
4.1 Fresco客户端的使用
在使用Fresco的使用,我们直接使用的是SimpleDraweeView这个类,然后在Activity或者Fragment中使用findViewById,然后便调用SimpleDraweeView.setImageUri(),这个方法,便直接可以加载图片,那么在这之间到底是怎么做的呢?结果打开SimpleDraweeView这个类,发现其继承体系,又发现中间有其他一些类,如果只是硬着头皮看代码,我们也会发现其中的逻辑,但是通过官方文档的介绍,我们会降低分析的时间花销
官方关于SimpleDraweeView的介绍
4.1.1 Drawees
rawees 负责图片的呈现,包含几个组件,有点像MVC模式
4.1.2 DraweeView(Viewer)
继承于 View, 负责图片的显示。
4.1.3 DraweeHierarchy(Model)
DraweeHierarchy 用于组织和维护最终绘制和呈现的Drawable对象,相当于MVC中的M。
4.1.4 DraweeController(Controller)
DraweeController 负责和 image loader 交互(默认是Fresco中 image pipeline),可以创建一个这个类的实例,来实现对所要显示的图片做更多的控制
4.1.5 DraweeView(Viewer)-DraweeHierarchy(Model)-DraweeController(Controller)的代码体现
了解通用的MVC模式,便知道Model负责的是持有数据,Viewer用于展示数据,Controller用于控制数据的逻辑,即核心的控制逻辑位于Controller中
MVC的示意图:
这个只是通用的MVC示意图,那么在Drawees中是如何体现呢:
在查看三者的关系时,我们从Viewer入手,在查看SimpleDraweeView,先看其继承体系
4.1.5.1 视图层DraweeView继承体系及各个类的作用
DraweeView
–| GenericDraweeView
——| SimpleDraweeView
DraweeView (Viewer)
获取和设置Hierarchy+Controller,DraweeView的相关信息在DraweeHolder中
DraweeHolder是一个辅助的类,解耦的设计方式,将需要设置以及传递控制的信息,全部交给DrawHolder来实现
GenericDraweeView
解析在xml中设置的属性
SimpleDraweeView
1. 从外界设置ConrolllerBuilderSupplier
2. 可以设置ImageUri
核心的业务逻辑位于DraweeView中
在控件初始化时,初始化了一个DraweeHolder
DraweeView的初始化源码
private DraweeHolder<DH> mDraweeHolder; public DraweeView(Context context) { super(context); init(context); } public DraweeView(Context context, AttributeSet attrs) { super(context, attrs); init(context); } public DraweeView(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); init(context); } //---init中创建了一个DraweeHolder private void init(Context context) { mDraweeHolder = DraweeHolder.create(null, context); }
再查看剩余的DraweeView的程序,发现其均将只是将相关事件传递给DraweeHolder,这是一种解耦的设计方式,以后就是不采用DraweeView,采用其他的方式,照样可以使用这套逻辑
DraweeView的剩余源码
查看完DraweeView的源码后,再查看其子类的源码,刚才已经提到,GenericDraweeView解析在xml中设置的属性
public void setHierarchy(DH hierarchy) { mDraweeHolder.setHierarchy(hierarchy); super.setImageDrawable(mDraweeHolder.getTopLevelDrawable()); } public DH getHierarchy() { return mDraweeHolder.getHierarchy(); } public boolean hasHierarchy() { return mDraweeHolder.hasHierarchy(); } @Nullable public Drawable getTopLevelDrawable() { return mDraweeHolder.getTopLevelDrawable(); } public void setController(@Nullable DraweeController draweeController) { mDraweeHolder.setController(draweeController); super.setImageDrawable(mDraweeHolder.getTopLevelDrawable()); } @Nullable public DraweeController getController() { return mDraweeHolder.getController(); } public boolean hasController() { return mDraweeHolder.getController() != null; } @Override protected void onAttachedToWindow() { super.onAttachedToWindow(); mDraweeHolder.onAttach(); } @Override protected void onDetachedFromWindow() { super.onDetachedFromWindow(); mDraweeHolder.onDetach(); } @Override public void onStartTemporaryDetach() { super.onStartTemporaryDetach(); mDraweeHolder.onDetach(); } @Override public void onFinishTemporaryDetach() { super.onFinishTemporaryDetach(); mDraweeHolder.onAttach(); } @Override public boolean onTouchEvent(MotionEvent event) { if (mDraweeHolder.onTouchEvent(event)) { return true; } return super.onTouchEvent(event); } @Override @Deprecated public void setImageDrawable(Drawable drawable) { mDraweeHolder.setController(null); super.setImageDrawable(drawable); } @Override @Deprecated public void setImageBitmap(Bitmap bm) { mDraweeHolder.setController(null); super.setImageBitmap(bm); } @Override @Deprecated public void setImageResource(int resId) { mDraweeHolder.setController(null); super.setImageResource(resId); } @Override @Deprecated public void setImageURI(Uri uri) { mDraweeHolder.setController(null); super.setImageURI(uri); }
GenericDraweeView构造的源码
构造的源码,分为两种,一种是从外界直接设置GenericDraweeHierarchy,另外一种是普通的xml中直接生成的GenericDraweeView,其实都是在自身设置了一个hierarchy,设置给了DraweeHolder,并且直接设置自身显示的view,获取的是DraweeHolder的topDrawable,这个DraweeHolder的getTopDrawable(),其实还是获取的GenericDraweeHierarchy的getTopDrawable()
public class GenericDraweeView extends DraweeView<GenericDraweeHierarchy> { private float mAspectRatio = 0; private final AspectRatioMeasure.Spec mMeasureSpec = new AspectRatioMeasure.Spec(); public GenericDraweeView(Context context, GenericDraweeHierarchy hierarchy) { super(context); setHierarchy(hierarchy); } public GenericDraweeView(Context context) { super(context); inflateHierarchy(context, null); } public GenericDraweeView(Context context, AttributeSet attrs) { super(context, attrs); inflateHierarchy(context, attrs); } public GenericDraweeView(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); inflateHierarchy(context, attrs); }}
inflateHierarchy()的源码
在inflater的过程中,使用了构造者模式,构造者模式,一般适用于类的属性比较多,并且需要链式书写,在安卓的使用中,AlertDialog中也是使用了构造者模式,虽然模式很好用,但是写起来比较费劲,因为感觉好多东西感觉都是重复的
private void inflateHierarchy(Context context, @Nullable AttributeSet attrs) { ...... int fadeDuration = GenericDraweeHierarchyBuilder.DEFAULT_FADE_DURATION; // images & scale types defaults int placeholderId = 0; ...... if (attrs != null) { TypedArray gdhAttrs = context.obtainStyledAttributes( attrs, R.styleable.GenericDraweeView); try { // fade duration fadeDuration = gdhAttrs.getInt( R.styleable.GenericDraweeView_fadeDuration, fadeDuration); //----解析xml中设置的各个属性 ....... } finally { gdhAttrs.recycle(); } } GenericDraweeHierarchyBuilder builder = new GenericDraweeHierarchyBuilder(resources); // set fade duration builder.setFadeDuration(fadeDuration); // set images & scale types if (placeholderId > 0) { builder.setPlaceholderImage(resources.getDrawable(placeholderId), placeholderScaleType); } //---将解析出来的xml属性,设置给builder中的相关属性 ...... setHierarchy(builder.build()); }
SimpleDraweeView的源码分析
分析方式同上,先查看构造函数,然后看其他方法,
构造方法方法,同样是两种方法,一种是支持从类中直接创建的,另外一种是从xml中创建出来的,在这两种方式中,都是先调用的父类的构造方法,然后在init中初始化了一个SimpleDraweeControllerBuilder
private SimpleDraweeControllerBuilder mSimpleDraweeControllerBuilder; public SimpleDraweeView(Context context, GenericDraweeHierarchy hierarchy) { super(context, hierarchy); init(); } public SimpleDraweeView(Context context) { super(context); init(); } public SimpleDraweeView(Context context, AttributeSet attrs) { super(context, attrs); init(); } public SimpleDraweeView(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); init(); } private void init() { if (isInEditMode()) { return; } Preconditions.checkNotNull( sDraweeControllerBuilderSupplier, "SimpleDraweeView was not initialized!"); mSimpleDraweeControllerBuilder = sDraweeControllerBuilderSupplier.get(); }
在init方法中,用到了一个Preconditions.checkNotNull的方法(这个是google自己提供的java的扩展包,这个包建议大家还是到网上查找相关介绍,因为功能比较强大。),另外,既然在这里都已经判空,那么sDraweeControllerBuilderSupplier肯定是要提前初始化的,在类中查看初始化的位置,发现位于静态的初始化方法中,至于何时调用这个方法,提前告诉大家,是在我们写Fresco.init()的方法,便已经初始化好了的,这就是为什么我们可以轻松的使用这个SimpleDraweeView了
private static Supplier
- Fresco 源码分析(一) DraweeView-DraweeHierarchy-DraweeController(MVC) DraweeView的分析
- Fresco 源码分析(一) DraweeView-DraweeHierarchy-DraweeController(MVC) DraweeHierachy+DraweeController的分析
- Fresco源码简单分析 DraweeView DraweeHierarchy DraweeController
- Fresco前传(2):源码分析 DraweeHierarchy/DraweeView/DraweeController
- Fresco源码分析之DraweeView
- Fresco解析(DraweeView,DraweeHierarchy)
- Fresco正传(2):DraweeView分析
- Fresco源码解析 - DraweeView
- Fresco中Drawee、DraweeHierarchy、DraweeController
- 实现fresco的DraweeView的图片手势缩放
- Fresco正传(3):DraweeHierarchy分析
- Fresco正传(4):DraweeController分析
- Fresco源码之DraweeController
- Fresco Fbcore源码分析_executor(一)
- Fresco 源码分析(序)
- 源码分析之Fresco
- Fresco源码分析
- Fresco源码分析
- Eclipse常用插件
- 对称加密与非对称加密
- 如何修改MFC对话框的窗口标题
- 各种常见排序算法的思路(比较)
- 腾讯面试题——多项式求解
- Fresco 源码分析(一) DraweeView-DraweeHierarchy-DraweeController(MVC) DraweeView的分析
- 字符串分割(C++)
- 内核窥秘之一:start_kernel()运行过程记录 http://blog.csdn.net/yyplc/article/details/7030983
- 插入排序的优化
- CodeForces A. Sereja and Swaps(暴力+贪心啊)
- C程序设计----UNIX系统接口
- android系统浏览器源码剖析
- mantis中issue的状态和解决转台说明
- JSP学习笔记