Android图片库-Fresco

Fresco特征

Fresco出产于facebook公司,也可以发生facebook公司的Android框架的图片加载库都是使用的Fresco,比如ReactNative。Fresco很明显的特点就是类似于MVC的结构,DraweeView作为View层,是图片的真正渲染层,DraweeHierarchy负责组件维护最终的Drawable对象,相当于是M,而DraweeController则相当于Controller,负责图片的数据处理,默认实现是ImagePipeline,拥有两级内存缓存和一级磁盘缓存。

对比于另外两个图片加载库Picasso和Glide,Fresco的主要优点就是加载速度和缓存能力是最好的,而且兼容Android5.0以下,利用C++层解决OOM问题。Android系统解压后的图片使用Bitmap来保存,会占用大量内存(几Mb的图片很常见了,有些广告页长图几十Mb,别说这种情况少,有就是有,拿了东家的钱,就得解决所有问题),超大Bitmap一般在低端机上容易OOM。

而Fresco使用了Ashmem匿名共享内存来解决这个问题。Android的内存区又叫Java Heap,由Dalvik虚拟机管理,每new一个对象都会消耗虚拟机的内存,并且Java Heap内存由GC直接管理,能够自动内容回收。除了Java Heap,还有另一个叫作Native Heap,这个内存区由C/C++申请,不受App最大可用内存限制,而只受设备物理可用内存限制。总所周知,C/C++的内存需要手动释放,因此Native Heap中的内存,需要有手动释放,否则就会内存泄漏。

Android有一块特殊的内存区域叫Ashmem,类似于Native内存区,当系统内存不足时,会回收Ashmem区状态为unpin的对象内存块。Ashmem内存区一般应用是无法访问的,但将BitmapFactory.Options.inPurgeable设置为ture,就可创建一个Purgeable Bitmap,这样decode出来的Bitmap就在Ashmem内存中,Dalvik的GC就无法回收这些内存了。当decode这个Bitmap时,将这个Bitmap的内存给pin住,这样系统就不会回收,渲染结束时,调用unPin让系统回收,Fresco为了防止重新渲染导致在UI线程再decode而没有调用unPin,而是在Bitmap离开屏幕时才调用unPin,也就是在onDetachWindow的时候去unPin。

Picasso库的特点是使用起来特别简单,Picasso出产于square,因此和OkHttp和Retrofit结合使用更多方便,但Picasso默认不支持磁盘缓存,需要自己实现,或者是交给OkHttp去实现。Glide是支持了加载尺寸,加载失败的处理,也支持了磁盘缓存,但使用起来可能比较麻烦。

Fresco库的特点就是加载快,缓存更可控,并且加载逻辑与显示逻辑分离,可定制度高,但缺点也是使用较为麻烦,封装太多,而且要使用Fresco,就必须得使用Fresco提供的View而不能再使用ImageView了,因为Fresco的View层是使用的继承结构。这也是最要命的,使用了Fresco,就很难再切到其他图片库,就算要使用其他图片库,也使用其他图片库将Fresco的DraweeView再包一层,也就是使用其他图片库来实现Fresco的DraweeView的接口。


Fresco简单使用

class FrescoDemoActivity: AppCompatActivity() {
     

    companion object {
     
        const val FRESCO_IMAGE_CACHE = "fresco_image_cache"
        const val FRESCO_DISK_CACHE_SIZE = 1024 * 1024 * 500L

        const val IMAGE_URL = "https://ss3.bdstatic.com/70cFv8Sh_Q1YnxGkpoWK1HF6hhy/it/u=3361338045,2067021064&fm=26&gp=0.jpg"

        fun initFresco(context: Context) {
     
            val builder = ImagePipelineConfig.newBuilder(context)
                .setMainDiskCacheConfig(DiskCacheConfig.newBuilder(context)
                    .setBaseDirectoryPath(context.externalCacheDir)
                    .setBaseDirectoryName(FRESCO_IMAGE_CACHE)
                    .setMaxCacheSize(FRESCO_DISK_CACHE_SIZE)
                    .build()
                )
                .setBitmapMemoryCacheParamsSupplier {
     
                    val MAX_HEAP_SIZE = Runtime.getRuntime().maxMemory()
                    val MAX_MEMORY_CACHE_SIZE =
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值