详解Android官推Kotlin-First的图片加载库

前言Coil 是一个非常年轻的图片加载库,在 2020 年 10 月 22 日才发布了 1.0.0 版本,但却受到了 Android 官方的推广,在 Android Developers Backstage 这个博客中专门聊过一期 。推广的原因比较简单:一方面是这个库确实做得很好,另一方面是这个库完全是用 Kotlin 写的,而且运用了大量 Kotlin 的特性,尤其是协程 。所以 google 嘴上说着不会放弃 JAVA,但实际上咱们都懂的 。

详解Android官推Kotlin-First的图片加载库

文章插图
 
Coil 名字的由来:取 Coroutine Image Loader 首字母得来,可以看出通过 Kotlin 协程来进行图片加载,特点如下:
  • 更快:Coil 在性能上有很多优化,包括内存缓存和磁盘缓存、把缩略图保存在内存中、通过 BitmAppool 循环利用 Bitmap、自动暂停和取消网络请求等
  • 更轻量级:Coil 只有 2000 个方法,跟 Picasso 的方法数差不多,相比 Glide 和 Fresco 要轻量非常多
  • 更容易使用:Coil 的 API 充分利用 Kotlin 的新特性,而且还有丰富的拓展函数,简化和减少了很多样板代码
  • 更流行:Coil 通过 Kotlin 来开发,并且使用包含 Coroutines、okhttp、okio 和 AndroidX Lifecycles 在内的非常多流行的开源库
从 Coil 的特性可以看出,这是一个非常适合个人 App 使用的图片加载库,特别是纯 Kotlin 开发的 App 。而且 Coil 里面运用了大量 Kotlin 的新特性以及协程,对于我们学习 Kotlin 有非常大的价值 。相比于 glide 和 fresco 有着非常复杂的结构和惊人的代码量,Coil 只有 2000 左右的方法数,所以也很适合进行源码研究和学习,
基本使用Coil 可以在 mavenCentral() 下载:
implementation("io.coil-kt:coil:1.1.1") Coil 给 ImageView 加了很多拓展函数,所以我们一行代码便能进行图片加载:
// URLimageView.load("https://www.example.com/image.jpg")// ResourceimageView.load(R.drawable.image)// FileimageView.load(File("/path/to/image.jpg"))同时我们也可以使用 lambda 语法轻松进行图片加载的配置:
imageView.load("https://www.example.com/image.jpg") {    crossfade(true)    placeholder(R.drawable.image)    transformations(CircleCropTransformation())}常用的 APIImageLoader
ImageLoader 是 Coil 中对于图片加载的大管家,负责处理缓存、数据获取、图像解码、请求管理、Bitmap 缓存池、内存管理等工作,一般建议只创建一个 ImageLoader 并在 App 中进行共享,这样性能是最优的 。这是因为每个 ImageLoader 都有自己的内存缓存和 Bitmap 缓存池 。
我们可以通过构造器来创建和配置 ImageLoader 。
val imageLoader = ImageLoader.Builder(context)    .availableMemoryPercentage(0.25)    .crossfade(true)    .build()同时由于 ImageLoader 是一个接口,也就意味着我们可以非常方便地进行测试,例如可以注入一个 fake 的 ImageLoader,从而每次都返回相同的 drawable 。
val fakeImageLoader = object : ImageLoader {    private val drawable = ColorDrawable(Color.BLACK)    override fun enqueue(request: ImageRequest): Disposable {        request.target?.onStart(drawable)        request.target?.onSuccess(drawable)        return disposable    }    override suspend fun execute(request: ImageRequest): ImageResult {        return SuccessResult(            drawable = drawable, request = request,            metadata = ImageResult.Metadata(                memoryCacheKey = MemoryCache.Key(""),                isSampled = false,                dataSource = DataSource.MEMORY_CACHE,                isPlaceholderMemoryCacheKeyPresent = false            )        )    }}


推荐阅读