美文网首页Android开发Android开发经验谈Android技术知识
(三)Doodle - 精简的图片加载框架 - 用法篇

(三)Doodle - 精简的图片加载框架 - 用法篇

作者: 呼啸长风 | 来源:发表于2023-03-27 08:06 被阅读0次

本篇本系列的最后一篇,概述和原理见另外两篇文章:
(一)Doodle - 精简的图片加载框架 - 概述篇
(二)Doodle - 精简的图片加载框架 - 原理篇

一、下载

implementation 'io.github.billywei01:doodle:2.0.2'

二、Doodle (框架入口)

方法 描述
Config config() 返回全局配置。
Request load(String) 根据路径返回Request。
Request load(File) 根据文件返回Request。
Request load(int) 根据资源id返回Request。
Request load(Uri) 根据Uri返回Request。
File downloadOnly(String) 下载文件(不解码器)。注意不要在主线程调用此方法。
File getCacheFile(String) 获取缓存好的文件,没有则返回null。
void cacheBitmap(String,Bitmap,Boolean) 保存bitmap到缓存。
Bitmap getCacheBitmap(String): Bitmap? 从缓存中取bitmap, 无则返回null。
void pauseRequests() 暂停请求。
void resumeRequests() 恢复请求。
void notifyPause(Object) 发送pause事件。
void notifyResume(Object) 发送resume事件。
void notifyDestroy(Object) 发送destroy事件。
void trimMemory(int) 缩减内存缓存。
void clearMemory() 清除LruCache中的所有bitmap。

三、Config (全局配置)

全局配置的设置和Request类似,都是链式调用。

Doodle.config()
    .setLogger(Logger)
    .setExecutor(IOExecutor)
    .setHttpSourceFetcher(OkHttpSourceFetcher)
    .addDrawableDecoders(GifDecoder)

全局配置中的各个选项都是可选的(可以不设置)。

方法 描述
setExecutor(Executor executor) 设置Executor。
APP中如果每个组件都创建自己的线程池并且保持核心线程不销毁,那整个APP的存活线程就很多了,容易导致OOM。
故此,编写框架的时候,最好留一个接口给调用者传入Executor, 这样APP可以统一管理线程,框架可以复用APP的线程池。
当然,Doodle内部会套队列来控制任务的并发量,具体做法原理篇有讲述。
setLogger(DLogger logger) 设置Logger。通过Log可以观察一些运行情况,输出错误日志等。
setCachePath(String) 设置结果缓存的存储路径。如果不设定,会默认在内部目录的cache目录下创建子目录。
setResultMaxCount(int) 设置果缓存最大数量,默认8192。
setResultCapacity(long) 设置结果缓存的容量,默认128M。
setSourceMaxCount(int) 设置原图缓存最大数量,默认4096。
setSourceCapacity(long) 设置原图缓存容量,默认256M。
setMemoryCacheCapacity(long) 设置内存缓存的容量,默认为maxMemory的1/6。
setCompressFormat(Bitmap.CompressFormat) 设置结果缓存的压缩格式。
如果不设定默认压缩格式,Doodle会根据解码格式(RGB_8888/RGB_565),文件类型,以及系统版本决定用哪一种压缩格式。
setHttpSourceFetcher(HttpSourceFetcher) Doodle内置了下载http文件的代码,用SDK自带的HttpURLConnection实现。
如果需要用自己的下载方法,实现HttpSourceFetcher并调此方法注入即可。
addDataParser(DataParser) 添加DataParser,用于自定义数据获取。
addDrawableDecoders(DrawableDecoder) 添加自定义DrawableDecoder。
addBitmapDecoders(BitmapDecoder) 添加自定义BitmapDecoder。

全局配置中的HttpSourceFetcher和自定义解码,这里展开讲一下:

  • HttpSourceFetcher
    HttpSourceFetcher的定义很简单,传入url, 返回InputStream,如果请求失败,抛IOException。
public interface HttpSourceFetcher {
    InputStream getInputStream(String url) throws IOException;
}

需要指出的是,Doodle自己实现了磁盘缓存(包括网络文件缓存),如果使用OkHttp实现下载HttpSourceFetcher,
建议在请求的地方调用:

cacheControl(CacheControl.Builder().noStore().noCache().build())

以免缓存两份原文件。

  • 自定义解码
    Doodle提供了两个自定义解码接口:
public Config addDrawableDecoders(DrawableDecoder decoder)
public Config addBitmapDecoders(BitmapDecoder decoder)

接口比较简单,传入解码信息(包括数据源信息以及目标解码参数,具体可参考源码),返回结果。
例如,DrawableDecoder定义如下:

public interface DrawableDecoder {
    Drawable decode(DecodingInfo info);
}

如果需要支持解码GIF, 可以引入android-gif-drawable,实现DrawableDecoder接口。

import pl.droidsonroids.gif.GifDrawable

object GifDecoder : DrawableDecoder {
    override fun decode(info: DecodingInfo): Drawable? {
        if (info.mediaType != MediaType.GIF) {
            return null
        }
        val gifDrawable = GifDrawable(info.data)
        // 如果GIF文件只有一帧,可以返回BitmapDrawable, Doodle会提取bitmap并缓存,那样下次加载就可以直接读缓存了。
        if (gifDrawable.numberOfFrames == 1) {
            return BitmapDrawable(AppConfig.appContext.resources, gifDrawable.currentFrame)
        }
        return gifDrawable
    }
}

