匕首不能创建对象图,虽然它可以产生点文件它可以、匕首、对象、文件

2023-09-05 23:24:43 作者:派大星和我一起来捉水母呀

我挣扎与匕首的设置(1.0.1),在现有的应用程序。它被配置为使用ProGuard的,但我禁用它这个测试与 -dontobfuscate

I'm struggling with the setup of Dagger (1.0.1), in a existing application. It was configured to use ProGuard but I disabled it for this test with -dontobfuscate.

当我使匕首编译它能够成功地生成与依赖关系图中的点文件,但是当我删除编译器和启动时建立在Release模式的应用程序崩溃,抱怨它无法创建对象图。

When I enable dagger-compiler it's able to successfully generate a dot file with the dependencies graph, but when I remove the compiler and build the app in Release mode it crashes during startup, complaining that it's unable to create the object graph.

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 正在按照此评论我预计这个工作显示在产生的点文件,因此。 AFAIK如果有什么问题,应该由我来生成点文件的编译器功能的版本被检测出来。

I see MyAppBaseActivity and it's dependencies with CroutonManager or ConnectionMonitor being displayed in the generated dot file, so according to this comment I expected this to work. AFAIK if there was something wrong it should be detected by the compiler-enabled build that I used to generate the dot file.

更新:

我previously指出,

I previously stated that

在调试模式下,它从来没有的

但它不是经过进一步的测试真的:在调试模式下,它不会失败,因为ProGuard的被禁用,而在发布模式下,默认情况下启用。如果我构建发布模式的应用程序,但跳过ProGuard的,我没有得到任何错误和应用程序成功启动。所以,问题肯定是与我ProGuard的配置。

but it's not really true after further testing: In Debug mode it doesn't fail because ProGuard is disabled, whereas in Release mode it is enabled by default. If I build the app in Release mode but skip ProGuard, I don't get the errors either and the app successfully starts. So the problem is definitely related to my ProGuard configuration.

推荐答案

匕首依赖了很多反思和类名是硬codeD和操作字符串。这使得code难以缩小/优化/模糊处理。

Dagger relies a lot on reflection and class names that are hard-coded and manipulated as strings. This makes the code difficult to shrink/optimize/obfuscate.

下面的配置适用于样本dagger/examples/simple在匕首1.1.0 :

The following configuration works for the sample 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 匕首注释,和所有参数构造函数。 ProGuard的可能,否则删除它们,如果它们出现未使用,但匕首实际上是注入/通过反射访问它们。这类似于RoboGuice

The configuration keeps all fields and methods with javax.inject or dagger annotations, and all parameterless constructors. ProGuard might otherwise remove them if they appear unused, but Dagger is actually injecting/accessing them through reflection. This is similar to RoboGuice.

它也必须保持受匕首产生的所有适配器类。

It also has to keep all adapter classes generated by Dagger.

它也必须保持与这些适配器类的所有类名,所以名字还是匹配。在此示例中,这些都是在包咖啡几乎所有的课,所以最简单的方法是使用一个外卡。这条线将是其他应用程序不同。

It also has to keep all class names related to these adapter classes, so the names still match. In this sample, those are almost all classes in the package coffee, so the easiest way is to use a wild-card. This line will be different for other applications.

最后,它也有保留类的名称 dagger.Lazy ,因为它的名字是硬codeD作为字符串中产生的code。

Finally, it also has to keep the name of the class dagger.Lazy, since its name is hard-coded as a string in the generated code.