图片加载框架

来源:互联网 发布:小米网络电视安装 编辑:程序博客网 时间:2024/06/05 01:01

ImageLoagder的设计原理

ImageLoagder的目的是为了实现异步网络图片的加载,缓存及显示,支持多线程异步加载

​ ImageLogder的工作原理是:在显示图片的时候,它会现在内存中查找,如果没有,就去本地查找;本地还没找到,就开一个新的线程去下载这张图片,下载成功后会把图片同时缓存到内存和本地

​ 基于这个原理,我们可以在每次退出一个Activity的时候,把ImageLoagder内存中的缓存全部清楚,这样就节省了大量内存,反正下次再用到的时候在本地提取就好啦

​ 此外,有序ImageLoader对图片是软引用(↓)的形式,所以内存中的图片会在内存不足的时候被系统回收(内存足够的时候不会对其进行垃圾回收).

拓展:1.SoftReference<T>:软引用-->当虚拟机内存不足时,将会回收他指定的对象,需要获取对象时,可以调用get方法

​ 2.WeakReference<T>:弱引用-->随时可能会被垃圾回收器回收,不一定要等到内存不足的时候才强制回收,要获取对象的时候,同样可以调用方法

​ 3.WeakReference一般用来防止内存泄漏,要保证内存被虚拟机回收,SoftReference多用来实现缓存机制(cashe);

ImageLoagder的使用

ImageLoader由三大组件组成:

​ 1.ImageLoaderConfiguration---对图片缓存进行总体配置,包括内存缓存的大小,本地缓存的大小和位置,日志,下载策略等到

​ 2.ImageLoader---我们一般使用displayImage来把URL对应的图片显示在ImageView上

​ 3.DisplayImageOptions---在每个页面需要显示图片的地方,控制如何显示的细节,比如指定下载时的默认图(包括下载中.下载失败.URL为空等),是否存放在内存或者本地磁盘.

Frescohttps://www.fresco-cn.org/

Fresco是一个强大的图片加载组件.使用它做图片加载,就不需要再关心图片的加载和显示这些繁琐的事情.支持版本Android2.3及以后的版本

Image Pipeline

Frescr中有一个Image Pipeline的模板.它负责从网络,从本地系统文件,本地资源加载图片.为了最大限度的节省空间和CPU的时间,它含有三级缓存(二级缓存,一级磁盘)

Drawees

Fresco中设计有一个叫做Drawees的模板,他会在图片加载前显示占位图,加载成功后自动替换成目标图片,当图片不在显示在屏幕上时,它会及时释放内存和空间的占用

Fresco的特性

内存管理

解压后的图片,即Android中的Bitmap,占用大量的内存。大的内存占用势必引发更加频繁的GC。在5.0以下,GC将会显著地引发界面卡顿。

在5.0以下系统,Fresco将图片放到一个特别的内存区域。当然,在图片不显示的时候,占用的内存会自动被释放。这会使得APP更加流畅,减少因图片内存占用而引发的OOM。

Fresco 在低端机器上表现一样出色,你再也不用因图片内存占用而思前想后。

图片加载

Fresco的Image Pipeline允许你用很多种方式来自定义图片加载过程,比如:

  • 为同一个图片指定不同的远程路径,或者使用已经存在本地缓存中的图片

  • 先显示一个低清晰度的图片,等高清图下载完之后再显示高清图

  • 加载完成回调通知

  • 对于本地图,如有EXIF缩略图,在大图加载完成之前,可先显示缩略图

  • 缩放或者旋转图片

  • 对已下载的图片再次处理

  • 支持WebP解码,即使在早先对WebP支持不完善的Android系统上也能正常使用!

    图片绘制

    Fresco 的 Drawees 设计,带来一些有用的特性:

    • 自定义居中焦点

    • 圆角图,当然圆圈也行

    • 下载失败之后,点击重现下载

    • 自定义占位图,自定义overlay, 或者进度条

    • 指定用户按压时的overlay

      图片的渐进式呈现

​ 渐进式的JPEG图片格式已经流行数年了,渐进式图片格式先呈现大致的图片轮廓,然后随着图片下载的继续,呈现逐渐清晰的图片,这对于移动设备,尤其是慢网络有极大的利好,可带来更好的用户体验。

Android 本身的图片库不支持此格式,但是Fresco支持。使用时,和往常一样,仅仅需要提供一个图片的URI即可,剩下的事情,Fresco会处理

开始使用Fresco

首先在项目中引入Fresco

编辑build.gradle文件:

dependencies {  // 其他依赖  compile 'com.facebook.fresco:fresco:0.12.0'}

下面的依赖需要根据需求添加:

dependencies {  // 在 API < 14 上的机器支持 WebP 时,需要添加  compile 'com.facebook.fresco:animated-base-support:0.12.0'  // 支持 GIF 动图,需要添加  compile 'com.facebook.fresco:animated-gif:0.12.0'  // 支持 WebP (静态图+动图),需要添加  compile 'com.facebook.fresco:animated-webp:0.12.0'  compile 'com.facebook.fresco:webpsupport:0.12.0'  // 仅支持 WebP 静态图,需要添加  compile 'com.facebook.fresco:webpsupport:0.12.0'}

依赖后异步加载等待过后就可以开始使用Fresco了

如果你仅仅是想简单下载一张网络图片,在下载完成之前,显示一张占位图,那么简单使用SimpleDraweeView 即可.

在加载图片之前,你必须初始化Fresco类。你只需要调用Fresco.initialize一次即可完成初始化,在Application 里面做这件事再适合不过了(如下面的代码),注意多次的调用初始化是无意义的。

[MyApplication.java]public class MyApplication extends Application {    @Override    public void onCreate() {        super.onCreate();        Fresco.initialize(this);    }}

做完上面的工作后,你需要在AndroidManifest.xml 中指定你的 Application 类。为了下载网络图片,请确认你声明了网络请求的权限。

<manifest    ...    >    <uses-permission android:name="android.permission.INTERNET" />    <application      ...      android:label="@string/app_name"      android:name=".MyApplication"      >      ...    </application>    ...  </manifest>

在xml布局文件中, 加入命名空间:

<!-- 其他元素--><LinearLayout    xmlns:android="http://schemas.android.com/apk/res/android"    xmlns:fresco="http://schemas.android.com/apk/res-auto"    android:layout_height="match_parent"    android:layout_width="match_parent">

加入SimpleDraweeView:

<com.facebook.drawee.view.SimpleDraweeView    android:id="@+id/my_image_view"    android:layout_width="130dp"    android:layout_height="130dp"    fresco:placeholderImage="@drawable/my_drawable"  />

开始加载图片:

Uri uri = Uri.parse("https://raw.githubusercontent.com/facebook/fresco/gh-pages/static/logo.png");SimpleDraweeView draweeView = (SimpleDraweeView) findViewById(R.id.my_image_view);draweeView.setImageURI(uri);

剩下的,Fresco会替你完成:

  • 显示占位图直到加载完成;

  • 下载图片;

  • 缓存图片;

  • 图片不再显示时,从内存中移除;

等等等等。

原创粉丝点击