dagger-reflect icon indicating copy to clipboard operation
dagger-reflect copied to clipboard

dagger-android crash in DaggerApplication

Open realdadfish opened this issue 5 years ago • 5 comments

  • Have your main application class derive from dagger.android.DaggerApplication
  • Implement applicationInjector() to return the AndroidInjector
  • Partial reflection setup
  • Dagger: 2.28.3, Delect 0.3.0 (Dagger-Reflect-latest)
java.lang.RuntimeException: Unable to create application my.application.MyApplication: java.lang.IllegalStateException: The AndroidInjector returned from applicationInjector() did not inject the DaggerApplication
      at android.app.ActivityThread.handleBindApplication(ActivityThread.java:6715)
      at android.app.ActivityThread.access$1300(ActivityThread.java:226)
      at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1898)
      at android.os.Handler.dispatchMessage(Handler.java:107)
      at android.os.Looper.loop(Looper.java:214)
      at android.app.ActivityThread.main(ActivityThread.java:7615)
      at java.lang.reflect.Method.invoke(Native Method)
      at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:492)
      at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:964)
Caused by: java.lang.IllegalStateException: The AndroidInjector returned from applicationInjector() did not inject the DaggerApplication
      at dagger.android.DaggerApplication.injectIfNecessary(DaggerApplication.java:65)
      at dagger.android.DaggerApplication.onCreate(DaggerApplication.java:38)
      at my.application.MyApplication.onCreate(MyApplication.kt:46)
      at android.app.Instrumentation.callApplicationOnCreate(Instrumentation.java:1190)
      at android.app.ActivityThread.handleBindApplication(ActivityThread.java:6710)
      ... 8 more

realdadfish avatar Sep 08 '20 08:09 realdadfish

Presumably because we don't support injecting a MembersInjector.

JakeWharton avatar Sep 08 '20 16:09 JakeWharton

Issue is that AndroidInjector has a void inject(T instance); and therefor does not enforce a specific void inject(MyApplication instance) method in the application component (which derives from said interface). dagger-reflect now reads this method's argument as Object and can't find the factory that provides injectees for this type.

I refactored the code to not use DaggerApplication and replaced the usage of AndroidInjector by a specific inject(...) method and that made this issue go away.

realdadfish avatar Sep 09 '20 12:09 realdadfish

While that's true, this still should work in reflection since we don't actually need to resolve that T. The implementation injects a Map<Class<?>, AndroidInjector<?>> which the generated module binds into using your application class as the key.

So I'm not exactly sure why this doesn't work already today. But we should be able to make it work.

JakeWharton avatar Sep 09 '20 13:09 JakeWharton

This is a problem with generic handling. We don't correctly project T to be your application subtype. There's a few other issues for this.

JakeWharton avatar Sep 13 '20 04:09 JakeWharton

I had the same problem and found a workaround that is somewhat simpler: In my case there is also an XxxInternalApplication which created the injector, so I just added:

@Override void inject(@NotNull XxxInternalApplication instance);

... to the InternalApplicationComponent and then in the XxxInternalApplication applicationInjector() method I added:

mInternalApplicationComponent.inject(this);

... before the return. Hope this helps someone.

catellie avatar Oct 14 '20 15:10 catellie