【问题标题】:Glide cache image on disk on background thread在后台线程的磁盘上滑动缓存图像
【发布时间】:2018-09-23 19:09:07
【问题描述】:

我想使用 Glide 急切地下载图像并将它们缓存在磁盘上以备将来使用。我想从后台线程调用此功能。

我已经阅读了Glide's caching documentation,但它没有解释如何在没有实际目标的情况下下载图像。然后我找到了this issue 并尝试使用类似的方法,但无论我尝试什么,我都会得到这个异常:

java.lang.IllegalArgumentException: You must call this method on the main thread

那么,如何让 Glide 缓存来自后台线程的图像?

编辑:我真的很想在后台线程上调用 Glide 的方法。我知道我可以使用 Handler 和其他方式将其卸载到 UI 线程,但这不是我要问的。

【问题讨论】:

  • 为什么不下载 ImageURLs 并将其存储在 Room DB 中,并且您可以随时从该 DB 加载图像。
  • @UmangBurman,将图像存储在数据库中是一个坏主意(就像存储任何其他大型二进制对象一样)。我可以下载图像,将其存储在本地并保留本地 URI,但这相当于重新发明轮子。首先我想知道 Glide 能不能做到。

标签: android multithreading android-glide


【解决方案1】:
GlideApp.with(context)
    .downloadOnly()
    .diskCacheStrategy(DiskCacheStrategy.DATA) // Cache resource before it's decoded
    .load(url)
    .submit(Target.SIZE_ORIGINAL, Target.SIZE_ORIGINAL)
    .get() // Called on background thread

【讨论】:

  • 正是我一直在寻找的。它甚至阻塞了很棒的线程。谢谢
【解决方案2】:

如果想在缓存中加载图像以供将来在后台线程中使用,那么 Glide 具有此功能

这里是怎么做的

 //here i passing application context so our glide tie itself with application lifecycle

FutureTarget<File> future = Glide.with(getApplicationContext()).downloadOnly().load("your_image_url").submit();

现在,如果您想检索要存储在数据库中的已保存路径,那么您可以这样做

File file = future.get();
String path = file.getAbsolutePath();

您也可以在一行中执行此操作,返回这样的路径字符串

String path = Glide.with(getApplicationContext()).downloadOnly().load("your_image_url").submit().get().getAbsolutePath();

【讨论】:

  • 感谢您非常详尽的回答。这是正确的,但我决定接受另一个答案,因为事实证明在这种情况下使用DATA 缓存策略是强制性的。
【解决方案3】:

您必须在主线程上调用此方法

无论你在哪里调用一个方法来使用Glide 或在后台做某事,都在里面运行:

runOnUiThread(new Runnable() {
                @Override
                public void run() {

              // Here, use glide or do your things on UiThread

            }
        });

在主线程中使用它,然后错误应该消失了。

【讨论】:

  • 谢谢,但这不是我问的。我有兴趣从后台线程调用 Glide 的方法,而不是跳回 UI 线程。
  • 正确!我刚看到你的编辑。但是,重点是,Glide 对 UI 的影响,因为它是一个图像加载库。所以,无论你想实现什么,它都会像现在这样抛出异常。
【解决方案4】:

我答对了吗?

private class update extends AsyncTask<Void, Void, Void> {

    @Override
    protected void onPreExecute() {
        super.onPreExecute();
    }

    @Override
    protected Void doInBackground(Void... params) {
        try {
        RequestOptions options = new RequestOptions()
        .diskCacheStrategy(DiskCacheStrategy.ALL) // Saves all image resolution
        .centerCrop()
        .priority(Priority.HIGH)
        .placeholder(R.drawable.null_image_profile)
        .error(R.drawable.null_image_profile);

    Glide.with(context).load(imageUrl)
        .apply(options);

        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    @Override
    protected void onPostExecute(Void aVoid) {
        //finish
    }
}

【讨论】:

  • 不。我没有profileImage,但即使我有,在后台线程上调用into 也会引发异常。
猜你喜欢
  • 1970-01-01
  • 2016-06-18
  • 1970-01-01
  • 1970-01-01
  • 2015-06-13
  • 1970-01-01
  • 2016-07-16
  • 2013-02-10
  • 2016-08-30
相关资源
最近更新 更多