我在现有应用程序中努力设置 Dagger (1.0.1)。它被配置为使用 ProGuard,但我使用 -dontobfuscate
将其禁用以进行此测试。
当我启用 dagger-compiler 时,它能够成功生成带有依赖关系图的点文件,但是当我删除编译器并在 Release 模式下构建应用程序时,它会在启动期间崩溃,并提示它无法创建对象图。
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
我看到 MyAppBaseActivity
并且它与 CroutonManager
或 ConnectionMonitor
的依赖关系显示在生成的点文件中,因此根据 this comment我希望这能奏效。据我所知,如果有问题,我用来生成点文件的启用编译器的构建应该会检测到它。
更新:
我之前说过
In Debug mode it never fails
但经过进一步测试后情况并非如此:在Debug 模式下它不会因为 ProGuard 被禁用而失败,而在 Release 模式下它默认启用。如果我在 Release模式下构建应用程序但跳过 ProGuard,我也不会收到错误并且应用程序会成功启动。所以问题肯定与我的 ProGuard 配置有关。
最佳答案
Dagger 很大程度上依赖于反射和类名,这些名称是硬编码的并作为字符串进行操作。这使得代码难以收缩/优化/混淆。
以下配置适用于示例 dagger/examples/simple in Dagger 1.1.0 :
-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
或 dagger
注释的字段和方法,以及所有无参数构造函数。如果它们看起来未使用,ProGuard 可能会以其他方式删除它们,但 Dagger 实际上是通过反射注入(inject)/访问它们。这类似于 RoboGuice。
它还必须保留 Dagger 生成的所有适配器类。
它还必须保留与这些适配器类相关的所有类名,以便名称仍然匹配。在此示例中,这些几乎都是 coffee
包中的所有类,因此最简单的方法是使用通配符。对于其他应用程序,此行将有所不同。
最后,它还必须保留类 dagger.Lazy
的名称,因为它的名称在生成的代码中被硬编码为字符串。
关于android - Dagger 不能创建对象图,尽管它可以生成点文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18102084/