Java 使用 Glide 预加载多个图像

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/37964187/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-11 19:51:04  来源:igfitidea点击:

Preload multiple images with Glide

javaandroidimageandroid-glide

提问by An-droid

We are trying to preload imagesinto cache memory to load them later (the images are located in the Asset folderof the application)

我们正在尝试将图像预加载到缓存中以便稍后加载(图像位于应用程序的Asset 文件夹中)

What we tried:

我们尝试了什么:

Glide.with(this)
    .load(pictureUri)
    .diskCacheStrategy(DiskCacheStrategy.ALL);

Glide.with(this)
    .load(picture_uri)
    .diskCacheStrategy(DiskCacheStrategy.ALL)
    .preload();

The issue: Images are cached only when we are trying to load/display them: They have to be loaded in memory before so that they appear faster.

问题:仅当我们尝试加载/显示图像时才会缓存图像:它们必须先加载到内存中,以便它们显示得更快。

Glide.with(this)
    .load(picture_uri)
    .into(imageView);

We also tried to use a GlideModule to increase the CacheMemory size:

我们还尝试使用 GlideModule 来增加 CacheMemory 大小:

public class GlideModule implements com.bumptech.glide.module.GlideModule {
    @Override
    public void applyOptions(Context context, GlideBuilder
        builder.setMemoryCache(new LruResourceCache(100000));
    }

    @Override
    public void registerComponents(Context context, Glide glide) {
    }
}

In the manifest:

在清单中:

 <meta-data android:name=".GlideModule" android:value="GlideModule"/>

Nothing is working so far. Any idea?

到目前为止没有任何工作。任何的想法?



We trying to use an invisible 1 dp imageView, but the result is the same:

我们尝试使用一个不可见的 1 dp imageView,但结果是一样的:

for(Drawing drawing: getDrawingsForTab(tab)){

    Glide.with(this)
            .load(drawing.getImage().toUri())
            .dontAnimate()
            .diskCacheStrategy(DiskCacheStrategy.ALL)
            .into(mPreloadCacheIv);

    for(Picture picture : getPictures()){

        Glide.with(this)
                .load(picture.getPicture().toUri())
                .dontAnimate()
                .diskCacheStrategy(DiskCacheStrategy.ALL)
                .into(mPreloadCacheIv);
    }
}

采纳答案by Sakchham

The best option is to handle caching yourself, it gives you more control & should be easy as you already know what bitmaps are to be loaded.

最好的选择是自己处理缓存,它为您提供更多控制权并且应该很容易,因为您已经知道要加载哪些位图。

First: Setup a LruCache

第一:设置 LruCache

LruCache<String, Bitmap> memCache = new LruCache<>(size) {
    @Override
    protected int sizeOf(String key, Bitmap image) {
        return image.getByteCount()/1024;
    }
};

Second: Load the bitmaps to the LruCache

第二:将位图加载到 LruCache

Display display = getWindowManager().getDefaultDisplay();
Point size = new Point();
display.getSize(size);
int width = size.x; //width of screen in pixels
int height = size.y;//height of screen in pixels
Glide.with(context)
    .load(Uri.parse("file:///android_asset/imagefile"))
    .asBitmap()
    .fitCenter() //fits given dimensions maintaining ratio
    .into(new SimpleTarget(width,height) {
        // the constructor SimpleTarget() without (width, height) can also be used.
        // as suggested by, An-droid in the comments
        @Override
        public void onResourceReady(Bitmap resource, GlideAnimation glideAnimation) {
            memCache.put("imagefile", resource);
        }
    });

Third: Use the cached bitmaps

第三:使用缓存的位图

Bitmap image = memCache.get("imagefile");
if (image != null) {
    //Bitmap exists in cache.
    imageView.setImageBitmap(image); 
} else {
    //Bitmap not found in cache reload it 
    Glide.with(context)
         .load(Uri.parse("file:///android_asset/imagefile"))
         .into(imageView);
}

回答by Vinay W

Use the following code to cache images without displaying them

使用以下代码缓存图像而不显示它们

  1. using the downloadOnlymethod if you are looking to download images from the web and store them in the diskCache:

    FutureTarget<File> future = Glide.with(applicationContext)
        .load(yourUrl)
        .downloadOnly(500, 500);
    
  2. using preloadmethod if you want to load them into the Memory Cache.

    Glide.with(context)
            .load(url)
            .preload(500, 500);
    
  1. downloadOnly如果您想从 Web 下载图像并将它们存储在 diskCache 中,请使用该方法:

    FutureTarget<File> future = Glide.with(applicationContext)
        .load(yourUrl)
        .downloadOnly(500, 500);
    
  2. preload如果要将它们加载到内存缓存中,请使用 using方法。

    Glide.with(context)
            .load(url)
            .preload(500, 500);
    

