Android圖片加載框架庫源碼解析 - Coil

一祟偷、什么是Coil

Coil是一個Android開源的圖片加載庫,使用Kotlin協(xié)程來加載圖片,Coil在 2020 年 10 月 22 日才發(fā)布了 1.0.0 版本岂膳,但卻受到了 Android官方的推廣,Coil有以下幾個特點(diǎn):

  • 更快:Coil在性能上做了很多優(yōu)化磅网,包括內(nèi)存緩存和磁盤緩存谈截、對內(nèi)存中的圖片進(jìn)行采樣、復(fù)用Bitmap涧偷、支持根據(jù)生命周期變化自動暫停和取消圖片請求等
  • 更輕量級: Coil大約會給你的App增加兩千個方法(前提是你的 App 已經(jīng)集成了OkHttp和Coroutines)簸喂,Coil的方法數(shù)和Picasso相當(dāng),相比Glide和Fresco要輕量級很多
  • 更容易使用:Coil’s API 充分利用了Kotlin語言的新特性燎潮,簡化并減少了很多重復(fù)代碼
  • 更流行:Coil首選Kotlin語言開發(fā)喻鳄,并且使用包含 Coroutines、OkHttp确封、Okio 和 AndroidX Lifecycles 在內(nèi)的更現(xiàn)代化的開源庫
    Coil的首字母由來:Coroutine除呵,Image 和Loader 得到 Coil
    Coil開源庫github地址:https://github.com/coil-kt/coil
    Coil官方文檔:https://coil-kt.github.io/coil

二、引入Coil

Coil要求AndroidX與Java 8+環(huán)境
app/build.gradle 中添加Coil依賴包

implementation("io.coil-kt:coil:1.2.1")

AndroidManifest.xml 中加上網(wǎng)絡(luò)權(quán)限

<uses-permission android:name="android.permission.INTERNET" />

1爪喘、ImageView加載圖片

在activity_main.xml中聲明ImageView颜曾,并使用Coil為ImageView加載圖片:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context=".MainActivity">

    <ImageView
        android:id="@+id/imageView"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_margin="16dp" />

    <Button
        android:id="@+id/button"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_margin="16dp"
        android:text="點(diǎn)擊" />
</LinearLayout>

1.1、普通加載

 val url = "https://img-blog.csdnimg.cn/20210124002108308.png"
    ......
        button.setOnClickListener {
            imageView.load(url)
        }
  • 通過擴(kuò)展方法load加載url
  • 除了String以外秉剑,還支持HttpUrl 泛豪、Url、 File秃症、 DrawableRes Int 候址、Drawable、 Bitmap等各種類型的加載
    舉例子:
// Resource
imageView.load(R.drawable.image)

// File
imageView.load(File("/path/to/image.jpg"))

1.2种柑、crossfade(淡入淡出)加載

  val url = "https://img-blog.csdnimg.cn/20210124002108308.png"
    ......
        reloadButton.setOnClickListener {
            imageView.load(url) {
                crossfade(true)
            }
        }

1.3岗仑、crossfade的動畫時間

 val url = "https://img-blog.csdnimg.cn/20210124002108308.png"
    ......
        reloadButton.setOnClickListener {
            imageView.load(url) {
                crossfade(3000)
            }
        }

1.4、placeholder
placeholder預(yù)置展位圖

 val url = "https://img-blog.csdnimg.cn/20210124002108308.png"
    ......
        button.setOnClickListener {
            imageView.load(url) {
                placeholder(R.drawable.placeholder)
                crossfade(3000)
            }
        }

1.5聚请、error
加載失敗時的錯誤占位圖片

  val url = "https://notfound.png"
    ......
        button.setOnClickListener {
            imageView.load(url) {
                error(R.drawable.error)
            }
        }

1.6荠雕、高斯模糊
BlurTransformation:高斯模糊變換
activity_main.xml代碼中把ImageView的高度設(shè)置成300dp

 val url = "https://img-blog.csdnimg.cn/20210124002108308.png"
    ......
        button.setOnClickListener {
            imageView.load(url) {
                transformations(BlurTransformation(context = applicationContext, radius = 5f, sampling = 5f))
            }
        }

