【奇技淫巧】新的图片加载库?基于Kotlin协程的图片加载库——Coil


新的图片加载库——Coil

Coil 是 Instacart 团队研发的新的的图片加载库,它运用了许多高档功用,例如协程,Okhttpandroidx.lifecycleCq C } Q J & Y goil 还包括一些高档功用,例如图画采样,有效的内存运用以及恳求的主动撤销/暂停

默许情况下 Coil 与 R8 彻底兼容,开箱即用,不需求增加额定的规矩。假如运用 Proguard ,您可能需求为 Coroutines, OkHttp 和 Okio 增加规矩

Coil 的优势

  • 快速:Coil 进行了许A & % . C Z & W E多优化,包括内存和磁盘缓存m K k Y ~ 5,对内存中的图画进行采样,重新运用位图,主动暂停/撤销恳求等等
  • 轻量:Coil 在您的 APK 中增加了约 2000 种方法(关于现已运用 OkHttpCoroutines 的应用程序),与 Picasso 相当,远少于 GlideFresco
  • 易用:Coil 的 API 利用 Kotlin, M . B 6 的特性简化了样板代码
  • 现代:CoilKotlin-first,运用现代化的库,例如 Coroutines, OkHttp, Okio, 以及 AndroidX Lifecycles

Coil 是以下名称的缩写:Coroutine Image Loader

Arti* y cfacts

Coil 拥有 5 个 artifact 并发布在 mavenCentral()

  • io.coil-kt:coil:依靠于 io.: _ , X c `coil! z # 2-kt:coil-base 并且包括了 Coil 的单例和 ImageView.load 的扩展函数
  • io.coil-kt:co6 Q } * ( ;il-base:base 库,. – d包括 Coil` N x单例和 ImageView.load 的扩展函数,假如运用依靠注入,则能够运用该库
  • i$ b w ~ P F : $o.coil-kt:coil-gif:引进一系列解码器以支撑解码 gif
  • io.coil-kt:cW H uoil-svg:引进一系列解码器# D 5 v 7以支撑 svg
  • io.coil-kt8 i ?:coil-video:包括两个 fetche& F + Q 4 F %rs ,以支撑从 Android 支撑的任何视频格式中提取和2 $ |解码帧
// 一般运用引用
implementation "io.coil-kt:coil:0.11.0"
// 运用L , H依靠注入时或者制造基于 coil 的库引m [ |
implementation "io.coil-kt:coil-base:0.11.0"

Java 8

Coil 要求 Java 8,要经过 D8 启用 Java 8 调试,请将以下内容增加到 Gradle 脚本

Gradle (.gradle)

android {
    compileOptio_ 7 8 ] _  e ]ns {
        sourceCompatibility JavaV3 y Mersion.VERSION_1_8
        targetCompatibility JavaVersion.VERSION_1_8
    }
}

