69

My android program has a class A, which has two static inner class. They are found to be stripped from .dex after applying proguard.

public class A{

  ...
  static class B{
    ...
  }

  static class C{
    ...
  }
}

I have put the following lines in proguard.flags, but seem no luck.

-keep class com.xxx.A
-keep class com.xxx.A$*

Any hint?

Bhushan Firake
  • 9,338
  • 5
  • 44
  • 79
David Guan
  • 809
  • 1
  • 8
  • 13
  • For me, it was happening because my inner class was implementing an interface which was introduced in API 16+. As soon as I removed that interface from `implements`, my inner class started working fine in pre-API 16. – Sufian Feb 22 '17 at 08:08

6 Answers6

74

Try adding InnerClasses to the keep attributes. e.g:

-keepattributes Exceptions, InnerClasses, ...

Also, try adding a body to the "keep" call with an asterisk, like so:

-keep class com.xxx.A$* {
    *;
}
akelec
  • 3,797
  • 3
  • 41
  • 39
Alexander Lucas
  • 22,171
  • 3
  • 46
  • 43
59

This is what I had to do for my config

-keep class com.xxx.A { *; }
-keep class com.xxx.A$B { *; }
-keep class com.xxx.A$C { *; }
ajma
  • 12,106
  • 12
  • 71
  • 90
  • 1
    This worked for me. I almost had this solution, but had to remove the word `public` from the statement, even though both outer and inner classes are public. Weird and confusing. – Gi0rgi0s Sep 16 '16 at 18:54
10

This did the trick for me

-keepattributes InnerClasses
 -keep class com.yourpackage.YourClass**
 -keepclassmembers class com.yourpackage.YourClass** {
    *;
 }

It may be a bit overkill with the wildcards but I wanted to make sure I didn't miss anything. The main thing is you need the InnerClasses attributes the keep on the class and the keepclassmembers on the class.

Eliezer
  • 7,209
  • 12
  • 56
  • 103
GameSalutes
  • 1,762
  • 2
  • 18
  • 24
  • 1
    this line "-keepclassmembers com.yourpackage.YourClass**" should be changed to this "-keepclassmembers class com.yourpackage.YourClass**" – Ray Hunter Jan 09 '14 at 04:15
  • 2
    You can merge the last two lines. keepclassmembers is only meaningful if you don't also keep the class itself as an entry point – mxk Mar 24 '14 at 12:26
10

if you don't want all inner class and members in some package to be obfuscated you can add lines in proguard-rules.pro

    -keep class com.xxx.task.*$* {
        *;
    }
Mr235
  • 166
  • 2
  • 5
5

Your configuration looks correct. You should double-check that you haven't misspelled the class names. If the spelling in incorrect, ProGuard should print out a note about it. You can also specify -printseeds seeds.txt, and see if your classes are listed in the resulting file. If they are listed, the classes are also in the processed code.

As Alexander Lucas mentioned, you may also want to keep the fields and methods of these classes -- that depends on your requirements.

Eric Lafortune
  • 45,150
  • 8
  • 114
  • 106
  • What does it mean if my inner class is not in the seeds.txt file? http://stackoverflow.com/questions/19368053/proper-proguard-configuration-to-keep-static-inner-class-fields – TacB0sS Oct 15 '13 at 14:32
1

Most of the top answers does the job but they are using wildcard (*;) for adding everything which is not the accurate answer. Below configuration only adds the fields and method properties to preserve inner class methods.

-keepattributes Exceptions,InnerClasses,Signature, ...

# preserve class and nested classes' fields and methods
-keep class com.abc.package.clazzes.** {
    <fields>;
    <methods>;
}