如何使用Coil配合WebView实现图片缓存及返回WebResourceResponse
Coil实现WebView图片缓存并返回WebResourceResponse方案
核心结论
Coil完全支持WebView图片缓存,默认已启用内存+磁盘缓存,只需在shouldInterceptRequest中通过同步方式获取Coil的图片数据即可解决你的问题。
解决方案
由于Coil的execute是挂起函数,无法直接在shouldInterceptRequest这个同步方法中调用,我们可以用runBlocking包裹挂起调用,实现同步获取图片结果。同时优化ImageRequest配置,直接请求Bitmap以提升效率。
完整实现代码
override fun shouldInterceptRequest( view: WebView?, request: WebResourceRequest? ): WebResourceResponse? { try { val url = request?.url?.toString() ?: return super.shouldInterceptRequest(view, request) val imageType = when { url.lowercase().contains(".jpg") || url.lowercase().contains(".jpeg") -> "image/jpeg" to Bitmap.CompressFormat.JPEG url.lowercase().contains(".png") -> "image/png" to Bitmap.CompressFormat.PNG // 修正原代码中PNG类型错误 else -> return super.shouldInterceptRequest(view, request) } // 构建Coil的Bitmap请求,启用缓存 val imageRequest = ImageRequest.Builder(view?.context ?: requireContext()) .data(url) .memoryCachePolicy(CachePolicy.ENABLED) // 启用内存缓存 .diskCachePolicy(CachePolicy.ENABLED) // 启用磁盘缓存 .target { } // 空target,仅用于获取Bitmap .build() // 用runBlocking同步获取Bitmap val result = runBlocking { view?.context?.imageLoader?.execute(imageRequest) } val bitmap = result?.drawable?.toBitmap() ?: return super.shouldInterceptRequest(view, request) return WebResourceResponse( imageType.first, "UTF-8", getBitmapInputStream(bitmap, imageType.second) ) } catch (e: Exception) { e.printStackTrace() return super.shouldInterceptRequest(view, request) } } private fun getBitmapInputStream(bitmap: Bitmap, compressFormat: Bitmap.CompressFormat): InputStream { val byteArrayOutputStream = ByteArrayOutputStream() bitmap.compress(compressFormat, 80, byteArrayOutputStream) val bitmapData = byteArrayOutputStream.toByteArray() return ByteArrayInputStream(bitmapData) }
关键细节说明
- 同步获取结果:使用
runBlocking将挂起的execute调用转为同步执行,适配shouldInterceptRequest的同步要求。WebView的拦截请求本身在后台线程处理,不会阻塞UI主线程。 - 缓存配置:显式设置
memoryCachePolicy和diskCachePolicy为ENABLED,确保Coil优先读取缓存,和Glide的DiskCacheStrategy.ALL效果一致。 - 类型修正:原代码中PNG图片返回的MIME类型错误为
image/jpg,修正为image/png以符合标准。 - 异常处理:保留原有的异常捕获逻辑,确保请求失败时WebView能正常加载图片。
额外优化建议
- 可以给Coil的ImageRequest添加
size限制,比如设置为WebView的可见尺寸或Size.ORIGINAL,减少内存占用。 - 复用全局
ImageLoader实例,避免重复创建资源消耗。
内容的提问来源于stack exchange,提问作者Rakshit Nawani
相关产品推荐
相关产品推荐

