Android Coil 3 extend ImageRequest's custom method/function,Kotlin
为Android Coil3图像加载库扩展自定义超时功能。通过创建MyCoilMgr类,使用companion object定义timeout扩展函数和属性,并实现TimeoutInterceptor拦截器来监控请求耗时。拦截器使用withTimeoutOrNull协程函数处理超时逻辑,记录请求耗时或超时情况。最后展示了使用方式:通过ImageRequest.Builder.timeout()设置超时时间,并用MyCoilMgr实例执行请求。该方案为Coil3提供了灵活的超时控制能力。
Kotlin
class MyCoilMgr {
companion object {
private val timeoutKey = Extras.Key(default = Long.MAX_VALUE)
fun ImageRequest.Builder.timeout(timeout: Long) = apply {
extras[timeoutKey] = timeout
}
val ImageRequest.timeout: Long
get() = getExtra(timeoutKey)
...
}
fun init(ctx: Context): ImageLoader {
//初始化加载器。
mImageLoader = ImageLoader.Builder(ctx)
...
.components {
add(TimeoutInterceptor())
}.build()
return mImageLoader
}
}
Kotlin
import android.util.Log
import coil3.intercept.Interceptor
import coil3.request.ImageResult
import com.ppdemo.coil.MyCoilMgr.Companion.timeout
import kotlinx.coroutines.withTimeoutOrNull
class TimeoutInterceptor : Interceptor {
companion object {
const val TAG = "fly/TimeoutInterceptor"
}
var startTime = 0L
var timeCost = 0L
lateinit var result: ImageResult
override suspend fun intercept(chain: Interceptor.Chain): ImageResult {
val timeout = chain.request.timeout
val exe = withTimeoutOrNull(timeout, {
startTime = System.currentTimeMillis()
result = chain.proceed()
timeCost = System.currentTimeMillis() - startTime
})
if (exe == null) {
Log.e(TAG, "timeout! $timeout ms , request=${chain.request.data}")
} else {
Log.d(TAG, "time cost = $timeCost ms , request=${chain.request.data}")
}
return result
}
}
so, we can use it in ImageRequest, for example:
Kotlin
val req = ImageRequest.Builder(this)
....
.timeout(1000)
.build()
MyCoilMgr.INSTANCE.enqueue(req)