我试图学习匕首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) ;
}
当我运行代码时,它会向我显示此错误:
错误:(15,10)错误:com.imennmn.hellodagger2example.MainView不能 提供时不带@ Provide-annotated方法。 com.imennmn.hellodagger2example.MainView注入 com.imennmn.hellodagger2example.presenterInjection.PresenterModule.provideMainPresenter(MAINVIEW) 注入com.imennmn.hellodagger2example.MainPresenter com.imennmn.hellodagger2example.MainActivity.mainPresenter com.imennmn.hellodagger2example.MainActivity注入 com.imennmn.hellodagger2example.simpleInjection.DataComponent.inject(activity)
我的问题是如何通过注入匕首并绑定MainPresenter和MainActivity来提供界面MainView? 任何帮助,将不胜感激 !
答案 0 :(得分:7)
通过以下代码:
MainPresenter provideMainPresenter(MainView mainView) {
return new MainPresenter(mainView);
}
你在告诉匕首:“嘿,每当我要求你注射MainPresenter
时,使用MainView
构建它。
但是匕首投诉,因为你没有具体说明他应该如何建立/获得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();
答案 1 :(得分:1)
您的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);
}
}
答案 2 :(得分:1)
添加带有@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();
}
}