Preload multiple images with Glide

后端 未结 5 958
我寻月下人不归
我寻月下人不归 2020-11-30 02:07

We are trying to preload images into cache memory to load them later (the images are located in the Asset folder of the application)

<
相关标签:
5条回答
  • 2020-11-30 02:11

    Glide version 4.6.1

    RequestOptions requestOptions = RequestOptions
            .diskCacheStrategy(DiskCacheStrategy.ALL);
    
    Glide.with(appContext)
            .asBitmap()
            .load(model)
            .apply(requestOptions)
            .submit();
    
    0 讨论(0)
  • 2020-11-30 02:15

    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<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

    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);
    }
    
    0 讨论(0)
  • 2020-11-30 02:19
    //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。

    0 讨论(0)
  • 2020-11-30 02:24

    As the downloadOnly function is deprecated to cache on Disk:

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

    We can now use:

    Glide.with(ctx)
            .downloadOnly()
            .load("Image URL")
            .submit(500, 500)
    
    0 讨论(0)
  • 2020-11-30 02:26

    Use the following code to cache images without displaying them

    1. using the downloadOnly method 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 preload method if you want to load them into the Memory Cache.

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

    You can later use the cached images using

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

    0 讨论(0)
提交回复
热议问题