使用 Glide 预加载多个图像

Preload multiple images with Glide

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

我们尝试了什么:

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

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

问题:图像仅在我们尝试 load/display 时才被缓存: 它们必须先加载到内存中才能显示得更快。

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

我们还尝试使用 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) {
    }
}

清单中:

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

目前没有任何效果。有什么想法吗?


我们尝试使用不可见的 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);
    }
}

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

  1. 如果您希望从网络下载图像并将它们存储在 diskCache 中,请使用 downloadOnly 方法:

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

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

您稍后可以使用

缓存的图像
Glide.with(yourFragment)
    .load(yourUrl)
    .into(yourView);

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

首先:设置一个 LruCache

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

其次:将位图加载到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);
        }
    });

第三:使用缓存的位图

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);
}

使用 Glide 预加载

Glide 版本 4.6.1

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

Glide.with(appContext)
        .asBitmap()
        .load(model)
        .apply(requestOptions)
        .submit();
//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这些工作完成了,从diskCache加载位图,只需要10ms。

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

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

我们现在可以使用:

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