Glide 图片加载进度 kotlin

Glide 加载图片进度 kotlin 中的玩法

前言

之前 在简书上分享过一个 Glide 加载 图片进度的文章 Android - 图片处理之Glide加载进度,年代久远,当时用的是java 想现在改成了 使用kotlin 方式

内部的原理还是 之前 郭嫂的 Glide 系列 博客

Android图片加载框架最全解析(一),Glide的基本用法
Android图片加载框架最全解析(二),从源码的角度理解Glide的执行流程
Android图片加载框架最全解析(三),深入探究Glide的缓存机制
Android图片加载框架最全解析(四),玩转Glide的回调与监听
Android图片加载框架最全解析(五),Glide强大的图片变换功能
Android图片加载框架最全解析(六),探究Glide的自定义模块功能
Android图片加载框架最全解析(七),实现带进度的Glide图片加载功能
Android图片加载框架最全解析(八),带你全面了解Glide 4的用法

详情

安装依赖

1
2
3
kapt 'com.github.bumptech.glide:glide:4.11.0'
kapt 'com.github.bumptech.glide:compiler:4.11.0'
implementation "com.github.bumptech.glide:okhttp3-integration:4.11.0"

安装 plugin

1
apply plugin: 'kotlin-kapt'

ProgressResponseBody

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50


import com.starot.wechat.glide.impl.ProgressListener
import com.starot.wechat.glide.interceptor.ProgressInterceptor
import okhttp3.MediaType
import okhttp3.ResponseBody
import okio.*


class ProgressResponseBody(
url: String,
private var responseBody: ResponseBody
) : ResponseBody() {

private var listener: ProgressListener? = ProgressInterceptor.map[url]

override fun contentLength(): Long {
return responseBody.contentLength()
}

override fun contentType(): MediaType? {
return responseBody.contentType()
}

override fun source(): BufferedSource {
return Okio.buffer(ProgressSource(responseBody.source()))
}

inner class ProgressSource(source: Source) : ForwardingSource(source) {

private var totalBytesRead: Long = 0

private var currentProgress = 0
override fun read(sink: Buffer, byteCount: Long): Long {
val bytesRead = super.read(sink, byteCount)
val fullLength = responseBody.contentLength()
if (bytesRead == -1L) {
totalBytesRead = fullLength;
} else {
totalBytesRead += bytesRead;
}
val progress = (100f * totalBytesRead / fullLength).toInt()
if (progress != currentProgress) {
listener?.onProgress(progress)
}
currentProgress = progress;
return bytesRead
}
}
}

ProgressInterceptor

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
object ProgressInterceptor : Interceptor {
override fun intercept(chain: Interceptor.Chain): Response {
val request: Request = chain.request()
val response = chain.proceed(request)
val url: String = request.url().toString()
val body = response.body()
return response.newBuilder().body(body?.let {
ProgressResponseBody(
url,
it
)
}).build()
}

val map = ConcurrentHashMap<String, ProgressListener>()

//入注册下载监听
fun addListener(url: String, listener: ProgressListener) {
map[url] = listener
}

//取消注册下载监听
fun removeListener(url: String?) {
map.remove(url)
}
}

ProgressListener

1
2
3
interface ProgressListener {
fun onProgress(progress: Int)
}

MyGlideModule

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20

@GlideModule
class MyGlideModule : AppGlideModule() {
override fun registerComponents(
context: Context,
glide: Glide,
registry: Registry
) {
//添加拦截器到Glide
val builder = OkHttpClient.Builder()
builder.addInterceptor(ProgressInterceptor)
val okHttpClient = builder.build()

registry.replace(
GlideUrl::class.java,
InputStream::class.java,
OkHttpUrlLoader.Factory(okHttpClient)
)
}
}

使用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
ProgressInterceptor.addListener(data, object : ProgressListener {
override fun onProgress(progress: Int) {
Log.i(TAG, "图片加载进度 $progress")
}
})
val options = RequestOptions()
.skipMemoryCache(true)
.diskCacheStrategy(DiskCacheStrategy.NONE)


Glide.with(this)
.load(data)
.apply(options)
.listener(object : RequestListener<Drawable> {
override fun onLoadFailed(
e: GlideException?,
model: Any?,
target: Target<Drawable>?,
isFirstResource: Boolean
): Boolean {
Log.i(TAG, "图片加载失败")
return false
}

override fun onResourceReady(
resource: Drawable?,
model: Any?,
target: Target<Drawable>?,
dataSource: DataSource?,
isFirstResource: Boolean
): Boolean {
Log.i(TAG, "图片加载成功")
return false
}
})
.into(photoView)

demo

https://github.com/JiangHaiYang01/WeChatPhoto