You can later use the cached images using

您可以稍后使用缓存的图像

Glide.with(yourFragment)
    .load(yourUrl)
    .into(yourView);


回答by yoAlex5

Glide version 4.6.1

滑翔版本 4.6.1

RequestOptions requestOptions = RequestOptions
        .diskCacheStrategy(DiskCacheStrategy.ALL);

Glide.with(appContext)
        .asBitmap()
        .load(model)
        .apply(requestOptions)
        .submit();

回答by dong sheng

//i can give you a solution

/**
 * 1.reflect some objects inside Glide
 */
fun prepareGlideObjects() {
    if (!enableFunctions || atomicPrepare.getAndSet(true)) {
        return
    }
    var t = LogTime.getLogTime()
    glide = Glide.get(BasicConfig.getInstance().appContext)
    if (diskCache == null) {
        val engine = getObject(glide, "engine")
        val diskCacheProvider = getObject(engine, "diskCacheProvider")
        val method = diskCacheProvider!!::class.java.getDeclaredMethod("getDiskCache")
        method.isAccessible = true
        diskCache = method.invoke(diskCacheProvider) as DiskCache
    }
    if (arrayPool == null) {
        arrayPool = getObject(glide, "arrayPool") as ArrayPool
    }
    if (decoder == null) {
        val registry = getObject(glide, "registry") as Registry
        val decoderRegistry = getObject(registry, "decoderRegistry") as ResourceDecoderRegistry
        val map = getObject(decoderRegistry, "decoders") as HashMap<*, *>
        val list = map["Bitmap"] as List<*>
        val o = list[0]
        decoder = getObject(o, "decoder") as ByteBufferBitmapDecoder
    }
    Log.debug(TAG, "prepareGlideObjects:" + LogTime.getElapsedMillis(t))
    try {
        t = LogTime.getLogTime()
        //首次打开diskCache 耗时较大,此处是提前打开文件索引
        val url = GlideUrl("http://xx.cdn.yy.com/fake_pic.jpg")
        val dataCacheKey = DataCacheKey(url, EmptySignature.obtain())
        diskCache?.get(dataCacheKey)
        Log.debug(TAG, "_load_fake_pic:" + LogTime.getElapsedMillis(t))
    } catch (e: Throwable) {
        Log.error(TAG, "cold load failed:$e")
    }
}

/**
 *2.load bitmap-file from diskCache
 */
fun loadBitmap(url: String) {
    val gUrl = GlideUrl(url:String)
    val dataCacheKey = DataCacheKey(gUrl, EmptySignature.obtain())
    val file = diskCache?.get(dataCacheKey)
}

//3.decode bitmap from file
private fun extractBitmapFromFile(url: String, file: File) {
    try {
        val dimen = getDimensionFromUrl(url)
        val result = decoder?.decode(ByteBufferUtil.fromFile(file), dimen[0], dimen[1],
                Options()) as BitmapResource?
        result!!.initialize()
        //simple bitmap cache
        bitmapMap[url] = result.get()
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
            Log.debug(TAG, "allocationByteCount:" +
                    bitmapMap[url]!!.allocationByteCount / 1024.0)
        }
    } catch (e: Throwable) {
        Log.error(TAG, "init result failed:$e")
    }
}

//4.decode file from http-stream
private fun decodeHttpStream() {
    val uri = GlideUrl(call?.request()?.url().toString())
    val contentLength = Preconditions.checkNotNull(responseBody).contentLength()
    val stream = ContentLengthInputStream.obtain(responseBody.byteStream(),
            contentLength)
    if (arrayPool == null) {
        //re prepare
        arrayPool = glide?.arrayPool
    }
    val encoder = StreamEncoder(arrayPool)
    val writer = DataCacheWriter(encoder, stream, Options())
    val originalKey = DataCacheKey(uri, EmptySignature.obtain())
    //ready,此处可以用来监控文件字节流写入本地文件的时间
    diskCache?.put(originalKey, writer)
    val file = diskCache?.get(uri)
}

//5.after these jobs done, load a bitmap from diskCache,it takes just 10ms。

//5.完成这些工作后,从diskCache加载位图,只需10ms。

回答by Mo Shaarawy

As the downloadOnlyfunction is deprecated to cache on Disk:

由于该downloadOnly函数已被弃用以缓存在磁盘上:

Glide.with(ctx)
        .load("Image URL")
        .downloadOnly(500, 500)

We can now use:

我们现在可以使用:

Glide.with(ctx)
        .downloadOnly()
        .load("Image URL")
        .submit(500, 500)