Dagger 2 и адаптер привязки данных android: не может быть предоставлен без @inject или @provides

Я использую библиотеку привязки данных Android и Dagger 2. Я хотел использовать DatabingAdapter для отображения моих изображений в RecyclerView. У меня есть экземпляр Picasso, созданный с помощью Dagger, и мне нужно вставить его в созданный мной DatabindingAdapter. Я следовал этому руководству здесь и получаю сообщение об ошибке, что Picasso не может быть предоставлен без аннотированного метода @Inject или @Provides. Вот мой код (классы упрощены, чтобы больше сосредоточиться на этой проблеме, у меня уже работал Пикассо).

AppModule.java

@Module(includes = {AndroidInjectionModule.class, NetworkModule.class, ViewModelModule.class})
public class AppModule {

    @Provides
    @AppScope
    Picasso picasso(App app, OkHttp3Downloader okHttp3Downloader) {
        return new Picasso.Builder(app.getApplicationContext())
                .downloader(okHttp3Downloader)
                .indicatorsEnabled(true)
                .build();
    }
}

BindingModule.java

@Module
public class BindingModule {
    @BindingScope
    @Provides
    ImageBindingAdapter provideImageBindingAdapter(Picasso picasso) {
        return new ImageBindingAdapter(picasso);
    }
}

BindingComponent.java

@BindingScope
@Component(dependencies = AppComponent.class, modules = BindingModule.class)
public interface BindingComponent extends androidx.databinding.DataBindingComponent {
}

AppComponent.java

@AppScope
@Component(modules = {AppModule.class, AndroidSupportInjectionModule.class, ActivityBuildersModule.class})
public interface AppComponent {

    void inject(App app);

    @Component.Builder
    interface Builder {
        @BindsInstance
        Builder application(App application);

        AppComponent build();
    }
}

ImageBindingAdapter.java

public class ImageBindingAdapter {

    private final Picasso picasso;

    public ImageBindingAdapter(Picasso picasso) {
        this.picasso = picasso;
    }

    @BindingAdapter(value = "url")
    public void loadImageUrl(ImageView imageView, String url) {
        if (url != null && !url.trim().isEmpty())
            picasso.load(Constants.ENDPOINT + url).into(imageView);
    }
}

И вот в чем ошибка.

error: [Dagger/MissingBinding] com.squareup.picasso.Picasso cannot be provided without an @Inject constructor or an @Provides-annotated method.
com.squareup.picasso.Picasso is injected at
com.ralphevmanzano.themoviedb.di.modules.BindingModule.provideImageBindingAdapter(picasso)
com.ralphevmanzano.themoviedb.databinding.ImageBindingAdapter is provided at
androidx.databinding.DataBindingComponent.getImageBindingAdapter()

Любая помощь горячо приветствуется.

Почему вы пытаетесь ввести свой BindingAdapter? Привязка данных может автоматически видеть это из файла xml.

p.alexey 26.10.2018 06:14

@ p.alexey, потому что я пытаюсь использовать экземпляр Picasso, который я построил с помощью кинжала в BindingAdapter

Ralph 26.10.2018 06:24

Вы можете просто сделать Picasso.get() вместо picasso внутри ImageBindingAdapter.

p.alexey 26.10.2018 07:07

@ p.alexey Я раньше тоже задавался вопросом, получит ли этот метод экземпляр, созданный в Dagger? Кроме того, это действительно моя проблема, только что попытался использовать инъекцию конструктора в адаптере привязки, и это сработало.

Ralph 26.10.2018 07:41

@ p.alexey Я просто сравнил экземпляры Picasso, зарегистрировав picasso.toString() и Picasso.get().toString(), и они получили разные шестнадцатеричные коды. Когда я проверил исходный код, я обнаружил, что мне нужно установить экземпляр singleton в Picasso, вызвав Picasso.setSingletonInstance(picasso). Теперь использование Picasso.get() возвращает тот же экземпляр, что и внедренный объект picasso, отлично! и спасибо!

Ralph 26.10.2018 07:53
2
5
807
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Вам не хватает аннотации @Inject в вашем классе ImageBindingAdapter

@AppScope
public class ImageBindingAdapter {

    private final Picasso picasso;

    @Inject
    public ImageBindingAdapter(Picasso picasso) {
        this.picasso = picasso;
    }

    @BindingAdapter(value = "url")
    public void loadImageUrl(ImageView imageView, String url) {
        if (url != null && !url.trim().isEmpty())
            picasso.load(Constants.ENDPOINT + url).into(imageView);
    }
}

Добавив @Inject tell dagger, чтобы добавить этот класс в граф, вы можете добавить аннотацию области видимости к своему классу, чтобы указать, в какую область видимости добавляется этот класс.

ps: вы можете удалить свой BindingModuleclass

@Ralph У меня такая же проблема, я уже добавил Inject к конструктору адаптера привязки, но все еще получил ту же ошибку, есть подсказка?

ysfcyln 09.02.2019 14:38

Другие вопросы по теме