我正在努力在现有应用程序中设置 Dagger (1.0.1)。它被配置为使用 ProGuard,但我在这个测试中禁用了它-dontobfuscate
.
当我启用 dagger-compiler 时,它能够成功生成带有依赖关系图的点文件,但是当我删除编译器并在发布模式下构建应用程序时,它会在启动过程中崩溃,抱怨它无法创建对象图。
java.lang.RuntimeException: Unable to start activity
ComponentInfo{com.corp.myapp/com.corp.myapp.ui.activity.MainActivity}:
java.lang.IllegalStateException: Errors creating object graph:
No injectable members on com.corp.myapp.core.services.ConnectionMonitor. Do
you want to add an injectable constructor? required by
com.corp.myapp.core.services.ConnectionMonitor
com.corp.myapp.ui.activity.MyAppBaseActivity.connectionManager
No injectable members on com.corp.myapp.ui.crouton.CroutonManager. Do you want
to add an injectable constructor? required by
com.corp.myapp.ui.crouton.CroutonManager
com.corp.myapp.ui.activity.MyAppBaseActivity.croutonManager
No injectable members on com.corp.core.assembler.ResourceAssembler. Do you want
to add an injectable constructor? required by
com.corp.core.assembler.ResourceAssembler
com.corp.myapp.ui.activity.MyAppBaseActivity.resourceAssembler
I see MyAppBaseActivity
它的依赖关系是CroutonManager
or ConnectionMonitor
显示在生成的点文件中,因此根据这条评论 https://github.com/square/dagger/issues/228#issuecomment-17621260我预计这会起作用。据我所知,如果有问题,我用来生成点文件的启用编译器的构建应该可以检测到它。
UPDATE:
我之前说过
在调试模式下它永远不会失败
但经过进一步测试后事实并非如此:Debug模式下它不会因为 ProGuard 被禁用而失败,而在Release模式默认启用。如果我在发布模式下构建应用程序但是跳过 ProGuard,我也没有收到错误,并且应用程序成功启动。所以问题肯定和我的ProGuard配置有关。
Dagger 很大程度上依赖于反射和类名,这些名称是硬编码的并作为字符串进行操作。这使得代码难以收缩/优化/混淆。
以下配置适用于示例Dagger 1.1.0 中的 dagger/examples/simple https://github.com/square/dagger/tree/dagger-parent-1.1.0/examples/simple:
-keepattributes *Annotation*
-keepclassmembers,allowobfuscation class * {
@javax.inject.* *;
@dagger.* *;
<init>();
}
-keep class **$$ModuleAdapter
-keep class **$$InjectAdapter
-keep class **$$StaticInjection
-keepnames !abstract class coffee.*
-keepnames class dagger.Lazy
该配置保留所有字段和方法javax.inject
or dagger
注解和所有无参数构造函数。如果它们看起来未使用,ProGuard 可能会删除它们,但 Dagger 实际上是通过反射注入/访问它们。这与 RoboGuice 类似。
它还必须保留 Dagger 生成的所有适配器类。
它还必须保留与这些适配器类相关的所有类名,以便名称仍然匹配。在此示例中,这些几乎是包中的所有类coffee
,所以最简单的方法是使用通配符。对于其他应用程序,该行将有所不同。
最后,它还必须保留班级的名称dagger.Lazy
,因为它的名称在生成的代码中被硬编码为字符串。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)