dart
dart copied to clipboard
Dart can't find injector when using Proguard
After enabling minifyEnabled
for release build, crashes start occurring.
I have a proguard-rules:
-dontwarn com.f2prateek.dart.internal.**
-keep class **$$ExtraInjector { *; }
-keepclasseswithmembernames class * {
@com.f2prateek.dart.* <fields>;
}
and seeing in log:
02-08 22:03:31.765 11321-11440/? D/Dart: Looking up extra injector for pl.srw.service.AService
02-08 22:03:31.767 11321-11440/? D/Dart: Not found. Trying superclass pl.srw.service.a
02-08 22:03:31.768 11321-11440/? D/Dart: Not found. Trying superclass android.app.IntentService
02-08 22:03:31.768 11321-11440/? D/Dart: MISS: Reached framework class. Abandoning search.
I'm on version 1.1.0
It looks like your issue is that the ExtraInjector
of the class pl.srw.service.AService
can't be found.
You can debug by trying to find out which injectors is not found after obfuscation: is it for the class itself, for its super class ? Should they be found ? Do superclasses have a ExtraInjector
in the non obfuscated version, etc.
We don't have enough detail on this bug to help you and we don't use obfuscation in our app, so it's hard to help.
We would advise to use newer versions than 1.1.0, it's been a while we didn't work on it.
ExtraInjector
is generated for super class a
. Without obfuscation there is one available and everything works fine.
My IntentService
super class has annotations on it and Dart.inject
call:
public abstract class a extends IntentService {
protected @InjectExtra(IntentCreator.A) String aExtra;
protected @Optional @InjectExtra(IntentCreator.B) int bExtra;
protected a(String name) {
super(name);
}
@Override
protected void onHandleIntent(final Intent intent) {
Dart.inject(this, intent.getExtras());
// ...
}
It's really hard to say what happens. You need to investigate things like:
- what is the name of
a
after obfuscation - how is ExtraInjector of
a
named - what does the call to it looks like after obfuscation, etc.
There is not enough information to answer your issue.
Ok, so I looked into release (obfuscated) apk and my hierarchy:
AService extends BaseService
is AService extends a
The abstract BaseService
class is the only one containing @InjectExtra
annotations and so BaseService$$ExtraInjector
is generated.
The problem is that Dart is looking for a$$ExtraInjector
whereas in the obfuscated apk it can find only the BaseService$$ExtraInjector
Hi, I see that after removing the last field with @Bind from my fragment, the fragment class is now obfuscated.
So I conclude that the proguard rule:
-keepclasseswithmembernames class * {
@com.f2prateek.dart.* <fields>;
}
does not work and
-keepclasseswithmembernames class * {
@butterknife.* <fields>;
}
works.
The diff between @Bind and @InjectExtra is that the first has CLASS retention and the second has SOURCE retention.
=> It is just an idea, but maybe @InjectExtra should have CLASS retention to fix this issue
Benoît
@bmarty you are right, I changed it and it works. Here you can find the sources and PR: https://github.com/f2prateek/dart/pull/163
@stephanenicolas let me know any problems