Dagger 2.11-rc2
Android Studio 2.4 preview7
classpath 'com.android.tools.build:gradle:2.4.0-alpha7'
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
When using @ContributesAndroidInjector, I get a runtime exception:
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.thepacific.clean/com.thepacific.clean.MainActivity}: java.lang.IllegalArgumentException: No injector factory bound for Class<com.thepacific.clean.MainActivity>
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2758)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2817)
at android.app.ActivityThread.-wrap11(Unknown Source:0)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1549)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:156)
at android.app.ActivityThread.main(ActivityThread.java:6440)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:240)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:746)
Caused by: java.lang.IllegalArgumentException: No injector factory bound for Class<com.thepacific.clean.MainActivity>
at com.thepacific.dagger.DispatchingAndroidInjector.inject(DispatchingAndroidInjector.java:110)
at com.thepacific.dagger.AndroidInjection.inject(AndroidInjection.java:64)
at com.thepacific.mvp.DaggerRxActivity.onCreate(DaggerRxActivity.java:20)
at com.thepacific.clean.MainActivity.onCreate(MainActivity.java:11)
at android.app.Activity.performCreate(Activity.java:6773)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1195)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2711)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2817)聽
at android.app.ActivityThread.-wrap11(Unknown Source:0)聽
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1549)聽
at android.os.Handler.dispatchMessage(Handler.java:102)聽
at android.os.Looper.loop(Looper.java:156)聽
at android.app.ActivityThread.main(ActivityThread.java:6440)聽
at java.lang.reflect.Method.invoke(Native Method)聽
at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:240)聽
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:746)聽
public class App extends DaggerApplication{
@Override
protected AndroidInjector<? extends DaggerApplication> applicationInjector() {
return DaggerAppComponent.builder().create(this);
}
}
@Module
public abstract class AppModule {
@Binds
public abstract Application app(App app);
}
@Component(modules = {AppModule.class, AppBinder.class, AndroidInjectionModule.class})
@Singleton
public interface AppComponent extends AndroidInjector<App> {
@Component.Builder
abstract class Builder extends AndroidInjector.Builder<App> {
}
}
@Module
public abstract class AppBinder {
@ContributesAndroidInjector
public abstract MainActivity mainActivity();
}
public class MainActivity extends DaggerAppCompatActivity{
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
}
Looks like you didn't follow the required steps (see step 3 specifically): https://google.github.io/dagger/android.html#injecting-activity-objects
@tbroyer
I follow this
Pro-tip: If your subcomponent and its builder have no other methods or supertypes than the ones mentioned in step #2, you can use @ContributesAndroidInjector to generate them for you. Instead of steps 2 and 3, add an abstract module method that returns your activity, annotate it with @ContributesAndroidInjector, and specify the modules you want to install into the subcomponent. If the subcomponent needs scopes, apply the scope annotations to the method as well.
@ActivityScope
@ContributesAndroidInjector(modules = { /* modules to install into the subcomponent */ })
abstract YourActivity contributeYourActivityInjector();
could somebody explain to me what was wrong here, and how to fix this issue? I'm trying to use the dagger in a Gradle multi-module project and getting the same exception
@tbroyer
You're right and need to follow all steps from https://google.github.io/dagger/android.html#injecting-activity-objects .
However, when not following one of these steps (the 3rd one specifically, in this example), the Dagger annotation processor should generate a compilation error. Right now, no compilation error is generated and instead, the above runtime exception is thrown...
It can't fail at compile time because you're adding an entry into a map which is only queried at runtime. Moreover, from which component the map being queried originates can only be determined at runtime based on the relationship of the element being injected to its parent object.
I see. That makes sense. Thanks!
However, it is not immediately clear that ContributesAndroidInjector uses a map which prevents Dagger from promising to generate compile-time errors if something is amiss in this case.
@JakeWharton I understand that the originating component can be determined only in runtime.
Would it be possible to add a loose check that at least some component in the project has a ContributesAndroidInjector binding?
That's better than no check at all.
do you think that this kind of check makes sense?
You should really only use @ContributesAndroidInjector across modules (aka compilation units). As a result, it's very likely that there is no component defined which includes it in a way that Dagger can analyze.
Most helpful comment
could somebody explain to me what was wrong here, and how to fix this issue? I'm trying to use the dagger in a Gradle multi-module project and getting the same exception