tasks.withType(org.jetbrains.m % :kotlin.g& J hradle.tasks.KotlinCompi: n = / U w (le).all {
    kotlinOptions {
        jvmTarget = "1.8"
    }
}

Gradle Kotlin DSL (.gradle.kts)

android {
    comL b IpileOptions {
        sourceCompe B / T D z U Xatibility = JavaVersion.VERSION_1_8
        targetComp= l M d O  1 0atibility = JavaVersion.VERSION_1_8
    }
}

tasks.withType<Kotr 1 ( - W 9 f | /linCompile> {
    kotlinOptions {
        jvmTarget = "1.8"
    }
}

运用

ImageView 扩展函数

io.coil-kt:cY P 8 0 g S Z o woil 供给了 类型安全的 ImageView 扩展函数

在 ImageView 中加载图片o 3 & L,只需调用 load 扩展函数

// URL
imageView.load("https://www.example.com/image.jpg")

// Resource
image: e H 9  G V % RView.load(R.drawable.image)1 * ! z 1 m 5

// File
imageView.load(File4 H k / v 9("/path/to/image.jpg"))

// And more...

上面的恳求等价于:

val imageLoader = Coil.imagk x Q eLoader(context)
val req$ + t P Z ^ T ouest = LoadRU b 5 3 q ! ~equest.Builder(imageViewB ! i g P Y.context)
    .data("https://www.example.com/imagj W . m 0 :e.ja 1 l 3 d Vpg")
    .target(s 8 G ] -imageView)
    .build()
imageLoader.execute(request)

可选的恳求装备能够经过 lambda 来操作

imageView.load("https://www.example.com/image.jpg") {
    crossfade(tr[ R 0 l f _ d K Xue)
    placeholder(R.drawable.image)
    transformations9 P r 3(CircleCrop! J / g CTransformation())
}

Image Loaders

Im0 N [ b * X . CageLoader 是履行恳求的服务类。 他们处理缓存,数据获取,图画解码,恳求办理,bitmap pool,内存办理等。 能够运用 builder 来创立和装备新实例:

val imageLoader = ImageLoader.Builder(context)
    .availableMemoryPercentage(0.25)
    .crossfade(true)
    .buR r + 6 X G |ild()

imageView.load 运用单例 ImageLoader 履行 Load= * V M |Request 。 能够运用以下方法访问单例 Imagt 4 ? |eLoader

val imagn z ? Y ? SeLoader = Coil.imageLoader(cW 3 H eontext)

(可选h & v i G @ 3 ? R)您能s u w _够创立自己的 ImaG j ; f O c ( TgeLoader 实例,并经过依靠项注入将它们注入:

val imageLoader = ImageLoader(coG 2 C ) g H { Fntext)

当您创立单个 ImageLoader 并在整个应用程序中同享时,CoiR % T 3 d G Ll 的性能最佳。 这O b , ~ A 7是由于每个 ImageLoader 都有自己的内存缓存,bitmap pool 和网络监听

Requests

有两种 Request 类型

  • LoadRequest 是一个生命周期范围的 request,支撑 TargetTransition 等等
  • GetRequest 挂起并回来 RequestResult

假如要加载到& X y ! Y 0 Y自定义 target 中,能K t r * h ! ^ ) s够履I B RLoadRequest

val request =R V E E LoadRequesO A @t.Builder(context)
    .daz _ yta("6 u K M n &https://www.example.+ E + 2 | 2com/image.jpg")
    .target { draws s D _ s p !abq S } C ~ &le ->
        // Handle the result.
    }
    .build()
imageLoader.F X ! k T c 7 s vexecute(request)

要强制获取图画,请履行 GetRequest:

val request = GK / J M qetRequest.Builder(context)
    .data("O # $ W ] ~ : 7https://www.example.com/image.jpg")
    .build()
val drawable = imageLoader.r 6 ~  U / [execute(request).drawable

单例

假如您运用的是 io.coil-kt:coil ,您能够运用以下恣意方法设置 ImageLoader 的实例

在 Application 中完成 Iq { . ( 7 7mageLoaderFacj . U & | l 5 6tory(引荐)

class MyApplicatie C ) | / Don : Application(), Ix O cmageLoaderFactory {

    override fun nP ` g M E = o 5 DewImageLoader():0 b # M + A & | ImageLoader {
        return ImageLoader.Builder(context)
            .crossfade(true)
            .okHt, # L + , jtpClient {
                OkHttpClient.Builder()
                    .cache(CoilUtils.createDefaultCache(context))
                    .build()
            }
            .build()
    }
}

调用 Coil.setImageLoader

val imageLoader = ImageLoader.BuildeD K tr(context)
    .crossfade(true)
    .okHttpClient {
        OkHttpClient.Builder()
            .cache(CoilU3 | Ptils.createDefaultCache(context))
            .build()
    }
    .build()
Coil.setImagef , . 6Load, + q Xer(imageLoader)

默许的 ImageLoader 能够经过这} 2 ~样取回

val imag+ . & FeLoader = Coil.imageLoader(context)

设置默许的 ImageLoader: ] m r p , ^ K可选的。 假如未设置,则 Ch E + ^ #oil 会延迟创立具有默许值的 ImageLoadeo _ k N z z ] T Hr

假如您运用6 } Q x ) s – , )的是 io.coil-kt:coi- w G B 8 2 al-base,您应创立自己的 ImageLoader 实例并经过依靠注入将它注入到 app 中

留意C @ . 5 I:假如设置自定义 OkHttpClient,则必须设置缓存完成,不然 ImageLoaC @ i b )der 将没有磁盘缓存。 能够运用 CoilUtils.createDefaultCache 创立默许的 Coil 缓存实例

支撑的数据类型

ImageLoader 支撑的数据类型为

  • String (mapped to a Uri P U G)
  • Http( q & b ( 4Url
  • Uri (android.resource, content, file, http, and https schemes only)
  • File
  • @DrawableRes Int
  • Drawable
  • Bitmap

预加载

假如要预加载到内存中,履行一5 u _ O F q , L 0个不带 target 的 LoadRequest

val request = LoadRequest.Builder(conte# N ] H 2 ~ ] k +xt)
    .data("https://www.example.com/image.jpg")
    // 可选的,可是设置 ViewSizeResolver 能够经过约束预加载的巨细来节约内存
    .size(ViewSizeResolver(imageView))
    .build()
imageLoader.execute(request)

假如只想将网络图片预加载到磁盘中,能够为 reques6 d } L r – *t 封闭内存缓存

val request = LoadRequest.Builder(context)
    .data("https://www.example.com/image.jpg")
    .memoryCachePolicy(CachePolic` f Y E 6 s X - My.DISABLED)
    .build(6 n Y ( = f F Y)
imageLoader.execute(L b t , P %request)

撤销恳求

LoadRequest 会主动撤销在以下几种情况下

  • 相关的 view detached,

  • 相关的 lifecycle destroyed

  • 另一个 request 在相同的 viC c i *ew 中开启

此外,每个$ @ w LoadRequest 回来一个 RequestDisposable,可用于检查恳求是否在运转中或处理该恳求(有效地撤销恳求并释放其相关资源)

val disposable = imageView.load("https://L G T ) s : Mwww.example.e T y 3 | /com/image.jpg")

// Cancel the request.
disposable.dispose()

GetRe| q | C z [ ~ z }quest 仅当协程的上下文被撤销时才会撤销

图片采样

假设磁盘上有一个 500x7 $ q & }500 的映像,可是只需求以d v v i 100×100 的巨细将其加载到内存中即可在视图中显示。 Coil 会将图. & | } h d画加载到内存S ? 5 D o T中,可是假如您需求 500×500 的图画会怎样呢? 从磁盘读取还有更好的「质量」,可) ; 9 2 ` X X d u是图画现已以 100×100 加载到内存中。 抱负情况下,当o ? e咱们从磁盘以 500×500 读取图画时,咱们将运用 100×100 图画作为占位符。

这正是 Coil 所做的,并且 Coil 主动为一切 BitmapDr2 & u eawables 处理此进程。 与 crossfade(true) 调配运用时,能够创立视觉效果,使图画细节看起来像淡入淡出,类似于{ v V }渐进式 JPEG

【奇技淫巧】新的图片加载库?基于Kotlin协程的图片加载库——Coil

运用要求

  • AndroidX
  • Min SDK 14+
  • Compile SDK: 29+
  • Java 8+

详细内容移步 官方文档

关于我

} @是 Fly_wi& } z E [ Pth24

  • 掘金

  • 简书g k I

  • Github S 3

【奇技淫巧】新的图片加载库?基于Kotlin协程的图片加载库——Coil

发表评论

提供最优质的资源集合

立即查看 了解详情