[英]Dagger2 - Project Rebuild Error - Field Injection - Android
我一直在嘗試實現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等。您將創建一個組件接口,在其中定義將模塊類的依賴項注入到哪里。
我正在使用:翻新,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中評論了構造函數注入。 我在那邊有場注入。 但是由於出現如上所述的錯誤,所以我無法構建項目。
任何幫助將不勝感激。 讓我知道是否需要其他與代碼相關的東西。
提前致謝。
編輯: PS:我知道答案,但我只是不明白為什么字段注入即@Inject APIEndPoints mApiEndPoints; 在HomePresenter中不起作用。 請有人給我解釋。
如您所見,我在HomePresenter中評論了構造函數注入。 我在那邊有場注入。
如果使用構造函數注入,然后匕首會為你創建對象,什么都知道。
如果你使用字段注入,那么你必須創建對象,並告訴匕首了。
我不明白為什么在這種情況下您更喜歡使用字段注入,但是使用字段注入時,您需要向模塊之一添加帶@Provides
注釋的方法,以使Dagger可以訪問演示者。
與錯誤狀態一樣,您需要在模塊中使用Construcotr注入或@Provides
注釋的方法。
您正在混淆依賴關系生成器機制和依賴關系消耗機制。 帶注釋的字段用於消耗依賴項。 在您的情況下, @Inject HomePresenter homePresenter
告訴Dagger“嘿,我希望您在此處注入HomePresenter”。 為此,Dagger需要您定義一個@Provides
方法或使用@Inject
注釋對象構造函數。
根據經驗,請始終使用@Inject
批注的構造函數來提供依賴關系。 僅當您提供的對象是@Provides
一種時,才應使用@Provides
方法提供程序:
interface
abstract
類 在您的情況下,由於沒有@Provides
注釋方法或@Inject
注釋構造函數,因此出現錯誤。 您應該取消對構造函數的注釋,因為這是您遇到的情況的處理方法。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.