I am using Android Databinding adapter and it says, it have to be static. So I am trying to make it non static and inject my classes into it with Dagger by following this tutorial. Although I can use my Picasso
instance which is provided by dagger normally in app, it says Picasso cannot be provided without an @Inject constructor or an @Provides-annotated method
.
I add @Inject annotation to my binding adapter constructor but still get same error
public class ImageBindingAdapter {
private final Picasso picasso;
@Inject
public ImageBindingAdapter(Picasso picasso) {
this.picasso = picasso;
}
@BindingAdapter("android:src")
public void loadImage(ImageView view, String url) {
picasso.load(url).fit().into(view);
}
}
I thought the problem might be relevant about a component
issue and changed my approach and followed this link and use subcomponent
. But this time dagger can not generate subcomponent and I can not set it like in the example
// Build dagger binding subcomponent and set it like default databinding component
DataBindingUtil.setDefaultComponent(sApplicationComponent
.daggerBindingComponentBuilder()
.build());
How can I inject my custom classes into binding adapter with Dagger, any help is appreciated
Here is my dagger classes, it is pretty same from tutorial that I mentioned above
ImageBindingAdapter Class
public class ImageBindingAdapter {
private final Picasso picasso;
@Inject
public ImageBindingAdapter(Picasso picasso) {
this.picasso = picasso;
}
@BindingAdapter("android:src")
public void loadImage(ImageView view, String url) {
picasso.load(url).fit().into(view);
}
}
BindingModule class
@Module
public class BindingModule {
@Provides
@DataBinding
ImageBindingAdapter provideImageBindingAdapter(Picasso picasso) {
return new ImageBindingAdapter(picasso);
}
}
BindingComponent class
@DataBinding
@Component(dependencies = AppComponent.class, modules = BindingModule.class)
public interface BindingComponent extends DataBindingComponent {
}
AppComponent class
@Singleton
@Component(modules = {AndroidSupportInjectionModule.class, AppModule.class, ...})
public interface AppComponent extends AndroidInjector<MyApp> {
@Component.Builder
interface Builder {
@BindsInstance
Builder application(Application application);
AppComponent build();
}
@Override
void inject(MyApp instance);
}
AppModule class
@Module
public class AppModule {
@Singleton
@Provides
Picasso picasso(Application application, OkHttp3Downloader okHttp3Downloader) {
return new Picasso.Builder(app.getApplicationContext())
.downloader(okHttp3Downloader)
.indicatorsEnabled(true)
.build();
}
....
}
Application class
public class MyApp extends DaggerApplication {
@Override
protected AndroidInjector<MyApp> applicationInjector() {
AppComponent appComponent = DaggerAppComponent.builder().application(this).build();
appComponent.inject(this);
BindingComponent bindingComponent = DaggerBindingComponent.builder()
.appComponent(appComponent)
.build();
DataBindingUtil.setDefaultComponent(bindingComponent);
return appComponent;
}
}
As error said, dagger could not resolve Picasso
dependency. In your case, the problem is that differenct dagger components can use directly only those dependencies, that interface marked with @Component
annotation declared using methods. To allow AppComponent
share Picasso
with BindingComponent
you need modify app component like that:
@Singleton
@Component(modules = {AndroidSupportInjectionModule.class, AppModule.class, ...})
public interface AppComponent extends AndroidInjector<MyApp> {
...
Picasso getPicasso();
}
After that dagger can properly resolve Picasso
dependency and error should disappear.