Injection with google guice does not work anymore after obfuscation with proguard

我只是一个虾纸丫 提交于 2019-11-29 02:20:15

Having used proguard for a good amount of time, here is how I decided to solve the issues regarding reflection (and Guice is only a use case of it).

Reflection can be used with Proguard as long as NO class or methods name are entered as Strings.

That's to say this code is valid and will work after ProGuard obfuscation

Class someClass = Class.forName(SomeClass.class.getName());

while this code won't work

Class someClass = Class.forName("SomeClass");

Furthermore, Proguard will shrink uncalled methods and constructor. As a consequence, the Class.newInstance method won't work. Unfortunatly, usual Guice bindings works using this method.

This has some consequences on Guice code.

  • All your injections must be produced using @Provides annotated methods, since ProGuard will shrink classes due to the fact their constructors are not explictely called.
  • Proguard must not shrink the code of your modules classes.
  • ProGuard must not shrink annotations, whichever, and wherever they are (this can be configured, but I cannot remember where).

The "Signature" attribute is required to be able to access generic types when compiling in JDK 5.0 and higher.

Use -keepattributes Signature to fix error with ParameterizedType

With the current version of Proguard (4.7) I was able to get it working by adding the following:-

-keepattributes *Annotation*,Signature  
-keep class com.google.inject.Binder    
-keep public class com.google.inject.Inject
 # keeps all fields and Constructors with @Inject
-keepclassmembers,allowobfuscation class * {
    @com.google.inject.Inject <fields>;
    @com.google.inject.Inject <init>(...);
}

In addition to explicitly keeping any class that is created by Guice eg

-keep class com.example.Service

Following code works for me, having had the same problem.

-keepattributes Signature was the fix.

-optimizationpasses 5
-dontusemixedcaseclassnames
-dontskipnonpubliclibraryclasses
-dontpreverify
#-dontobfuscate
-repackageclasses ''
-keepattributes *Annotation*
-keepattributes Signature
-verbose
-optimizations !code/simplification/arithmetic,!field/*,!class/merging/*

-keep public class * extends android.app.Activity
-keep public class * extends android.app.Application
-keep public class * extends android.app.Service
-keep public class * extends android.content.BroadcastReceiver
-keep public class * extends android.content.ContentProvider
-keep public class * extends android.app.backup.BackupAgentHelper
-keep public class * extends android.preference.Preference
-keep public class com.android.vending.licensing.ILicensingService

-keepclasseswithmembernames class * {
    native <methods>;
}

-keepclasseswithmembernames class * {
    public <init>(android.content.Context, android.util.AttributeSet);
}

-keepclasseswithmembernames class * {
    public <init>(android.content.Context, android.util.AttributeSet, int);
}

-keepclassmembers enum * {
    public static **[] values();
    public static ** valueOf(java.lang.String);
}
-keepattributes Signature
-keep class * implements android.os.Parcelable {
  public static final android.os.Parcelable$Creator *;
}
-keep class com.google.inject.Binder
-keepclassmembers class * {
    @com.google.inject.Inject <init>(...);
}
-keep public class * extends android.view.View {
    public <init>(android.content.Context);
    public <init>(android.content.Context, android.util.AttributeSet);
    public <init>(android.content.Context, android.util.AttributeSet, int);
    public void set*(...);
} 

# I didn't need this one, maybe you need it.
#-keep public class roboguice.** 

-keepclassmembers class **.R$* {
    public static <fields>;
}
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!