Dagger 虽然可以生成点文件,但无法创建对象图

2024-03-23

我正在努力在现有应用程序中设置 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(使用前将#替换为@)

Dagger 虽然可以生成点文件,但无法创建对象图 的相关文章

随机推荐