然后在APP初始化时注册:

fun initApplication(context: Application) {
      Doodle.config().addDrawableDecoders(GifDecoder)
}

注册了Gif解码器后,常规调用即可:如果图片源是GIF动图,会解码得到GifDrawable。

Doodle.load(path).into(imageView)

当然也可以指定不需要显示动图, 调用asBitmap方法即可。

四、Request (加载请求)

Doodle加载图片的API和Picasso/Glide相似。

基本用法,加载图片到ImageView:

Doodle.load(path).into(imageView)

或者,如果target不是ImageView, 可以通过接口回调result,在将结果应用到所需要的target。
Doodle的result目前只有三种情况,Bitmap,Drawable或者null。

Doodle.load(path).into(result -> {
    if (result instanceof Bitmap) {
        // handle bitmap
    } else if (result instanceof Drawable) {
        // handle drawable
    } else { 
        // handle null
    }
});

或者直接获取bitmap:

Bitmap bitmap = Doodle.load(path).get()

或者仅预加载:

Doodle.load(path).preload()

Doodle加载图片,从load()方法开始,到into(), get() 或者 preload()方法结束。
在into()/get()/preload()之前,可以添加更多的参数。

方法 描述
sourceKey(String) 设置数据源的key。
path默认情况下作为CacheKey的一部分,有时候path有动态的参数,使得path频繁变化,从而无法缓存。
此时可以取不变的部设置为sourceKey,替换path作为CacheKey的一部分。
override(int, int) 指定目标尺寸。
scaleType(ImageView.ScaleType) 指定缩放类型。
如果未设定,且target为ImageView,则会自动从ImageView获取。
clipType(ClipType) ClipType 是自定义缩放类型枚举,大部分和ScaleType重叠,有少量增删。
enableUpscale() 默认情况下,解码图片文件基于降采样的方式。
例如:
目标宽高是200x200,目标scaleType='centerCrop'。
1、文件分辨率是400x400,最终会解码出200x200的bitmap;
2、文件分辨率是100x100,最终会解码出100x100的bitmap。
第2种情况,由于源文件本身的分辨率只有100x100, 当ImageView的scaleType是centerCrop时,正常解码100x100和上采样成200x200的显示结果是一样的,后者并不会比前者清晰。
但有的情况就是要不管源文件分辨率,要求最终解码出的bitmap是目标宽高,这时候可以调用此方法。
memoryCacheStrategy(MemoryCacheStrategy) 设置内存缓存策略,默认LRU策略。
diskCacheStrategy(DiskCacheStrategy) 设置磁盘缓存策略,默认ALL。
noCache() 不做任何缓存,包括磁盘缓存和内存缓存。
onlyIfCached(boolean) 指定网络请求是否只从缓存读取(原图缓存)。
decodeFormat(DecodeFormat) 设置解码格式,默认ARGB_8888。
transform(Transformation) 设置解码后的图片变换(圆形剪裁,圆角,灰度,模糊等),可以连续调用(会按顺序执行)。
Doodle内置了圆形剪裁和圆角两种Transfromation。
keepOriginalDrawable() 默认情况下请求开始会先清空ImageView之前的Drawable, 调用此方法后会保留之前的Drawable,直到加载结束。
placeholder(int) 设置占位图,在结果加载完成之前会显示此drawable。
placeholder(Drawable) 同上。
error(int) 设置加载失败后的占位图。
error(Drawable) 同上。
animation(int) 设置加载成功后的过渡动画。
animation(Animation) 同上。
fadeIn(int) 加载成功后显示淡入动画。
crossFade(int) 这个动画效果是“原图”从透明度100到0, bitmap从0到100。
当设置placeholder时,placeholder为“原图”。
如果没有设置placeholder, 效果和fadeIn差不多。
需要注意的是,这个动画在原图和bitmap宽高不相等时,动画结束时图片会变形。
因此,慎用crossFade。
alwaysAnimation(Boolean) 默认情况下仅在图片是从磁盘或者网络加载出来时才做动画,可通过此方法设置总是做动画。
asBitmap() 当设置了GIF Decoder时,默认情况下只要图片是GIF图片,则用GIF Decoder解码。
调用此方法后,不走GIF解码器,直接用BitmapFactory解码,并返回bitmap。
observeHost(Object) 传入宿主(Activity/Fragment/View), 以观察其生命周期。
addOption(String, String) options目前有两个作用:
1. 传递参数给自定义Decoder;
2. 参与计算CacheKey, 以区分不同请求。
setBitmapDecoder(BitmapDecoder) 添加针对单个请求的BitmapDecoder。
此Decoder仅作用于当前Request, 并且会优先于其他自定义Decoder。
enableThumbnailDecoder() 这个选项是用于加速相册缩略图显示的,只对相册媒体(路径开头为"content://media/external/")有效。
相册中的媒体文件通常伴有生成好的缩略图文件,读取缩略图文件要比读取原文件要快很多。
缩率图文件分辨率较低,用于自定义相册的列表显示足够了。
开启此选项,会优先尝试读取缩略图,如果读取不到则访问原文件。
此选项仅作用于当前Request。
listen(CompleteListener) 监听加载任务结束时有没有取到结果(bitmap/drawable)。

相关文章

网友评论

    本文标题:(三)Doodle - 精简的图片加载框架 - 用法篇

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