Proguard打破参数化构造函数注入

时间:2015-06-29 16:46:01

标签: android dependency-injection proguard roboguice android-proguard

我设置了一个测试项目,看看如何使用注入的参数化构造函数来使用RoboGuice和Proguard。

这是我的proguard-rules.pro文件:

-keep class roboguice.** { *; }
-keep interface roboguice.** { *; }
-dontwarn roboguice.**

-keep class org.roboguice.** { *; }
-keep interface org.roboguice.** { *; }
-dontwarn org.roboguice.**

-keepattributes **

-keep class com.example.vladfatu.roboguicetest.application.TestModule

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

这是我的TestModule:

public class TestModule implements Module {

public TestModule() {
    super();
}

@Override
public void configure(Binder binder) {
    binder.bind(StateProvider.class).to(RoboTestStateProvider.class);
}

}

这是StateProvider:

public interface StateProvider {

String getState();
}

这是RoboTestStateProvider:

public class RoboTestStateProvider implements StateProvider {

private Context context;

@Inject
public RoboTestStateProvider(Context context) {
    this.context = context;
}

@Override
public String getState() {
    return "State";
}

}

这是Application类:

public class RoboTestApplication extends Application {

@Override
public void onCreate() {
    super.onCreate();

    RoboGuice.setUseAnnotationDatabases(false);
    configureInjection();
}

protected void configureInjection() {
    RoboGuice.getOrCreateBaseApplicationInjector(this, RoboGuice.DEFAULT_STAGE, RoboGuice.newDefaultRoboModule(this), new TestModule());
}
}

当它尝试创建Application Injector时(在Application类中),它失败并显示以下错误:

  

在com.example.vladfatu.roboguicetest.monitor.RoboTestStateProvider中找不到合适的构造函数。类必须有一个(也是唯一一个)使用@Inject注释的构造函数或一个非私有的零参数构造函数。

我认为“@ com.google.inject.Inject(...);”来自proguard规则的行应该已经修复了这个,但它没有。我甚至尝试反编译apk以确保@Inject注释在那里(在构造函数之前)并且它是,但它仍然不起作用。

显然,没有Proguard,这个工作正常...... 我使用的RoboGuice版本是3.0

2 个答案:

答案 0 :(得分:0)

如果你只想要上下文,你可以:

  1. @Inject as a property
  2. 使用构造函数的Provider<Context>参数
  3. 在proguard-rules.pro文件中包含以下内容:

    -keep class com.google.inject.Binder
    -keepclassmembers class * {
        @com.google.inject.Inject <init>(...);
    }
    -keepclassmembers class * {
        @javax.inject.Inject <init>(...);
    }
    # There's no way to keep all @Observes methods, so use the ORn*Event convention to identify event handlers
    -keepclassmembers class * {
        void *(**On*Event);
    }
    -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*(...);
    }
    
    -keep public class roboguice.**
    -keep class roboguice.** { *; }
    -keep class org.roboguice.** { *; }
    -keep public class javax.**
    -keep public class javax.annotation.**
    -keep public @interface javax.annotation.**
    -keep public interface javax.annotation.**
    -keep public class com.actionbarsherlock.**
    -keep public class android.**
    -keep public class android.** { *; }
    -keep public class android.content.res.Resources.Theme
    -keep public class android.content.res.Resources.Theme { *; }
    -keep public class android.content.res.Resources
    -keep public class android.content.res.Resources { *; }
    -keep public class com.google.** { *; }
    -keep public class com.google.**
    -keep public class android.support.**
    -keep public interface android.support.**
    
    #
    # Added to get it to work
    #
    
    #-dontwarn roboguice.activity.RoboSherlockPreferenceActivity
    -dontwarn com.actionbarsherlock.**
    -dontwarn com.google.android.maps.**
    -dontwarn javax.annotation.Nullable
    -dontwarn roboguice.activity.RoboMapActivity
    -dontwarn roboguice.activity.SherlockAccountAuthenticatorActivity
    -dontwarn javax.annotation.CheckReturnValue
    -dontwarn javax.annotation.concurrent.GuardedBy
    -dontwarn javax.annotation.ParametersAreNonnullByDefault
    -dontwarn sun.misc.Unsafe
    -dontwarn javax.annotation.CheckForNull
    -ignorewarnings
    

答案 1 :(得分:0)

我发现我也收到了这个错误 - 即使在做了与op相同的事情之后 - 如果构造函数的任何参数被混淆了。 (即使在RoboGuice Module配置中明确绑定这些类也没有帮助。)

但在确保所有构造函数参数类型也有ProGuard -keepclassnames异常后,ProGuard可以找到构造函数。

我猜这个异常消息在这种情况下有点误导;或者至少有点不完整,因为它应该声明所有构造函数参数类型也需要&#34;找到&#34;用他们原来的名字。