Dagger2 - 项目重建错误 - 现场注入 - Android [英] Dagger2 - Project Rebuild Error - Field Injection - Android

查看:964
本文介绍了Dagger2 - 项目重建错误 - 现场注入 - Android的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一直在尝试实现Dagger2。

I have been trying to implement Dagger2.

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

Problem: When I use constructor injection, it works fine but when I use field injection, it throws an Error like below:

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 - 我的理解:你必须在那里创建一个Module类将创建方法。这些方法将为您提供所需类的相应对象,如Retrofit,ApplicationContext等。您将创建一个组件接口,您将在其中定义注入模块类依赖项的位置。

Dagger2 - My Understanding: You have to create a Module class where you will create methods. These methods will give you respective object of your needed class like Retrofit, ApplicationContext etc.. You will create an component interface in which you will define where to inject module class's dependencies.

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

I'm using: 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'

Dagger2DemoApplication.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;
    }
}

ApplicationModule.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;
    }
}

ApplicationComponent.java

    @Singleton
@Component(modules = {ApplicationModule.class})
public interface ApplicationComponent {

    void inject(BaseActivity 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);
    }
}

BaseView.java

    public interface BaseView extends View {

    void handleResponse(Object obj);

    void showMessage(String msg);
}

View.java

    public interface View {

}

BasePresenter.java

public interface BasePresenter {

    void attachView(View view);

    void callAPI();
}

HomePresenter.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());
    }
}

HomeActivity.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中的构造函数注入。我在那里进行了Field Injection。但是我无法构建项目,因为我收到了如上所述的错误。

As you can see I commented Constructor Injection in HomePresenter. I'm having Field Injection there instead. But I'm not able to build the project as I'm getting error like mentioned above.

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

Any help will be appreciated. Let me know if any other things related to code is required.

提前致谢。

编辑:
PS:我知道答案,但我无法理解为什么Field Injection即 @Inject
APIEndPoints mApiEndPoints;
在HomePresenter中不起作用。请有人解释一下。

PS: I know the answer but I just can't understand why Field Injection i.e @Inject APIEndPoints mApiEndPoints; is not working in HomePresenter. Please someone explain me.

推荐答案


如您所见,我在HomePresenter中评论了构造函数注入。我在那里有Field Injection。

As you can see I commented Constructor Injection in HomePresenter. I'm having Field Injection there instead.

如果你使用Constructor Injection,那么Dagger将为你创建对象并了解所有相关内容。

If you use Constructor Injection, then Dagger will create the object for you and know all about it.

如果您使用字段注入,那么必须创建对象告诉Dagger这件事。

If you use field injection then you have to create the object and tell Dagger about it.

我不明白为什么你更喜欢在这种情况下使用现场注入,但是通过现场注入你需要添加一个 @Provides 为您的某个模块添加注释方法,让Dagger可以访问您的演示者。

I don't see why you would prefer to use field injection in this case, but with field injection you need to add a @Provides annotated method to one of your modules to give Dagger access to your presenter.

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

You need to use either Construcotr injection, or a @Provides annotated methods in your module, just as the error states.

这篇关于Dagger2 - 项目重建错误 - 现场注入 - Android的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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