Я использую адаптер Android Databinding, и он говорит, что он должен быть статическим. Поэтому я пытаюсь сделать его нестатичным и добавить в него свои классы с помощью Dagger, следуя этому уроку. Хотя я могу использовать свой экземпляр Picasso
который обычно предоставляется кинжалом в приложении, он говорит, что Picasso cannot be provided without an @Inject constructor or an @Provides-annotated method
.
Я добавляю аннотацию @Inject в конструктор адаптера привязки, но все равно получаю ту же ошибку
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);
}
}
Я подумал, что проблема может иметь отношение к проблеме с component
и изменил мой подход, следуя этой ссылке и используя subcomponent
. Но на этот раз кинжал не может генерировать подкомпонент, и я не могу установить его, как в примере
// Build dagger binding subcomponent and set it like default databinding component
DataBindingUtil.setDefaultComponent(sApplicationComponent
.daggerBindingComponentBuilder()
.build());
Как я могу внедрить свои пользовательские классы в связывающий адаптер с Dagger, любая помощь приветствуется
Вот мои классы кинжала, это то же самое из учебника, который я упоминал выше
Класс ImageBindingAdapter
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
@Module
public class BindingModule {
@Provides
@DataBinding
ImageBindingAdapter provideImageBindingAdapter(Picasso picasso) {
return new ImageBindingAdapter(picasso);
}
}
Класс BindingComponent
@DataBinding
@Component(dependencies = AppComponent.class, modules = BindingModule.class)
public interface BindingComponent extends DataBindingComponent {
}
Класс AppComponent
@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
@Module
public class AppModule {
@Singleton
@Provides
Picasso picasso(Application application, OkHttp3Downloader okHttp3Downloader) {
return new Picasso.Builder(app.getApplicationContext())
.downloader(okHttp3Downloader)
.indicatorsEnabled(true)
.build();
}
....
}
Класс приложения
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;
}
}
Как говорится в сообщении об ошибке, кинжал не смог разрешить зависимость Picasso
. В вашем случае проблема состоит в том, что разные компоненты кинжала могут напрямую использовать только те зависимости, которые помечены аннотацией @Component
объявленной с использованием методов. Чтобы разрешить AppComponent
совместно использовать Picasso
с BindingComponent
вам необходимо изменить компонент приложения следующим образом:
@Singleton
@Component(modules = {AndroidSupportInjectionModule.class, AppModule.class, ...})
public interface AppComponent extends AndroidInjector<MyApp> {
...
Picasso getPicasso();
}
После этого кинжал может правильно разрешить зависимость Picasso
и ошибка должна исчезнуть.
@BindingAdapter должен быть public static void
, см. Документацию Binding Adapters.