Android图片加载框架Fresco分析(一)

作为Android开发者,虽然不是大牛,但也接触了很多图片加载框架,因为手机上最难处理最占内存的往往也就是图片,如果图片处理不好,很容易引起程序崩溃。到目前为止我接触过很多种图片加载框架,其中主要有:UniversalImageLoader,Picasso,Glide,Fresco。
Fresco是Facebook最新推出的一款用于Android应用中展示图片的强大图片库,可以从网络、本地存储和本地资源中加载图片。其中的Drawees可以显示占位符,直到图片加载完成。而当图片从屏幕上消失时,会自动释放内存。由于目前项目中使用到了Fresco,所以针对Fresco做一下源码分析。

1.功能介绍

Fresco类似ImageLoader和Picasoo一样,操作起来都比较简单,几行代码就可以开始使用了。可以简单的在xml里使用SimpleDraweeView配置一些属性。在代码中使用SimpleDraweeViewsetImageURI方法来进行图片的加载。

Fresco有很大的优点,Fresco的中文文档中说的就很明白,主要优点有:

  1. 能够通过Drawees模块让不再显示在屏幕上的图片及时地释放内存和空间。
  2. 能够渐进式加载图片。这也是其他图片加载控件所没有的功能。
  3. 支持加载Gif图,支持WebP格式
  4. 缩放或者旋转图片,圆形圆角图片等等

自定义控件使用isInEditMode防止窗口泄漏

在开发过程中有时候会遇到Activity has leaked window.,此时便是出现了窗口泄漏问题。

Android的每一个Activity都有个WindowManager窗体管理器,同样构建在某个Activity之上的对话框、PopupWindow也有相应的WindowManager窗体管理器。因为对话框、PopupWindow不能脱离Activity而单独存在着,所以当某个Dialog或者某个PopupWindow正在显示的时候我们去finish()了承载该Dialog或PopupWindow的 Activity时,就会抛WindowLeaked异常了,因为这个Dialog或PopupWindow的WindowManager已经没有谁可以附属了,所以它的窗体管理器已经泄漏了。

使用isInEditMode解决可视化编辑器无法识别自定义控件的问题

isInEditMode:
Indicates whether this View is currentlyin edit mode. A View is usually in edit mode when displayed within a developertool. For instance, if this View is being drawn by a visual user interfacebuilder, this method should return true. Subclasses should check the returnvalue of this method to provide different behaviors if their normal behaviormight interfere with the host environment. For instance: the class spawns athread in its constructor, the drawing code relies on device-specific features,etc. This method is usually checked in the drawing code of custom widgets.

所以可以在自定义view的初始化或者需要加载界面的地方设置此方法,避免导致窗体泄漏的问题。

private void init() {
  if (isInEditMode()) {
    return;
  }
  //初始化代码
}

Android自动换行ViewGroup

在Android开发过程中经常会碰到需要让某一些控件,比如:Textview作为标签,而这些标签还要能够自适应屏幕,即要求能够超过一行的宽度时自动换到下一行。Android本身是没有这个控件的。实现起来也不是很难。下面描述一下如何实现这个viewGroup。
首先,我们需要知道控件内部的子view的三个属性:横向间距纵向间距子view方向(orientation)。需要先设置控件属性。代码如下:

<declare-styleable name="FlowLayout">
    <attr name="horizontalSpacing" format="dimension" />
    <attr name="verticalSpacing" format="dimension" />
    <attr name="orientation" format="enum">
        <enum name="horizontal" value="0" />
        <enum name="vertical" value="1" />
    </attr>
</declare-styleable>