1.7、灰度變換
GrayscaleTransformation:灰度變換

 val url = "https://img-blog.csdnimg.cn/20210124002108308.png"
    ......
        button.setOnClickListener {
            imageView.load(url) {
                transformations(GrayscaleTransformation())
            }
        }

1.8驶赏、圓形
CircleCropTransformation:圓形變換

val url = "https://img-blog.csdnimg.cn/20210124002108308.png"
    ......
        button.setOnClickListener {
            imageView.load(url) {
                transformations(CircleCropTransformation())
            }
        }

1.9炸卑、圓角
RoundedCornersTransformation:圓角矩形變換

 val url = "https://img-blog.csdnimg.cn/20210124002108308.png"
    ......
        button.setOnClickListener {
            imageView.load(url) {
                transformations(
                    RoundedCornersTransformation(
                        topLeft = 10f,
                        topRight = 10f,
                        bottomLeft = 10f,
                        bottomRight = 10f
                    )
                )
            }
        }

上面左右可以設(shè)置圓角:topLeft = 10f,topRight = 10f,bottomLeft = 0f,bottomRight = 0f



下面左右可以設(shè)置圓角:topLeft = 0f,topRight = 0f,bottomLeft = 10f,bottomRight = 10f


2、Gif加載

添加依賴包:

implementation("io.coil-kt:coil-gif:1.4.0")

官方文檔:https://coil-kt.github.io/coil/gifs/
創(chuàng)建 gif ImageLoader 實(shí)例

 private val gifUrl = "https://img.zcool.cn/community/01ca905aebe350a801219b7f53a0e4.gif"
    ......
        button.setOnClickListener {

            val imageLoader = ImageLoader.Builder(this)
                .componentRegistry {
                    if (SDK_INT >= 28) {
                        add(ImageDecoderDecoder())
                    } else {
                        add(GifDecoder())
                    }
                }
                .build()

            //設(shè)置全局唯一實(shí)例
            Coil.setImageLoader(imageLoader)

            imageView.load(gifUrl) //加載gif圖片
        }
    }

3煤傍、視頻幀加載

implementation("io.coil-kt:coil-video:1.2.2")//支持Video
private val videoUrl = "https://vd4.bdstatic.com/mda-jbppbefbbztvws50/sc/mda-jbppbefbbztvws50.mp4"
    ......
        button.setOnClickListener {

            //創(chuàng)建 gif ImageLoader 實(shí)例
            val imageLoader = ImageLoader.Builder(applicationContext)
                .componentRegistry {
                    add(VideoFrameDecoder(this@MainActivity))
                }.build()

            //設(shè)置全局唯一實(shí)例
            Coil.setImageLoader(imageLoader)

            imageView.load(videoUrl)
        }
    }

5盖文、監(jiān)聽下載過程

 private val imageUrl = "https://img-blog.csdnimg.cn/20210124002108308.png"
    ......
        button.setOnClickListener {
            imageView.load(imageUrl) {
                listener(
                    onStart = { request ->
                        Log.d("coil-", "onStart")
                    },
                    onError = { request, throwable ->
                        Log.d("coil-", "onError")
                    },
                    onCancel = { request ->
                        Log.d("coil-", "onCancel")
                    },
                    onSuccess = { request, metadata ->
                        Log.d("coil-", "onSuccess")
                    }
                )
            }
        }

6、取消下載

private val imageUrl = "https://img-blog.csdnimg.cn/20210124002108308.png"
    ......
        button.setOnClickListener {
            val disposable = imageView.load(imageUrl)
            //取消加載
            disposable.dispose()
        }
f3d98b1c429f4968bffd8f9dc6d22ef2.png

7蚯姆、替換 okhttp 實(shí)例

coil底層是使用okhttp作為網(wǎng)絡(luò)請求工具五续,可以設(shè)置okHttpClient實(shí)例

