Closed
Description
- Create a vector drawable in xml
- Refer the drawable id in the
error
method - Run the app on Android < 5.0
- Make sure main image is not loaded and the error drawable is displayed
- The app crashes with:
android.content.res.Resources$NotFoundException: File res/drawable/no_image_placeholder.xml from drawable resource ID #0x7f020080
at android.content.res.Resources.loadDrawable(Resources.java:3376)
at android.content.res.Resources.getDrawable(Resources.java:1872)
at com.bumptech.glide.request.GenericRequest.getErrorDrawable(GenericRequest.java:409)
at com.bumptech.glide.request.GenericRequest.setErrorPlaceholder(GenericRequest.java:399)
at com.bumptech.glide.request.GenericRequest.onException(GenericRequest.java:548)
at com.bumptech.glide.load.engine.EngineJob.handleExceptionOnMainThread(EngineJob.java:183)
at com.bumptech.glide.load.engine.EngineJob.access$200(EngineJob.java:22)
at com.bumptech.glide.load.engine.EngineJob$MainThreadCallback.handleMessage(EngineJob.java:204)
at android.os.Handler.dispatchMessage(Handler.java:98)
at android.os.Looper.loop(Looper.java:146)
at android.app.ActivityThread.main(ActivityThread.java:5653)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:515)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1291)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1107)
at dalvik.system.NativeStart.main(Native Method)
Caused by: org.xmlpull.v1.XmlPullParserException: Binary XML file line #2: invalid drawable tag vector
at android.graphics.drawable.Drawable.createFromXmlInner(Drawable.java:986)
at android.graphics.drawable.Drawable.createFromXml(Drawable.java:930)
at android.content.res.Resources.loadDrawable(Resources.java:3372)
at android.content.res.Resources.getDrawable(Resources.java:1872)
at com.bumptech.glide.request.GenericRequest.getErrorDrawable(GenericRequest.java:409)
at com.bumptech.glide.request.GenericRequest.setErrorPlaceholder(GenericRequest.java:399)
at com.bumptech.glide.request.GenericRequest.onException(GenericRequest.java:548)
at com.bumptech.glide.load.engine.EngineJob.handleExceptionOnMainThread(EngineJob.java:183)
at com.bumptech.glide.load.engine.EngineJob.access$200(EngineJob.java:22)
at com.bumptech.glide.load.engine.EngineJob$MainThreadCallback.handleMessage(EngineJob.java:204)
at android.os.Handler.dispatchMessage(Handler.java:98)
at android.os.Looper.loop(Looper.java:146)
at android.app.ActivityThread.main(ActivityThread.java:5653)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:515)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1291)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1107)
at dalvik.system.NativeStart.main(Native Method)
The problem is that GenericRequest
gets resources from the application context, not the provided context. All the AppCompat classes (like AppCompatActivity
) can return the VectorEnabledTintResources
class, which supports vector drawable. Unfortunately, there's no AppCompatApplication
, so the Application
class always returns just plain Resources
class which doesn't support vector drawables before Android 5.0.
Glide Version:
3.7.0
Integration libraries:
okhttp3-integration:1.4.0
Device/Android Version:
GT-P5210 Android 4.4.2
Metadata
Metadata
Assignees
Type
Projects
Relationships
Development
No branches or pull requests
Activity
TWiStErRob commentedon Jun 14, 2016
A simple workaround would be to get the drawable yourself:
.error(ContextCompat.getDrawable(getContext(), R.drawable.no_image_placeholder))
.Tip: you can save the request builder into a field and reuse it in an adapter to prevent continuously calling these (see
Glide.with(...).from*
).TWiStErRob commentedon Jun 14, 2016
I took a deeper look, checked the flow of
Context
from user toGenericRequest
and it seems to me that if we are not paranoid inRequestManager
the wrapped activity context would flow nicely to where you need it. The problem is that it would require a full analysis of other escape paths of that context to see if they're not kept once the Activity is destroyed.You said there's no
AppCompatApplication
, but you could simply create your own. Wouldn't it "just work" if you copiedAppCompatActivity.getResources
method into yourApplication
class?@sjudd what's your take on this?
jakubkrolewski commentedon Jun 14, 2016
The
AppCompatApplication
(full source below) is what I'm using right now, so the bug is no a blocker for me. However, the providedContext
can be in fact some custom instance ofContextWrapper
, so getting resources from it directly would be a more bulletproof solution.sjudd commentedon Jun 14, 2016
Themes are a sign we ought to use the provided context to load placeholders, not the application. We will have to be careful to avoid leaking activities unnecessarily, but that already can happen (if you use something like SimpleTarget) and we do try to guard against it by cancelling/restarting requests when activities and fragments are destroyed/re-created, so hopefully it won't be too bad.
sjudd commentedon Oct 18, 2017
So I think I have a more complete fix for this in 4.3 which will allow automatic application of themes and handle custom ContextWrappers for error/fallback/placeholder. The original issue I think was actually fixed a while ago in bd9e265.
Pass a non-application Context into Glide’s Requests.