如何使用Dagger2在片段中注入Presenter

时间:2017-09-26 10:44:42

标签: android android-fragments dependency-injection dagger-2 dagger

如何使用Dagger2

在片段中注入Presenter

我写了以下代码

@Module
public abstract class ActivityBuilder {

    @ContributesAndroidInjector(modules = { DetailCastActivityModule.class, FragmentDependencyProvider.class })
    abstract DetailCastActivity bindDetailCastActivity();
}

@Module
public abstract class FragmentDependencyProvider {

    @ContributesAndroidInjector(modules = CastInfoFragmentModule.class)
    abstract CastInfoFragment provideCastInfoFragmentFactory();
}

@Module
public class CastInfoFragmentModule {

    @Provides
    CastInfoMvpPresenter<CastInfoMvpView> provideCastInfoMvpPresenter(CastInfoPresenter<CastInfoMvpView> presenter) {
        return presenter;
    }

}

但即使我写了提供方法

,我仍然会低于错误
Error:(24, :sunglasses: error: [dagger.android.AndroidInjector.inject(T)] com.app.nmot.ui.castdetail.info.CastInfoPresenter cannot be provided without an @Provides- or @Produces-annotated method.
com.app.nmot.ui.castdetail.info.CastInfoPresenter is injected at
com.app.nmot.ui.castdetail.info.CastInfoFragment.presenter
com.app.nmot.ui.castdetail.info.CastInfoFragment is injected at
dagger.android.AndroidInjector.inject(arg0)

评论中提到的答案并没有解决我的问题。 我已经检查了所有的注释,我正在使用Dagger2提供的新的android注入器

2 个答案:

答案 0 :(得分:2)

1-创建范围

import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;

import javax.inject.Scope;

@Scope
@Retention(RetentionPolicy.RUNTIME)
public @interface BaseScope {
}

2-创建合同

public interface FeatureContract {
   interface View {
        void onReceiveError(Throwable throwable);
        void onReceiveItems(List<Object> items);
        void showAlertDialog();
        ... //others methods
    }

    interface Presenter {
        void onInitView(Object item);
    }
}

3-创建模块(dagger2)

import dagger.Module;
import dagger.Provides;

@Module
public class FeatureContractModule {

    private final FeatureContract.View mView;

    public FeatureContractModule(FeatureContract.View view) {
        mView = view;
    }

    @Provides @BaseScope
    FeatureContract.Presenter providesFeaturePresenter(FeatureContract.View view) {
        return new FeaturePresenter(view);
    }

    @Provides @BaseScope
    FeatureContract.View providesFeatureView() {
        return mView;
    }
}

4-创建演示者

public class FeaturePresenter implements FeatureContract.Presenter{

   @NonNull
   private final FeatureContract.View mView;

   public FeaturePresenter(@NonNull FeatureContract.View view){
      mView = view;
   }

   @Override
   public void onInitView(Object item){
      mView.showAlertDialog(); //<--for sample
   }
}

5-在你的片段中

import javax.inject.Inject;

public class FeatureFragment extends Fragment implements FeatureContract.View{
@Inject FeatureContract.Presenter mPresenter;

@Override public void onActivityCreated(@Nullable Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);
        ((MyApplication) getActivity().getApplication()).getDataComponent()
                                                                 .plus(new FeatureContractModule(this /*view*/))
                                                                 .inject(this /*fragment*/);

        mPresenter. onInitView(null);
    }
}

5-您的申请

public class MyApplication extends Application {
    //Dagger object
    private DataComponent mDataComponent;

    /**
     * Dagger Injector
     */
    public static DataComponent get(Context context) {
        MyApplication application = (MyApplication) context.getApplicationContext();
        return application.mDataComponent;
    }

    @Override
    public void onCreate() {
    super.onCreate();
    mDataComponent = DaggerDataComponent.builder()
                                        .dataModule(new DataModule(this, Locale.getDefault()))
                                        .build();
    }
    public DataComponent getDataComponent() {
        return mDataComponent;
    }   
}

6 - 创建DataComponent

import javax.inject.Singleton;

import dagger.Component;

@Singleton
@Component(modules = {DataModule.class})
public interface DataComponent {
Application application();
FeatureComponent plus(FeatureContractModule module);
...
}

7 - 最后是你的ComponentModule

import dagger.Module;
import dagger.Provides;

@BaseScope
@Subcomponent(modules = FeatureContractModule.class)
public interface FeatureComponent {
    void inject(FeatureFragment fragment);
}

我相信我没有忘记任何事情

答案 1 :(得分:0)

制作CastInfoFragmentModule摘要并添加:

@YourScope
@Binds
abstract CastInfoMvpPresenter<CastInfoMvpView> bindPresenter(CastInfoPresenter<CastInfoMvpView> presenter);

此外,您必须在@Inject

的构造函数上添加CastInfoPresenter