I was happy to see google's fork of Dagger has been made available. (At the time of this writing, I realize that it is not "released" yet.) we have an android app which uses dagger heavily, although we do not use many of the more advanced features.
We have a business requirement to obfuscate our code, so I have have attempted an upgrade to Dagger 2.0-SNAPSHOT in the hopes that the removal of runtime reflection from Dagger would make it possible to run obfuscation.. however I'm finding that reflection is still used in terms of string constants being used at runtime to load classes.
Below is the relevent bits of my proguard.conf.
-dontpreverify
-keepattributes *Annotation*,JavascriptInterface,SourceFile,LineNumberTable,Signature
-verbose
-optimizations !code/simplification/arithmetic,!field/*,!class/merging/*
-ignorewarnings
-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.app.Fragment
-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 class android.support.v4.app.** { *; }
-keep interface android.support.v4.app.** { *; }
-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*(...);
}
-keepclasseswithmembernames class * {
native <methods>;
}
-keepclasseswithmembers class * {
public <init>(android.content.Context, android.util.AttributeSet);
}
-keepclasseswithmembers class * {
public <init>(android.content.Context, android.util.AttributeSet, int);
}
###### dagger 2.0 stuff
-keep class dagger.** { *; }
-keep interface dagger.** { *; }
-keepnames class com.ourcompany.**
-keep class **$$ModuleAdapter { *; }
-keepnames class **$$InjectAdapter { *; }
-keepclassmembers class * {
@javax.inject.Inject <fields>;
@javax.inject.Inject <init>(...);
}
-adaptclassstrings
As you can see I have turned off much of the obfuscation. This allows for some classes to be injected properly, however it still fails on injecting one paticular class.
Here is the exception:
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.ourcompany.mobile.ourapp/com.ourcompany.mobile.ourapp.MainActivity}: java.lang.IllegalStateException: Unable to create binding for com.ourcompany.mobile.ourapp.LogMetricsHelper
E/AndroidRuntime( 7228): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2195)
E/AndroidRuntime( 7228): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2245)
E/AndroidRuntime( 7228): at android.app.ActivityThread.access$800(ActivityThread.java:135)
E/AndroidRuntime( 7228): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1196)
E/AndroidRuntime( 7228): at android.os.Handler.dispatchMessage(Handler.java:102)
E/AndroidRuntime( 7228): at android.os.Looper.loop(Looper.java:136)
E/AndroidRuntime( 7228): at android.app.ActivityThread.main(ActivityThread.java:5017)
E/AndroidRuntime( 7228): at java.lang.reflect.Method.invokeNative(Native Method)
E/AndroidRuntime( 7228): at java.lang.reflect.Method.invoke(Method.java:515)
E/AndroidRuntime( 7228): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:779)
E/AndroidRuntime( 7228): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:595)
E/AndroidRuntime( 7228): at dalvik.system.NativeStart.main(Native Method)
E/AndroidRuntime( 7228): Caused by: java.lang.IllegalStateException: Unable to create binding for com.ourcompany.mobile.ourapp.LogMetricsHelper
E/AndroidRuntime( 7228): at dagger.internal.Linker.linkRequested(Linker.java:147)
E/AndroidRuntime( 7228): at dagger.ObjectGraph$DaggerObjectGraph.getInjectableTypeBinding(ObjectGraph.java:320)
E/AndroidRuntime( 7228): at dagger.ObjectGraph$DaggerObjectGraph.inject(ObjectGraph.java:290)
E/AndroidRuntime( 7228): at com.ourcompany.mobile.module.ScopedActionBarActivity.onCreate(ScopedActionBarActivity.java:20)
E/AndroidRuntime( 7228): at com.ourcompany.mobile.ourapp.BaseActivity.onCreate(BaseActivity.java:68)
E/AndroidRuntime( 7228): at com.ourcompany.mobile.ourapp.MainActivity.onCreate(MainActivity.java:146)
E/AndroidRuntime( 7228): at android.app.Activity.performCreate(Activity.java:5231)
E/AndroidRuntime( 7228): at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1087)
E/AndroidRuntime( 7228): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2159)
E/AndroidRuntime( 7228): ... 11 more
Has anyone tried out proguard with Google's dagger fork yet?
ProGuard is a command-line tool that reduces app size by shrinking bytecode and obfuscates the names of classes, fields and methods. It's an ideal fit for developers working with Java or Kotlin who are primarily interested in an Android optimizer.
ProGuard is a free shrinker, optimizer, obfuscator, and preverifier for Java bytecode: It detects and removes unused classes, fields, methods, and attributes.
Latest Dagger 2.0 SNAPSHOT (as of writing this) plays nicely with ProGuard. I added no rules for Dagger 2 in my ProGuard config. Everything just works.
BTW I'm also using ButterKnife and greenDAO in my project. Both need 3-4 ProGuard rules.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With