首页 > 解决方案 > 如何检索加载到 SimpleDraweeView - Android 的图像/Gif 文件

问题描述

所以基本上我想访问加载到SimpleDraweeView. 当 Fresco 从 url 下载图像时,我想将该图像保存在我的数据库中以供将来访问(以帮助减少数据使用),因为这些图像不会更改。这样,下次我想将图像加载到SimpleDraweeView我加载本地媒体时,无需再次从 url 下载它。

Fresco.newDraweeControllerBuilder在将侦听器添加到我所在的位置后,我尝试了几种方法onFinalImageSet

1-尝试File从 Fresco 使用的缓存中访问图像/gif 以获取它的 ByteArray,但是,我总是hasKey() = FalseImagePipelineFactory

val imageRequest = ImageRequest.fromUri(mediaUrl)
val cacheKey = DefaultCacheKeyFactory.getInstance().getEncodedCacheKey(imageRequest, null)
if(ImagePipelineFactory.getInstance().mainFileCache.hasKey(cacheKey)) {
    val resource = ImagePipelineFactory.getInstance().mainFileCache.getResource(cacheKey) 
    val file = (resource as FileBinaryResource).file
}else if (ImagePipelineFactory.getInstance().smallImageFileCache.hasKey(cacheKey)){
    val resource = ImagePipelineFactory.getInstance().mainFileCache.getResource(cacheKey) 
    val file = (resource as FileBinaryResource).file
}

2-尝试从imageInfo(as a CloseableStaticBitmap) 或animatable(as a CloseableAnimateImage) 获取位图,但是如果我想将可动画转换为该位图,则会CloseableAnimateImage收到编译错误“未解析的引用:CloseableAnimateImage”。然后的想法是从位图中获取 ByteArray 并保存它。尽管如此,我真的很想得到(1)的方法。

关于如何获取缓存文件的任何想法?先感谢您!

标签: androidfilefresco

解决方案


最后,直到有人能回答如何做到这一点,SimpleDraweeView我决定同时选择 Glide。Picasso 不是一个选项,因为它不支持 gif,这是我的问题中的要求之一。此外,我想继续显示加载的图像,ImageView因此我不想将其更改into为自定义目标。

因此,使用 Glide 的解决方案如下:

首先,我们尝试通过tryToGetFromMyDatabase. 如果找到它,我们将继续简单地ByteArray使用 Glide 加载。如果我们没有找到保存在数据库中的媒体,tryToGetFromMyDatabase则将返回 null,因此我们继续使用 Glide 加载 url 并在 Glide 完成下载媒体时收听。完成后,我们从 Glide 的缓存中检索文件并将其保存ByteArray在我的数据库中。

这种方法的代码如下:

val url: String = "http://myUrl"
val mediaByteArray: ByteArray? = tryToGetMediaFromMyDatabase(url)
val myImageView: ImageView = findViewById(R.id.image_view)

if(mediaByteArray == null){
    //We don't have the media saved in our database se we download from url and on response save it in database
    var builder = if(isGif){
            Glide.with(context)
            .asGif()
            .load(mediaUrl)
            .addListener(object: RequestListener<GifDrawable> {
                override fun onLoadFailed(e: GlideException?, model: Any?, target: Target<GifDrawable>?, isFirstResource: Boolean): Boolean {
                    return false
                }

                override fun onResourceReady(resource: GifDrawable?, model: Any?, target: Target<GifDrawable>?, dataSource: DataSource?, isFirstResource: Boolean): Boolean {
                    onMediaLoaded(mediaUrl)
                    return false
                }
            })

        }else{
            Glide.with(context)
            .asBitmap()
            .load(mediaUrl)
            .addListener(object: RequestListener<Bitmap>{
                override fun onLoadFailed(e: GlideException?, model: Any?, target: Target<Bitmap>?, isFirstResource: Boolean): Boolean {
                    return false
                }

                override fun onResourceReady(resource: Bitmap?, model: Any?, target: Target<Bitmap>?, dataSource: DataSource?, isFirstResource: Boolean): Boolean {
                    onMediaLoaded(mediaUrl)
                    return false
                }

            })
        }

builder.into(myImageView)

}else{
    //We have the media saved in database so we just load it without downloading it from the url
    var builder = if(isGif){
            Glide.with(context).asGif()
        }else{
            Glide.with(context).asBitmap()
        }
    builder.load(mediaByteArray).into(myImageView)
}

onMediaLoaded(url: String)执行以下操作以从 Glide 缓存中获取文件并将其保存到我的数据库中:

Thread(Runnable {
    val imageBytes = Glide.with(context)
            .asFile()
            .load(url)
            .submit()
            .get()
            .readBytes()
    saveIntoDatabase(url, imageBytes)
})

推荐阅读