1

I am using DexGuard to compile my app. My app uses vector drawables. I have all the settings correct, and it works correctly, both in the debug version, and when I use Proguard for the release version. It only crashes in the release version when using DexGuard. So I know it's a DexGuard issue. I am using DexGuard v7.0 and I cannot update due to license restrictions. I have added -keepresourcefiles "res/drawable/**" -keep class android.support.v7.** { *; } to my dexguard file for testing purposes and for clearer stacktraces, so we know that is not the issue. It crashes with following stacktrace;

 java.lang.RuntimeException: Unable to start activity ComponentInfo{com.lionscribe.myapp/com.lionscribe.elist.main.MainActivity}: android.content.res.Resources$NotFoundException: File res/drawable/abc_ic_ab_back_material.xml from drawable resource ID #0x7f020018
       at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2413)
       at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2471)
       at android.app.ActivityThread.access$900(ActivityThread.java:175)
       at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1308)
       at android.os.Handler.dispatchMessage(Handler.java:102)
       at android.os.Looper.loop(Looper.java:146)
       at android.app.ActivityThread.main(ActivityThread.java:5602)
       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:1283)
       at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1099)
       at dalvik.system.NativeStart.main(Native Method)
    Caused by: android.content.res.Resources$NotFoundException: File res/drawable/abc_ic_ab_back_material.xml from drawable resource ID #0x7f020018
       at android.content.res.Resources.loadDrawable(Resources.java:3440)
       at android.content.res.Resources.getDrawable(Resources.java:1917)
       at o.?.?(:354)
       at android.support.v7.widget.AppCompatDrawableManager.getDrawable(:193)
       at android.support.v7.widget.AppCompatDrawableManager.getDrawable(:181)
       at android.support.v7.widget.AppCompatDrawableManager.checkVectorDrawableSetup(:689)
       at android.support.v7.widget.AppCompatDrawableManager.getDrawable(:186)
       at android.support.v7.widget.TintTypedArray.getDrawableIfKnown(:77)
       at android.support.v7.app.AppCompatDelegateImplBase.<init>(:83)
       at android.support.v7.app.AppCompatDelegateImplV7.<init>(:146)
       at android.support.v7.app.AppCompatDelegateImplV11.<init>(:28)
       at android.support.v7.app.AppCompatDelegateImplV14.<init>(:41)
       at android.support.v7.app.AppCompatDelegate.create(:193)
       at android.support.v7.app.AppCompatDelegate.create(:173)
       at android.support.v7.app.AppCompatActivity.getDelegate(:511)
       at android.support.v7.app.AppCompatActivity.onCreate(:71)
       at o.hF.onCreate(:29)
       at com.lionscribe.elist.main.MainActivity.onCreate(:121)
       at android.app.Activity.performCreate(Activity.java:5451)
       at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1093)
       at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2377)
       at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2471) 
       at android.app.ActivityThread.access$900(ActivityThread.java:175) 
       at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1308) 
       at android.os.Handler.dispatchMessage(Handler.java:102) 
       at android.os.Looper.loop(Looper.java:146) 
       at android.app.ActivityThread.main(ActivityThread.java:5602) 
       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:1283) 
       at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1099) 
       at dalvik.system.NativeStart.main(Native Method) 
    Caused by: org.xmlpull.v1.XmlPullParserException: Binary XML file line #17: 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:3436)
       at android.content.res.Resources.getDrawable(Resources.java:1917) 
       at o.?.?(:354) 
       at android.support.v7.widget.AppCompatDrawableManager.getDrawable(:193) 
       at android.support.v7.widget.AppCompatDrawableManager.getDrawable(:181) 
       at android.support.v7.widget.AppCompatDrawableManager.checkVectorDrawableSetup(:689) 
       at android.support.v7.widget.AppCompatDrawableManager.getDrawable(:186) 
       at android.support.v7.widget.TintTypedArray.getDrawableIfKnown(:77) 
       at android.support.v7.app.AppCompatDelegateImplBase.<init>(:83) 
       at android.support.v7.app.AppCompatDelegateImplV7.<init>(:146) 
       at android.support.v7.app.AppCompatDelegateImplV11.<init>(:28) 
       at android.support.v7.app.AppCompatDelegateImplV14.<init>(:41) 
       at android.support.v7.app.AppCompatDelegate.create(:193) 
       at android.support.v7.app.AppCompatDelegate.create(:173) 
       at android.support.v7.app.AppCompatActivity.getDelegate(:511) 
       at android.support.v7.app.AppCompatActivity.onCreate(:71) 
       at o.hF.onCreate(:29) 
       at com.lionscribe.elist.main.MainActivity.onCreate(:121) 
       at android.app.Activity.performCreate(Activity.java:5451) 
       at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1093) 
       at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2377) 
       at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2471) 
       at android.app.ActivityThread.access$900(ActivityThread.java:175) 
       at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1308) 
       at android.os.Handler.dispatchMessage(Handler.java:102) 
       at android.os.Looper.loop(Looper.java:146) 
       at android.app.ActivityThread.main(ActivityThread.java:5602) 
       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:1283) 
       at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1099) 
       at dalvik.system.NativeStart.main(Native Method) 

Upon following the code, I follow that when using DexGuard, the method loadDrawableFromDelegates (called from getDrawable) in android.support.v7.widget.AppCompatDrawableManager is returning null. Therefore getDrawable continues and calls ContextCompat.getDrawable, which does not support Vectors in pre-Lollipop devices, and it returns null with an invalid drawable tag vector log, and therefore causes a ResourcesNotFoundException.
When using the debug version, loadDrawableFromDelegates does return a Drawable, therefore ContextCompat.getDrawable does not get called, and everything works fine. Does anyone have any ideas how to avoid this. I Googled, and there are others who had similiar issues, but they were mostly appcompat vector setting issues, not DexGuard.

Lewis McGeary
  • 7,692
  • 2
  • 40
  • 46
lionscribe
  • 3,413
  • 1
  • 16
  • 21

1 Answers1

4

Well after 12 hours of work, I finally figured it out, and all it was is 1 line in the DexGuard config. You do not need any of the settings I mentioned above. all you need is

-keepresourcexmlattributenames vector/**

Reason for this is that the AppCompat library does not look for the attributes of the vector, like viewportWidth by id, but it uses the actual atribute name. Dexguard by default strips the name, thus it never found the value. By adding the above line, you are telling DexGuard to leave the attribute names for all vector files.
I hope this saves others of much heartache.

lionscribe
  • 3,413
  • 1
  • 16
  • 21
  • You could have saved the hassle by using a more recent DexGuard version, which supports vector drawables already via its default configuration. – T. Neidhart Aug 22 '16 at 20:32
  • I already mentioned it, O cannot upgrade due to license limitations. I am sure there are many around in same situation, as DexGuard had changed their licensing model. – lionscribe Aug 22 '16 at 20:40
  • Well "license limitation" is somewhat misleading. DexGuard has changed its license model to an annual subscription, and it might be a bit too expensive for some developers, but there is no limitation per se. – T. Neidhart Aug 22 '16 at 20:43
  • Well, switching fees from €500 per user unlimited, to about €5000 per app per year, is to most people a BIG issue and is a limitation that does not allow upgrading! – lionscribe Aug 23 '16 at 00:05