我设置了一个测试项目,看看如何使用注入的参数化构造函数来使用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
答案 0 :(得分:0)
如果你只想要上下文,你可以:
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
答案 1 :(得分:0)
我发现我也收到了这个错误 - 即使在做了与op相同的事情之后 - 如果构造函数的任何参数被混淆了。 (即使在RoboGuice Module
配置中明确绑定这些类也没有帮助。)
但在确保所有构造函数参数类型也有ProGuard -keepclassnames
异常后,ProGuard可以找到构造函数。
我猜这个异常消息在这种情况下有点误导;或者至少有点不完整,因为它应该声明所有构造函数参数类型也需要&#34;找到&#34;用他们原来的名字。