问题
I want to use Glide to eagerly download images and cache them on disk for a future use. I want to call this functionality from a background thread.
I've read Glide's caching documentation, but it doesn't explain how to download the image without having an actual target right now. Then I found this issue and tried to use a similar approach, but whatever I try I get this exception:
java.lang.IllegalArgumentException: You must call this method on the main thread
So, how can I tell Glide to cache an image from a background thread?
EDIT: I really want to call Glide's methods on background thread. I know that I can use Handler and other ways to offload it to UI thread, but that's not what I'm asking.
回答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:
If want to load images in cache for future use in background thread then Glide have this functionality
here how you can do this
//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();
now if you want to retrieve the saved path that you want to store in your DB then you can do
File file = future.get();
String path = file.getAbsolutePath();
you can also do this in just one line returning a path string like this
String path = Glide.with(getApplicationContext()).downloadOnly().load("your_image_url").submit().get().getAbsolutePath();
回答3:
You must call this method on the main thread
Wherever you call a method to use Glide
or doing something from background, run inside:
runOnUiThread(new Runnable() {
@Override
public void run() {
// Here, use glide or do your things on UiThread
}
});
To use it inside the main thread and then error should be gone.
回答4:
The into(ImageView)
method of Glide
requires you to call it only on main thread, but when you pass the loading to a Timer it will be executed in a background
thread.
What you can do is to retrieve a bitmap by calling get()
instead of into()
and then set that bitmap
on the ImageView
by calling setImageBitmap()
.
Glide.with(getApplicationContext())
.load("your url")
.asBitmap()
.get()
or
Glide.with(getApplicationContext())
.load("your url")
.asBitmap()
.into(new BitmapImageViewTarget(imgView) {
@Override
protected void setResource(Bitmap resource) {
//Play with bitmap
super.setResource(resource);
}
});
Try this.
回答5:
Did I get the question right?
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
}
}
来源:https://stackoverflow.com/questions/52464658/glide-cache-image-on-disk-on-background-thread