匕首2 - 项目重建错误 - 字段注入 - 安卓



我一直在尝试实现Dagger2。

问题:当我使用构造函数注入时,它工作正常,但是当我使用字段注入时,它会抛出如下所示的错误:

Error:(6, 48) error: cannot find symbol class DaggerApplicationComponent
/home/moderator/Downloads/Maulik/Sample Codes/Made/Dagger2Demo/app/src/main/java/com/dagger2demo/dagger2demo/di/component/ApplicationComponent.java
Error:(18, 10) error: com.dagger2demo.dagger2demo.mvp.HomePresenter cannot be provided without an @Inject constructor or from an @Provides- or @Produces-annotated method. This type supports members injection but cannot be implicitly provided.
com.dagger2demo.dagger2demo.mvp.HomePresenter is injected at
com.dagger2demo.dagger2demo.mvp.BaseActivity.homePresenter
com.dagger2demo.dagger2demo.mvp.BaseActivity is injected at
com.dagger2demo.dagger2demo.di.component.ApplicationComponent.inject(baseActivity)
Error:Execution failed for task ':app:compileDebugJavaWithJavac'.
> Compilation failed; see the compiler error output for details.

Dagger2 - 我的理解:你必须创建一个模块类,你将在其中创建方法。这些方法将为您提供所需类的相应对象,如Retrofit,ApplicationContext等。您将创建一个组件接口,您将在其中定义在何处注入模块类的依赖项。

我正在使用:Retrofit,RxJava - RaxAndroid,Dagger2和MVP。

代码如下:

build.gradle(app)

// Retrofit Dependency
compile 'com.squareup.retrofit2:retrofit:2.3.0'
// Gson Converter Factory Dependency
compile 'com.squareup.retrofit2:converter-gson:2.3.0'
// RxJava2 Adapter Dependency for Retrofit2
compile 'com.squareup.retrofit2:adapter-rxjava2:2.3.0'
// ButterKnife Dependencies
compile 'com.jakewharton:butterknife:8.8.1'
annotationProcessor 'com.jakewharton:butterknife-compiler:8.8.1'
// RxJava & RxAndroid Dependencies
compile group: 'io.reactivex.rxjava2', name: 'rxjava', version: '2.1.8'
compile group: 'io.reactivex.rxjava2', name: 'rxandroid', version: '2.0.1'
// Dagger2 Dependency
compile 'com.google.dagger:dagger:2.14.1'
annotationProcessor 'com.google.dagger:dagger-compiler:2.14.1'

dagger2演示应用程序.java

public class Dagger2DemoApplication extends Application {
private ApplicationComponent mApplicationComponent;
@Override
public void onCreate() {
super.onCreate();
mApplicationComponent = DaggerApplicationComponent.builder()
.applicationModule(new ApplicationModule())
.build();
}
public ApplicationComponent getmApplicationComponent() {
return mApplicationComponent;
}
}

应用模块.java

@Module
public class ApplicationModule {
@Provides
@Singleton
public APIEndPoints provideAPIEndPoints() {
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("https://reqres.in/")
.addConverterFactory(GsonConverterFactory.create())
.addCallAdapterFactory(RxJava2CallAdapterFactory.create())
.build();
APIEndPoints apiEndPoints = retrofit.create(APIEndPoints.class);
return apiEndPoints;
}
}

应用程序组件.java

@Singleton
@Component(modules = {ApplicationModule.class})
public interface ApplicationComponent {
void inject(BaseActivity baseActivity);
}

基本活动.java

public class BaseActivity extends AppCompatActivity {
// Variables
public ProgressDialog mProgressDialog;
@Inject
HomePresenter homePresenter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// For Dagger2 i.e Creating instance of all provide methods defined in ApplicationModule
((Dagger2DemoApplication) getApplication()).getmApplicationComponent().inject(this);
setupProgressBar();
}
private void setupProgressBar() {
mProgressDialog = new ProgressDialog(this);
mProgressDialog.setTitle(getString(R.string.str_progress_dialog_title));
mProgressDialog.setMessage(getString(R.string.str_progress_dialog_desc));
mProgressDialog.setCancelable(false);
}
}

