Dagger 2:在构造函数中注入接口
Dagger 2: inject an interface in a constructor
我正在尝试学习 dagger 2,但我对使用接口注入构造函数感到困惑。这是我的以下代码:
MainActivity.java
public class MainActivity extends AppCompatActivity implements MainView {
// this keyword of request dependency . At compiling process, dagger will look at all of these annotations
//to create the exact dependency
@Inject MainPresenter mainPresenter ;
TextView textView ;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
textView = findViewById(R.id.textview) ;
DaggerPresenterComponent.create().inject(this);
textView.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View view) {
mainPresenter.doThings(8555) ;
}
});
}
/**********************************/
@Override
public void invokeRandomViewMethod(String msg) {
textView.setText(msg);
}
}
MainPresenter.java
public class MainPresenter {
private MainView mainView ;
@Inject
public MainPresenter(MainView mainView) {
this.mainView = mainView;
}
public void doThings(int value){
Random random = new Random();
int rand= random.nextInt(value) ;
if(mainView != null){
mainView.invokeRandomViewMethod("You random number is "+rand);
}
}
public interface MainView {
void invokeRandomViewMethod(String msg) ;
}
}
这是模块:
@Module
public class PresenterModule {
@Provides
// this is the method that will provide the dependancy
MainPresenter provideMainPresenter(MainView mainView){
return new MainPresenter(mainView);
}
}
这是 组件
@Component (modules = PresenterModule.class)
public interface PresenterComponent {
void inject(MainActivity activity) ;
}
当我 运行 代码时,它向我显示此错误:
Error:(15, 10) error: com.imennmn.hellodagger2example.MainView cannot
be provided without an @Provides-annotated method.
com.imennmn.hellodagger2example.MainView is injected at
com.imennmn.hellodagger2example.presenterInjection.PresenterModule.provideMainPresenter(mainView)
com.imennmn.hellodagger2example.MainPresenter is injected at
com.imennmn.hellodagger2example.MainActivity.mainPresenter
com.imennmn.hellodagger2example.MainActivity is injected at
com.imennmn.hellodagger2example.simpleInjection.DataComponent.inject(activity)
我的问题是如何通过注入 Dagger 并绑定 MainPresenter 和 MainActivity 来提供接口 MainView ?
任何帮助,将不胜感激 !
您的 provideMainPresenter
隐含地依赖于 MainView
。匕首没有办法得到它。您需要添加一个方法来提供它:
@Module
public class PresenterModule {
@Provides
MainView provideMainView(){
// Provide MainView here somehow so Dagger can use this to create a MainPresenter
}
@Provides
// this is the method that will provide the dependancy
MainPresenter provideMainPresenter(MainView mainView){
return new MainPresenter(mainView);
}
}
通过以下代码:
MainPresenter provideMainPresenter(MainView mainView) {
return new MainPresenter(mainView);
}
你在告诉匕首:"hey, whenever I ask you to inject MainPresenter
, construct it using MainView
"。
但是匕首投诉,因为你还没有具体说明他应该如何 build/acquire MainView
.
因此,在您的 PresenterModule
中执行此操作:
@Module
public class PresenterModule {
MainView mainView;
public PresenterModule(MainView mainView) {
this.mainView = mainView;
}
@Provides
MainPresenter provideMainPresenter() {
return new MainPresenter(mainView);
}
}
然后在构建组件时:
DaggerPresenterComponent.builder()
.presenterModule(new PresenterModule(this))
.build();
添加带有@Binds
注解的抽象模块,看我的实现:AbstractTestSettingsFragmentModule.java
TestFragment.java
public class TestFragment extends Fragment{
@Inject TestFragmentContract.Presenter mPresenter;
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
AndroidSupportInjection.inject(this);
}
}
TestFragmentPresenterImpl.java
public class TestFragmentPresenterImpl implements TestFragmentContract.Presenter {
@Inject
public TestFragmentPresenterImpl(){
}
}
AbstractTestSettingsFragmentModule.java
@Module
public abstract class AbstractTestSettingsFragmentModule {
@Binds
@NonNull
public abstract TestSettingsFragmentContract.Presenter testSettingsFragmentPresenterImpl(TestSettingsFragmentImpl presenter);
}
ContributesModule.java
@Module
public abstract class ContributesModule {
@ContributesAndroidInjector(modules = {AbstractTestSettingsFragmentModule.class})
abstract TestSettingsFragment testSettingsFragment();
}
AppComponent.java
@Singleton
@Component(
modules = {
AndroidSupportInjectionModule.class,
ContributesModule.class,
AppModule.class,
})
public interface AppComponent extends AndroidInjector<DaggerApplication> {
void inject(TheApplication theApplication);
@Override
void inject(DaggerApplication instance);
@Component.Builder
interface Builder {
@BindsInstance
Builder application(Application application);
AppComponent build();
}
}
我正在尝试学习 dagger 2,但我对使用接口注入构造函数感到困惑。这是我的以下代码:
MainActivity.java
public class MainActivity extends AppCompatActivity implements MainView {
// this keyword of request dependency . At compiling process, dagger will look at all of these annotations
//to create the exact dependency
@Inject MainPresenter mainPresenter ;
TextView textView ;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
textView = findViewById(R.id.textview) ;
DaggerPresenterComponent.create().inject(this);
textView.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View view) {
mainPresenter.doThings(8555) ;
}
});
}
/**********************************/
@Override
public void invokeRandomViewMethod(String msg) {
textView.setText(msg);
}
}
MainPresenter.java
public class MainPresenter {
private MainView mainView ;
@Inject
public MainPresenter(MainView mainView) {
this.mainView = mainView;
}
public void doThings(int value){
Random random = new Random();
int rand= random.nextInt(value) ;
if(mainView != null){
mainView.invokeRandomViewMethod("You random number is "+rand);
}
}
public interface MainView {
void invokeRandomViewMethod(String msg) ;
}
}
这是模块:
@Module
public class PresenterModule {
@Provides
// this is the method that will provide the dependancy
MainPresenter provideMainPresenter(MainView mainView){
return new MainPresenter(mainView);
}
}
这是 组件
@Component (modules = PresenterModule.class)
public interface PresenterComponent {
void inject(MainActivity activity) ;
}
当我 运行 代码时,它向我显示此错误:
Error:(15, 10) error: com.imennmn.hellodagger2example.MainView cannot be provided without an @Provides-annotated method. com.imennmn.hellodagger2example.MainView is injected at com.imennmn.hellodagger2example.presenterInjection.PresenterModule.provideMainPresenter(mainView) com.imennmn.hellodagger2example.MainPresenter is injected at com.imennmn.hellodagger2example.MainActivity.mainPresenter com.imennmn.hellodagger2example.MainActivity is injected at com.imennmn.hellodagger2example.simpleInjection.DataComponent.inject(activity)
我的问题是如何通过注入 Dagger 并绑定 MainPresenter 和 MainActivity 来提供接口 MainView ? 任何帮助,将不胜感激 !
您的 provideMainPresenter
隐含地依赖于 MainView
。匕首没有办法得到它。您需要添加一个方法来提供它:
@Module
public class PresenterModule {
@Provides
MainView provideMainView(){
// Provide MainView here somehow so Dagger can use this to create a MainPresenter
}
@Provides
// this is the method that will provide the dependancy
MainPresenter provideMainPresenter(MainView mainView){
return new MainPresenter(mainView);
}
}
通过以下代码:
MainPresenter provideMainPresenter(MainView mainView) {
return new MainPresenter(mainView);
}
你在告诉匕首:"hey, whenever I ask you to inject MainPresenter
, construct it using MainView
"。
但是匕首投诉,因为你还没有具体说明他应该如何 build/acquire MainView
.
因此,在您的 PresenterModule
中执行此操作:
@Module
public class PresenterModule {
MainView mainView;
public PresenterModule(MainView mainView) {
this.mainView = mainView;
}
@Provides
MainPresenter provideMainPresenter() {
return new MainPresenter(mainView);
}
}
然后在构建组件时:
DaggerPresenterComponent.builder()
.presenterModule(new PresenterModule(this))
.build();
添加带有@Binds
注解的抽象模块,看我的实现:AbstractTestSettingsFragmentModule.java
TestFragment.java
public class TestFragment extends Fragment{
@Inject TestFragmentContract.Presenter mPresenter;
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
AndroidSupportInjection.inject(this);
}
}
TestFragmentPresenterImpl.java
public class TestFragmentPresenterImpl implements TestFragmentContract.Presenter {
@Inject
public TestFragmentPresenterImpl(){
}
}
AbstractTestSettingsFragmentModule.java
@Module
public abstract class AbstractTestSettingsFragmentModule {
@Binds
@NonNull
public abstract TestSettingsFragmentContract.Presenter testSettingsFragmentPresenterImpl(TestSettingsFragmentImpl presenter);
}
ContributesModule.java
@Module
public abstract class ContributesModule {
@ContributesAndroidInjector(modules = {AbstractTestSettingsFragmentModule.class})
abstract TestSettingsFragment testSettingsFragment();
}
AppComponent.java
@Singleton
@Component(
modules = {
AndroidSupportInjectionModule.class,
ContributesModule.class,
AppModule.class,
})
public interface AppComponent extends AndroidInjector<DaggerApplication> {
void inject(TheApplication theApplication);
@Override
void inject(DaggerApplication instance);
@Component.Builder
interface Builder {
@BindsInstance
Builder application(Application application);
AppComponent build();
}
}