java - 通过 Dagger 将 Presenter 注入到活动中
问题描述
我想知道如何使用代码在活动中注入 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);
}
类别PresenterImpl
public class CategoryPresenterImpl implements CategoryContract.CategoryPresenter {
@Inject
public CategoryPresenterImpl() {
}
@Override
public void onStart() {
}
@Override
public void onStop() {
}
@Override
public void getCategoryLiast() {
}
}
解决方案
我认为当前的错误很容易修复,因为它看起来很像这个问题。
您已指示 Dagger 如何提供@AScope CategoryContract.CategoryPresenter
,但在活动中您要求 Dagger 注入CategoryContract.CategoryPresenter
。Dagger在这一点上很困惑,因为这两件事不匹配。
你所要做的,只是添加@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
,dagger 会分析带注释的字段并MainActivity
查看。这意味着,此时 Dagger 应该找到适当的提供者/绑定器方法,以便能够按照在此接口中声明的方式进行注入。@Inject
CategoryPresenter
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();
}
完成此操作后,您将能够运行该应用程序,但MainActivity
由于以下行,您最终会进入 NPE in :
.categoryContractModule(new CategoryContractModule(retrofit.create(HeadyAPI.class)))
您指的retrofit
是尚未初始化的对象。
长话短说,您最初的问题已经发生了几次变异,实际上您的代码中存在一些问题。你仍然有一个问题,因为你试图使用retrofit
它来构建一个组件,它应该retrofit
为你注入。
推荐阅读
- curl - Unable to read resources via K8s API
- c# - 出现表单错误时不显示 ASP.NET MVC 验证摘要
- dart - 对函数参数使用扩展运算符
- reactjs - NextJS - 经过身份验证和未经身份验证的用户的静态页面
- java - 运行“java”时出错:在 android studio 中找不到默认活动
- css - Material UI 中的 GridListTile 项目未对齐
- c# - 具有已知指纹的 Renci.SshNet 预接受密钥
- java - CAS的高可用配置
- r - 从矩阵创建 R 中的直方图
- postgresql - Jpql:没有分组依据