基本视图.java

public interface BaseView extends View {
void handleResponse(Object obj);
void showMessage(String msg);
}

查看.java

public interface View {
}

基本演示者.java

public interface BasePresenter {
void attachView(View view);
void callAPI();
}

主页主讲人.java

public class HomePresenter implements BasePresenter {
private BaseView mBaseView;
@Inject
APIEndPoints mApiEndPoints;
/*@Inject
public HomePresenter(APIEndPoints apiEndPoints) {
this.mApiEndPoints = apiEndPoints;
}*/
@Override
public void attachView(View view) {
mBaseView = (BaseView) view;
}
@Override
public void callAPI() {
// Actually calling API here with observable object - Start
Observable<Users> usersObservable = mApiEndPoints.getUsers();
usersObservable
.subscribeOn(Schedulers.newThread())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(this::onSuccess, this::onError);
// Actually calling API here with observable object - End
}
private void onSuccess(Users users) {
mBaseView.handleResponse(users);
}
private void onError(Throwable throwable) {
mBaseView.showMessage(throwable.toString());
}
}

家活动.java

public class HomeActivity extends BaseActivity implements BaseView {
// Widgets
@BindView(R.id.rv_users)
RecyclerView rv_users;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// For ButterKnife
ButterKnife.bind(this);
// Initializing Presenter
homePresenter.attachView(this);
}
public void getDataFromServer(View view) {
mProgressDialog.show();
homePresenter.callAPI();
}
// BaseView Methods
@Override
public void handleResponse(Object obj) {
Users users;
if (obj instanceof Users) {
users = (Users) obj;
if (users != null) {
mProgressDialog.dismiss();
rv_users.setLayoutManager(new LinearLayoutManager(HomeActivity.this));
rv_users.setAdapter(new RVAdapter(users.getData()));
}
}
}
@Override
public void showMessage(String msg) {
if (msg != null) {
mProgressDialog.dismiss();
Toast.makeText(this, msg, Toast.LENGTH_SHORT).show();
}
}
}

如您所见,我在HomePresenter中评论了构造函数注入。我在那里进行现场注射。但是我无法构建项目,因为我遇到了如上所述的错误。

任何帮助将不胜感激。如果需要与代码相关的任何其他内容,请告诉我。

提前谢谢。

编辑:PS:我知道答案,但我只是不明白为什么场注入,即@Inject APIEndPoints mApiEndPoints;在家庭演示器中不起作用。请有人解释我。

如您所见,我在HomePresenter中评论了构造函数注入。我在那里进行现场注射。

如果您使用构造函数注入,那么 Dagger 将为您创建对象并了解它的所有信息。

如果你使用场注入,那么你必须创建对象告诉Dagger。

我不明白为什么您更喜欢在这种情况下使用字段注入,但是对于字段注入,您需要向其中一个模块添加@Provides注释方法,以使 Dagger 可以访问您的演示者。

您需要在模块中使用 Construcotr 注入或@Provides注释的方法,就像错误状态一样。

您混淆了依赖项生产者机制和依赖项使用机制。带批注的字段用于使用依赖项。在你的情况下,@Inject HomePresenter homePresenter告诉dagger"嘿,我希望你在这里注射一个HomePresenter"。为此,Dagger 需要您定义一个@Provides方法,或者使用@Inject注释对象构造函数。

根据经验,请始终使用带批注@Inject构造函数来提供依赖项。仅当提供的对象是以下对象时@Provides才应使用方法提供程序:

  • 一个interface
  • abstract
  • 来自外部库的对象(您无权访问构造函数)
  • 在提供之前需要自定义的对象

在您的情况下,您遇到了错误,因为您没有@Provides注释的方法,也没有@Inject注释的构造函数。您应该取消注释您的构造函数,因为这是您情况中要走的路。

最新更新