1

我建立了一个测试项目,看看我如何将 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());
}
}

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

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

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

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

4

2 回答 2

0

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

  1. @Inject 作为属性
  2. 使用Provider<Context>构造函数的参数

并在您的 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
于 2015-06-30T16:07:26.390 回答
0

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

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

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

于 2016-11-09T20:08:44.350 回答