Dagger no puede crear el gráfico del objeto aunque puede producir el archivo del punto

Estoy luchando con la configuración de Dagger (1.0.1), en una aplicación existente. Se configuró para usar ProGuard pero lo deshabilité para esta prueba con -dontobfuscate .

Cuando habilito dagger-compilador es capaz de generar con éxito un archivo de puntos con el gráfico de dependencias, pero cuando elimino el compilador y construyo la aplicación en el modo Release, se bloquea durante el inicio, quejándose de que no puede crear el gráfico de objetos.

 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 

Veo MyAppBaseActivity y sus dependencias con CroutonManager o ConnectionMonitor se exhiben en el archivo generado del punto, así que según este comentario esperé que esto trabajara. AFAIK si había algo mal que debe ser detectado por el compilador habilitado construir que he utilizado para generar el archivo de puntos.


ACTUALIZAR:

Ya dije que

En el modo de depuración nunca falla

Pero en realidad no es cierto después de otras pruebas: En modo de depuración no falla porque ProGuard está deshabilitado, mientras que en el modo Release está habilitado de forma predeterminada. Si construyo la aplicación en el modo Release, pero omitiendo ProGuard , tampoco obtienes los errores y la aplicación se inicia correctamente. Así que el problema está definitivamente relacionado con mi configuración de ProGuard.

Dagger se basa mucho en la reflexión y los nombres de clase que están codificados y manipulados como cadenas. Esto hace que el código sea difícil de reducir / optimizar / ofuscar.

La siguiente configuración funciona para la daga de muestra / examples / simple en 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 

La configuración mantiene todos los campos y métodos con anotaciones javax.inject o dagger , y todos los constructores sin parámetros. ProGuard podría eliminarlos de otra forma si parecen no utilizados, pero Dagger realmente está inyectando / accediendo a ellos a través de la reflexión. Esto es similar a RoboGuice.

También tiene que mantener todas las clases de adaptador generadas por Dagger.

También tiene que mantener todos los nombres de clase relacionados con estas clases de adaptador, por lo que los nombres aún coinciden. En esta muestra, son casi todas las clases en el paquete de coffee , por lo que la forma más fácil es utilizar un comodín. Esta línea será diferente para otras aplicaciones.

Finalmente, también tiene que mantener el nombre de la clase dagger.Lazy , ya que su nombre está codificado como una cadena en el código generado.

Conseguí la aplicación para comenzar después de agregar -dontshrink al archivo de configuración de ProGuard. Tener -dontobfuscate al principio no era suficiente.

De hecho, si quito -dontobfuscate también funciona.

Definitivamente necesito un control más fino para esto, pero es un punto de partida. Mi configuración actual de ProGuard para Dagger es:

 ############# # Dagger # ############# -keep class dagger.** { *; } -dontwarn dagger.internal.codegen.** 

Dagger no requiere que @Inject esté en una clase para pasar a graph.inject(myActivity) porque algunas actividades pueden no tener ninguna inyección que hacer. Sin embargo, estos parecen dependencias de upstream, lo que significa que necesitan ser proporcionados a ComponentInfo , y por lo tanto necesitan ser aprovisionados por Dagger. No puede hacer esto si no puede crear estas clases, y no puede hacerlo si no se anotan, a menos que las proporcione a través de un método @Provides .

Por lo tanto, es necesario crear una clase @Module anotada que devuelve estos tipos de @Provides -anotado métodos, o necesita agregar @Inject a su constructor.

 -keep class * extends dagger.internal.Binding 

Dicho esto, en este caso, ¿está usando proguard en modo de "liberación"? ¿Y no proguarding en modo de depuración? Si es así, sospecho que Proguard está eliminando anotaciones. Tendrás que hacer alguna variante de:

 -keep class javax.inject.** { *; } 

… para asegurarse de que Proguard no elimine las anotaciones.

Acabé quemando una semana + tratando de conseguir que esto funcione. Al final fracasé y decidí darle una oportunidad a DexGuard. Funcionó maravillosamente fuera de la caja. Sí, es un producto comercial, pero DexGuard tiene un gran apoyo y por eso hemos podido finalmente enviar. La identificación definitivamente recomienda DexGuard si usted absolutamente necesidad de solucionar este problema.

  • Android Studio, ProGuard no puede calcular hash de Classes.jar
  • Proguard dando "Warning: org.msgpack. *"
  • Uso de ProGuard con Android.
  • Proguard no puede encontrar el método referenciado 'void allowCoreThreadTimeOut (boolean)'
  • Proguard Error al intentar exportar a través de android studio
  • ¿Por qué proguard procesa AndroidManifest.xml?
  • ¿Cómo ofuscar sólo un poco de clase o un solo paquete?
  • Android proguard obfuscated código está causando NullPointerException cuando realmente no debe ser
  • Problemas con ProGuard para Android con Parse 1.3.5 jar
  • ¿Cómo hacer que Proguard ignore las bibliotecas externas?
  • Proguard.cfg Falta
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.