【问题标题】:Proguard breaks parameterized constructor injectionProguard 打破了参数化构造函数注入
【发布时间】:2015-09-16 05:45:19
【问题描述】:

我设置了一个测试项目,以了解如何将 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>(...);
}

这是我的测试模块:

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";
}

}

这是应用程序类:

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());
}
}

当它尝试创建应用程序注入器(在应用程序类中)时,它会失败并出现以下错误:

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

我认为“@com.google.inject.Inject (...);” proguard 规则中的行应该已经解决了这个问题,但它没有。我什至尝试反编译 apk 以确保 @Inject 注释存在(在构造函数之前)并且它存在,但它仍然不起作用。

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

【问题讨论】:

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


    【解决方案1】:

    我发现如果构造函数的任何参数被混淆了,我也收到了这个错误——即使在做了与 op 相同的事情之后。 (即使在 RoboGuice Module 配置中显式绑定这些类也无济于事。)

    但是在我确保所有的构造函数参数类型也有 ProGuard -keepclassnames 异常之后,ProGuard 才能找到构造函数。

    我猜在这种情况下异常消息有点误导;或者至少有点不完整,因为它应该声明所有构造函数参数类型也需要通过它们的原始名称“找到”。

    【讨论】:

      【解决方案2】:

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

      1. @Inject 作为属性
      2. 为构造函数使用Provider&lt;Context&gt; 参数

      并在您的 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
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2016-11-26
        • 1970-01-01
        • 1970-01-01
        • 2015-11-11
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-03-27
        相关资源
        最近更新 更多