1

我有我想注入片段的 RegisterPresenterImpl 。当我调用该演示者的方法 register() 时,我的应用程序崩溃。它说我的演示者为空。

我该如何解决这个问题?

public class RegisterAccountFragment extends Fragment implements RegisterAccountView {


@Inject
RegisterAccountPresenterImpl registerPresenter;

public RegisterAccountFragment() {
    // Required empty public constructor
}


@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {
    // Inflate the layout for this fragment
    View v =  inflater.inflate(R.layout.fragment_register_account, container, false);

 DaggerRegisterAccountComponent.builder()
            .netComponent(((App) getActivity().getApplicationContext()).getNetComponent())
            .registerAccountModule(new RegisterAccountModule(this))
            .build()
            .inject(this);

   registerPresenter.register(getName(), getEmail(), getPassword(), getConfirm());
     } 
}

组件接口:

 @FragmentScoped
 @Component(dependencies = NetComponent.class, modules =  RegisterAccountModule.class)
  public interface RegisterAccountComponent {
       void inject(RegisterAccountFragment fragment);
}

这是模块类:

@Module
public class RegisterAccountModule {

private RegisterAccountView view;

public RegisterAccountModule(RegisterAccountView view){
    this.view = view;
}


@Provides
@FragmentScoped
RegisterAccountView providesRegisterAccountView(){
    return view;
   }
}

这是一个名为 RegisterPresenterImpl 的类

 public class RegisterAccountPresenterImpl implements RegisterAccountPresenter{

private RegisterAccountView view;
private Retrofit retrofit;
private CompositeDisposable compositeDisposable = new CompositeDisposable();

@Inject
public RegisterAccountPresenterImpl(Retrofit retrofit, RegisterAccountView view){
    this.retrofit = retrofit;
    this.view = view;
}

@Override
public void register(String name, String email, String password, String confirm) {
    // CODE
    }
}
4

2 回答 2

3

提供您RegisterAccountPresenterImplRegisterAccountComponent

它应该是这样的:

@FragmentScoped
@Component(dependencies = NetComponent.class, modules =  
RegisterAccountModule.class)
public interface RegisterAccountComponent {
   void inject(RegisterAccountFragment fragment);

   RegisterAccountPresenterImpl getRegisterAccountPresenterImlp();
}

您的实施有一些问题

  1. Inject Constructor/Field/Method还不支持public。删除那个多余的关键字
  2. 初始化您的DaggerRegisterAccountComponentinonCreate()而不是onCreateView()确保在使用任何依赖项之前构建它。
  3. 考虑使用在构造函数中设置的final所有内容。因为它只会初始化一次。fieldRegisterAccountPresenterImpl
private final RegisterAccountView view;

private final Retrofit retrofit;
  1. 我只是不明白为什么你必须在 a 中定义 a view(这是你的片段)presenter,反之亦然。这是循环依赖吗?

我发现本教程是关于使用 MVP 和 Dagger 的超酷帖子。请考虑阅读

还有一件事:如果你想有效地调试 Dagger-2,去你的Dagger...Component班级看看里面有什么。Android Studio 将帮助您在使用时发现任何问题。

希望这有帮助!

于 2017-07-29T17:01:35.877 回答
2

应该

public class RegisterAccountFragment extends Fragment implements RegisterAccountView {       
    @Inject
    RegisterAccountPresenter registerPresenter; // <-- not impl, why use DI then?

@FragmentScoped // <-- scope here
public class RegisterAccountPresenterImpl implements RegisterAccountPresenter{

    private final RegisterAccountView view;
    private final Retrofit retrofit;

    @Inject
    public RegisterAccountPresenterImpl(Retrofit retrofit, RegisterAccountView view){
        this.retrofit = retrofit;
        this.view = view;
    }
}

@Module
public class RegisterAccountModule {

    private RegisterAccountView view;

    public RegisterAccountModule(RegisterAccountView view){
        this.view = view;
    }

    @Provides
    // @FragmentScoped // <-- no need for scoping item in module
    RegisterAccountView providesRegisterAccountView(){
        return view;
    }

    @Provides // <-- provide constructor injected stuff and bind to interface
    RegisterAccountPresenter registerAccountPresenter(RegisterAccountPresenterImpl impl) {
        return impl;
    }
}
于 2017-07-29T18:20:53.133 回答