2017-07-29 55 views
1

我有RegisterPresenterImpl,我想注入片段。当我调用演示者的方法register()时,我的应用程序崩溃。它说我的演示者为null。如何使用Dagger2将演示者插入片段?

我该如何解决这个问题?

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 
    } 
} 
+0

为什么你'ApplicationComponent'称为'NetComponent'? – EpicPandaForce

回答

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呢。在onCreate()而不是onCreateView()删除多余的关键字
  2. 初始化你DaggerRegisterAccountComponent,以确保它会使用任何依赖年前建成。
  3. 考虑使用finalRegisterAccountPresenterImpl所有field被设置内部构造。因为它只会初始化一次。
private final RegisterAccountView view; 

private final Retrofit retrofit; 
  • 我只是不明白,为什么你必须定义一个view(这是你的片段)一presenter,反之亦然内。这是一个循环依赖?
  • 我发现这个tutorial是关于使用MVP和Dagger的超酷贴。请考虑阅读

    还有一件事:如果您想有效地调试Dagger-2,请转到您的Dagger...Component类,以查看其中内置的内容。 Android Studio将帮助您在使用时发现任何问题。

    希望得到这个帮助!

    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; 
        } 
    }