18

I am succesfully using proguard for my Android apps.

However, with one app I am having trouble.

This app uses a java library that has a .xml file that is stored in the package.

InputStream istream = Library.class.getResourceAsStream("resource.xml");

This library works great when proguard is disabled. However, running proguard, it seems that the xml file is just completely stripped away.

Relevant proguard.cfg

-optimizationpasses 5
-dontusemixedcaseclassnames
-dontskipnonpubliclibraryclasses
-dontpreverify
#-dontobfuscate
#-repackageclasses '' //THIS IS DISABLED
-keepattributes *Annotation*
-keepattributes Signature
-verbose
-dontwarn roboguice.activity.RoboMapActivity
-optimizations !code/simplification/arithmetic,!field/*,!class/merging/*

Any ideas on how to force keep this xml file?

Peterdk
  • 15,625
  • 20
  • 101
  • 140

3 Answers3

19

You shoud add a new file keep.xml under res/raw.

<?xml version="1.0" encoding="utf-8"?>
<resources xmlns:tools="http://schemas.android.com/tools"
    tools:keep="@layout/l_used*_c,@layout/l_used_a,@layout/l_used_b*"
    tools:discard="@layout/unused2" />

In tools:keep, you list the layouts you want to keep. You can even keep specefic drawables if you use reflection in your code to get your drawable

tools:keep="@drawable/ico_android_home_infosperso"

I prefer to add tools:shrinkMode="strict" so that I make sure no resource is eliminated unless it is not used for sure. You may want to have a look at this link Shrink your code. Don't Forget to add these lines to your proguard rules:

-keepattributes InnerClasses -keep class **.R -keep class **.R$* { <fields>; }

Meriam
  • 945
  • 8
  • 18
  • using `strict` will eliminate resources if it not used explicitly. So if resource is used by `Library.class.getResource` it will be eliminated – Mahmoud Mabrok May 17 '22 at 14:16
13

First of all, It turned out that using ant and my build.xml script didn't process the .xml resource file at all. You'll need to manually add a copy action to the build.xml for the resource files to be copied to the output dir.

Still, having solved that, proguard messed up my work. Solution was:

 -keeppackagenames the.package.where.the.file.is.kept

This made sure that the .xml file could be found by calling the Library.class.getResource.

Peterdk
  • 15,625
  • 20
  • 101
  • 140
-1

You should store files in the appropriate /res/xml, /res/assets, or /res/raw folder and access them through the resource management system or the asset manager correspondingly. You can read more about providing resources in Android Developer's Guide.

Abandoned Cart
  • 4,512
  • 1
  • 34
  • 41
Malcolm
  • 41,014
  • 11
  • 68
  • 91
  • That's all nice, but this is a xml file in a java library, not a android one. I use it in my android application, and without proguard it works fine. I ofcourse understand that in normal android apps you don't use it this way. – Peterdk May 01 '11 at 15:29
  • The problem is, it doesn't look like ProGuard's fault. ProGuard doesn't strip resources from JARs, it can only remove classes during shrinking. It is more likely that these problems originate from Android build files. It is possible to modify them to suit your needs, but that's not an easy soultion. And even if you succeed, you may have to do it again every time SDK gets updated. – Malcolm May 01 '11 at 18:55
  • Still, when proguard is disabled, the resources work from within my app. When proguard is enabled, they don't. So, proguard is doing something that causes trouble. – Peterdk May 02 '11 at 16:56
  • How exactly do you disable ProGuard? You mean that it isn't called in build.xml at all or do you change its configuration file so that it doesn't shrink, optimize or obfuscate? – Malcolm May 02 '11 at 17:50
  • I disable it in the build.properties or other properties file. Anyway, I found the solution and also a bug in my implementation. – Peterdk May 03 '11 at 08:00
  • Then my guess was right that the problem is with the Android build files. By the way, what was your solution? – Malcolm May 03 '11 at 08:34
  • Indeed, you were right. It turned out that I used eclipse build for without proguard testing, and used ant buildscript for use with proguard. I added a copy ***/*.xml to output dir in ant build-script. – Peterdk May 04 '11 at 13:07