private val imageUrl = "https://img-blog.csdnimg.cn/20210124002108308.png"
    ......
        button.setOnClickListener {

            val okHttpClient = OkHttpClient.Builder()
                .cache(CoilUtils.createDefaultCache(this))
                .build()

            val imageLoader = ImageLoader.Builder(this).okHttpClient {
                okHttpClient
            }.build()

            Coil.setImageLoader(imageLoader)

            imageView.load(imageUrl)
        }

8洒敏、自定義

 private val imageUrl = "https://img-blog.csdnimg.cn/20210124002108308.png"
    ......
        button.setOnClickListener {

            val okHttpClient = OkHttpClient.Builder()
                .cache(CoilUtils.createDefaultCache(this))
                .build()

            val imageLoader = ImageLoader.Builder(this)
                .availableMemoryPercentage(0.2)
                .diskCachePolicy(CachePolicy.ENABLED) //磁盤緩策略 ENABLED、READ_ONLY疙驾、WRITE_ONLY凶伙、DISABLED
                .crossfade(true) //淡入淡出
                .crossfade(1000) //淡入淡出時間
                .okHttpClient { //設(shè)置okhttpClient實(shí)例
                    okHttpClient
                }.build()

            Coil.setImageLoader(imageLoader)
            imageView.load(imageUrl)

        }

轉(zhuǎn)載:https://blog.csdn.net/qq_35091074/article/details/134089606

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市它碎,隨后出現(xiàn)的幾起案子函荣,更是在濱河造成了極大的恐慌,老刑警劉巖扳肛,帶你破解...
    沈念sama閱讀 219,188評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件傻挂,死亡現(xiàn)場離奇詭異,居然都是意外死亡敞峭,警方通過查閱死者的電腦和手機(jī)踊谋,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,464評論 3 395
  • 文/潘曉璐 我一進(jìn)店門蝉仇,熙熙樓的掌柜王于貴愁眉苦臉地迎上來旋讹,“玉大人,你說我怎么就攤上這事轿衔〕良#” “怎么了?”我有些...
    開封第一講書人閱讀 165,562評論 0 356
  • 文/不壞的土叔 我叫張陵害驹,是天一觀的道長鞭呕。 經(jīng)常有香客問我,道長宛官,這世上最難降的妖魔是什么葫松? 我笑而不...
    開封第一講書人閱讀 58,893評論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮底洗,結(jié)果婚禮上腋么,老公的妹妹穿的比我還像新娘。我一直安慰自己亥揖,他們只是感情好珊擂,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,917評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著费变,像睡著了一般摧扇。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上挚歧,一...
    開封第一講書人閱讀 51,708評論 1 305
  • 那天扛稽,我揣著相機(jī)與錄音,去河邊找鬼滑负。 笑死在张,一個胖子當(dāng)著我的面吹牛锡搜,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播瞧掺,決...
    沈念sama閱讀 40,430評論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼耕餐,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了辟狈?” 一聲冷哼從身側(cè)響起肠缔,我...
    開封第一講書人閱讀 39,342評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎哼转,沒想到半個月后明未,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,801評論 1 317
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡壹蔓,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,976評論 3 337
  • 正文 我和宋清朗相戀三年趟妥,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片佣蓉。...
    茶點(diǎn)故事閱讀 40,115評論 1 351
  • 序言:一個原本活蹦亂跳的男人離奇死亡披摄,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出勇凭,到底是詐尸還是另有隱情疚膊,我是刑警寧澤,帶...
    沈念sama閱讀 35,804評論 5 346
  • 正文 年R本政府宣布虾标,位于F島的核電站寓盗,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏璧函。R本人自食惡果不足惜傀蚌,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,458評論 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望蘸吓。 院中可真熱鬧善炫,春花似錦、人聲如沸美澳。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,008評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽制跟。三九已至舅桩,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間雨膨,已是汗流浹背擂涛。 一陣腳步聲響...
    開封第一講書人閱讀 33,135評論 1 272
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人撒妈。 一個月前我還...
    沈念sama閱讀 48,365評論 3 373
  • 正文 我出身青樓恢暖,卻偏偏與公主長得像,于是被迫代替她去往敵國和親狰右。 傳聞我的和親對象是個殘疾皇子杰捂,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,055評論 2 355

推薦閱讀更多精彩內(nèi)容