Внедрить ведущего в деятельность через Dagger - PullRequest
0 голосов
/ 13 июня 2018

Я хочу знать, как внедрить Presenter в действие с помощью кода. Ниже приведены подробности

Ниже приводится сообщение об ошибке:

 Error:(12, 46) error: cannot find symbol class DaggerCategoryPresenterComponent
Error:(9, 46) error: cannot find symbol class DaggerNetComponent
Error:(18, 10) error: [Dagger/MissingBinding] com.headytest.android.category_listing.CategoryContract.CategoryPresenter cannot be provided without an @Provides-annotated method.
com.headytest.android.category_listing.CategoryContract.CategoryPresenter is injected at
com.headytest.android.MainActivity.categoryPresenter
com.headytest.android.MainActivity is injected at
com.headytest.android.dagger_component.NetComponent.inject(com.headytest.android.MainActivity)

Ниже приведены модули

  @Module
  public class NetworkModule {

String baseURL;

public NetworkModule(String baseURL) {
    this.baseURL = baseURL;
}

@Provides
@Singleton
Cache provideHttpCache(Application application) {
    int cacheSize = 10 * 1024 * 1024;
    Cache cache = new Cache(application.getCacheDir(), cacheSize);
    return cache;
}

@Provides
@Singleton
Gson provideGson() {
    GsonBuilder gsonBuilder = new GsonBuilder();
    gsonBuilder.setFieldNamingPolicy(FieldNamingPolicy.LOWER_CASE_WITH_UNDERSCORES);
    return gsonBuilder.create();
}

@Provides
@Singleton
OkHttpClient provideOkhttpClient(Cache cache) {
    HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor();
    interceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
    OkHttpClient.Builder client = new OkHttpClient.Builder();
    client.cache(cache);
    client.addInterceptor(interceptor);
    return client.build();
}

@Provides
@Singleton
Retrofit provideRetrofit(Gson gson, OkHttpClient okHttpClient) {
    try {
        return new Retrofit.Builder()
                .addConverterFactory(GsonConverterFactory.create(gson))
                .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
                .baseUrl(baseURL)
                .client(okHttpClient)
                .build();
    } catch (Exception e) {
        e.printStackTrace();
        return new Retrofit.Builder()
                .addConverterFactory(GsonConverterFactory.create(gson))
                .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
                .baseUrl(Constants.BASE_URL)
                .client(okHttpClient)
                .build();
    }
}
}

ApplicationModule

@Module
public class ApplicationModule {

Application application;

public ApplicationModule(Application application) {
    this.application = application;
}

@Provides
@Singleton
Application providesApplication() {
    return application;
}
}

CategoryContractModule

@Module
public class CategoryContractModule {


public CategoryContractModule() {
}

@Provides
@AScope
CategoryContract.CategoryPresenter providesCategoryPresenter(CategoryPresenterImpl categoryPresenter) {
    return (CategoryContract.CategoryPresenter)categoryPresenter;
}
}

Следующие компоненты:

@Singleton
@Component(modules = {ApplicationModule.class, NetworkModule.class})
public interface NetComponent {
void inject(MainActivity activity);
 }

CategoryPresenterComponent:

@AScope
@Component(dependencies = NetComponent.class, modules = 
{CategoryContractModule.class})
public interface CategoryPresenterComponent {
 void inject(MainActivity activity);
 }

AScope

@Scope
@Retention(RetentionPolicy.RUNTIME)
public @interface AScope {
}

Ниже приведен код в MainActivity:

@Inject
CategoryPresenter categoryPresenter;

@Inject
Retrofit retrofit;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
     DaggerCategoryPresenterComponent.builder()
            .categoryContractModule(new CategoryContractModule())
            .netComponent(((App) getApplicationContext()).getNetComponent())
            .build()
            .inject(this);
}

CategoryPresenterImpl

    public class CategoryPresenterImpl implements CategoryContract.CategoryPresenter {

    @Inject
    public CategoryPresenterImpl() {
    }

    @Override
    public void onStart() {

    }

    @Override
    public void onStop() {

    }

    @Override
    public void getCategoryLiast() {


    }
}

1 Ответ

0 голосов
/ 14 июня 2018

Я предполагаю, что текущую ошибку будет легко исправить, потому что она очень похожа на эту проблему.

Вы указали Dagger, как предоставить @AScope CategoryContract.CategoryPresenter, но в активности, которую вы запрашиваетеКинжал для введения CategoryContract.CategoryPresenter.Кинжал в замешательстве, потому что эти две вещи не совпадают.

Вам нужно просто добавить @AScope к categoryPresenter:

@Inject
@AScope
CategoryPresenter categoryPresenter;

Я проверил ваш проект .Проблема была в NetComponent.java:

@Singleton
@Component(modules = {ApplicationModule.class, NetworkModule.class})
public interface NetComponent {
    void inject(MainActivity activity);
}

Проблема в строке void inject(MainActivity activity).Почему это проблема?Поскольку к тому времени, когда вы создаете NetComponent в App, кинжал анализирует MainActivity для @Inject аннотированного поля и видит CategoryPresenter.Это означает, что в этот момент Dagger должен найти подходящий метод провайдера / связывателя, чтобы иметь возможность внедрить MainActivity, как объявлено внутри этого интерфейса.

Но он не может найти такой метод провайдера / связывателя, потому что онобъявлен в другом компоненте - CategoryPresenterComponent, и этот компонент (NetComponent) так или иначе не связан с CategoryPresenterComponent (подкомпонентами или зависимостями компонентов), поэтому привязки не отображаются.

Простое удаление этой строки приведет ксделайте вашу сборку успешной:

@Singleton
@Component(modules = {ApplicationModule.class, NetworkModule.class})
public interface NetComponent {
}

Для устранения «Ошибка: невозможно получить доступ к Nullable» см. этот поток , который предлагает применить compile 'com.google.code.findbugs:jsr305:3.0.2' кВаш файл Gradle.

После этого вы преодолеете это сообщение об ошибке и наткнетесь на retrofit2.Retrofit cannot be provided without an @Inject constructor or an @Provides-annotated method, который имеет те же симптомы, что и CategoryPresenter.

Чтобы преодолеть эту проблему, вынеобходимо добавить метод Retrofit провайдера внутри NetComponent (или удалить @Inject Retrofit retrofit из активности):

@Singleton
@Component(modules = {ApplicationModule.class, NetworkModule.class})
public interface NetComponent {
    Retrofit providesRetrofit();
}

После этого вы сможете запустить приложение, но выв итоге яНа NPE в MainActivity, из-за этой строки:

.categoryContractModule(new CategoryContractModule(retrofit.create(HeadyAPI.class)))

Вы имеете в виду объект retrofit, который еще не инициализирован.

Короче говоря, ваш первоначальный вопрос имеетмутировал пару раз, и на самом деле у вас было несколько проблем в вашем коде.Тем не менее, у вас есть проблема, потому что вы пытаетесь использовать retrofit для создания компонента, который должен был ввести retrofit для вас.

...