通过Dagger将主持人注入活动 [英] Inject presenter into activity via Dagger

查看:59
本文介绍了通过Dagger将主持人注入活动的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想知道如何使用代码在活动中注入Presenter,以下是详细信息

I want to know how to inject Presenter in activity using code Following are details

以下是错误消息:

 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

CategoryPresenterImpl

    public class CategoryPresenterImpl implements CategoryContract.CategoryPresenter {

    @Inject
    public CategoryPresenterImpl() {
    }

    @Override
    public void onStart() {

    }

    @Override
    public void onStop() {

    }

    @Override
    public void getCategoryLiast() {


    }
}


推荐答案

我认为当前错误很容易解决,因为它看起来很像问题。

I assume current error will be easy to fix, because it very much looks like this issue.

您已指示Dagger如何提供 @AScope CategoryContract.CategoryPresenter ,但在活动中,您要求Dagger注入 CategoryContract.CategoryPresenter 。此时Dagger感到困惑,因为这两个东西不匹配。

You've instructed Dagger how to provide @AScope CategoryContract.CategoryPresenter but in activity you request Dagger to inject CategoryContract.CategoryPresenter. Dagger is confused at this point, because those two things do not match.

您要做的只是添加 @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活动)。为什么这是一个问题?因为到了您在NetComponent 的时候com / headytest / android / App.java rel = nofollow noreferrer> App ,匕首分析 MainActivity for @Inject 带注释的字段,并看到 CategoryPresenter 。这意味着,在这一点上,Dagger应该找到适当的provider / binder方法,以便能够像在此接口内声明的那样注入 MainActivity

The issue is in line void inject(MainActivity activity). Why is this an issue? Because by the time you construct NetComponent in App, dagger analyzes MainActivity for @Inject annotated field and sees CategoryPresenter. This means, that at this point Dagger should find appropriate provider/binder method in order to be able to inject MainActivity as declared inside this interface.

但是它找不到这样的提供者/绑定器方法,因为它是在另一个组件中声明的- CategoryPresenterComponent 和该组件( NetComponent )始终未与 CategoryPresenterComponent 连接(子组件或组件依赖性),因此不公开绑定。

But it cannot find such a provider/binder method, because it is declared in an another component - CategoryPresenterComponent and this component (NetComponent) is not connected with CategoryPresenterComponent anyhow (subcomponents or component dependencies), thus bindings are not exposed.

只需删除该行即可使您的构建成功:

Simply removing that line will make your build successful:

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






要解决错误:无法访问可为空 ,请参考线程,建议应用 compile'c​​om.google.code.findb ugs:jsr305:3.0.2'到gradle文件中。


For resolving "Error:cannot access Nullable" refer to this thread, which suggest applying compile 'com.google.code.findbugs:jsr305:3.0.2' to your gradle file.

执行完此操作后,您将克服该错误消息,并偶然发现 retrofit2。如果没有@Inject构造函数或@Provides注释方法,则无法提供Retrofit,该方法的症状与 CategoryPresenter

After doing this you'll overcome that error message and will stumble on retrofit2.Retrofit cannot be provided without an @Inject constructor or an @Provides-annotated method, which has the same symptoms as CategoryPresenter had.

要解决此问题,您必须在内添加 Retrofit 提供程序方法NetComponent (或从活动中删除 @Inject Retrofit改造):

To overcome this issue you have to add a Retrofit provider method inside NetComponent (or to remove @Inject Retrofit retrofit from activity):

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

执行此操作后,您将能够运行该应用程序,但是您可以由于以下原因,最终会在 MainActivity 中以NPE结尾:

After doing this you'll be able to run the app, but you'll end up in a NPE in MainActivity, because of this line:

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

retrofit 对象,该对象尚未初始化。

You are referring to retrofit object, which is not yet initialized.

长话短说,您的最初问题已经改变了几次实际上,您的代码中存在一些问题。仍然有一个问题,因为您尝试使用 retrofit 来构造一个组件,该组件应该注入 retrofit 给你。

Long story short, your initial question has mutated a couple of times and in fact you had a few problems in your code. Still you have a problem there, because you are trying to use retrofit in order to construct a component, that was supposed to inject the retrofit for you.

这篇关于通过Dagger将主持人注入活动的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