Java 演示者注射匕首2

Java 演示者注射匕首2,java,android,dependency-injection,mvp,dagger-2,Java,Android,Dependency Injection,Mvp,Dagger 2,我刚开始使用Dagger2,我在网上找到了成千上万的指南,每一个都有不同的实现,我现在有点困惑。 基本上这就是我现在写的: AppModule.java: @Module public class AppModule { Application mApplication; public AppModule(Application application) { mApplication = application; } @Provides @Singleton Appli

我刚开始使用Dagger2,我在网上找到了成千上万的指南,每一个都有不同的实现,我现在有点困惑。 基本上这就是我现在写的:

AppModule.java:

@Module
public class AppModule {

 Application mApplication;

 public AppModule(Application application) {
    mApplication = application;
 }

 @Provides
 @Singleton
 Application providesApplication() {
    return mApplication;
 }
}
@Module
public class DataModule {

private static final String BASE_URL = "http://beta.fridgewizard.com:9001/api/";

@Provides
@Singleton
NetworkService provideNetworkService() {
    return new NetworkService(BASE_URL);
}

@Provides
@Singleton
SharedPreferences provideSharedPreferences(Application app) {
    return PreferenceManager.getDefaultSharedPreferences(app);
}
}
DataModule.java:

@Module
public class AppModule {

 Application mApplication;

 public AppModule(Application application) {
    mApplication = application;
 }

 @Provides
 @Singleton
 Application providesApplication() {
    return mApplication;
 }
}
@Module
public class DataModule {

private static final String BASE_URL = "http://beta.fridgewizard.com:9001/api/";

@Provides
@Singleton
NetworkService provideNetworkService() {
    return new NetworkService(BASE_URL);
}

@Provides
@Singleton
SharedPreferences provideSharedPreferences(Application app) {
    return PreferenceManager.getDefaultSharedPreferences(app);
}
}
PrefsModel.java:

@Module(includes = DataModule.class)
public class PrefsModel {

@Provides
@Singleton
QueryPreferences provideQuery(SharedPreferences prefs) {
    return new QueryPreferences(prefs);
}
}
java(我公开QueryPreferences对象,因为我需要在演示者中使用它,希望它是正确的):

然后是FwApplication.java:

public class FwApplication extends Application {

private static final String TAG = "FwApplication";

private NetworkService mNetworkService;

private AppComponent mDataComponent;

    @Override
    public void onCreate() {
       super.onCreate();

       buildComponentAndInject();
    }

    public static AppComponent component(Context context) {
      return ((FwApplication)   context.getApplicationContext()).mDataComponent;
    }

    public void buildComponentAndInject() {
       mDataComponent = DaggerComponentInitializer.init(this);
    }

    public static final class DaggerComponentInitializer {
      public static AppComponent init(FwApplication app) {
        return DaggerAppComponent.builder()
                .appModule(new AppModule(app))
                .dataModule(new DataModule())
                .build();
    }
   }
}
最后,我为演示者添加了另一个模块:

@Module
public class PresenterModule {

   @Provides
   Presenter<FwView> provideHomePresenter(NetworkService networkService) {
      return new HomePresenterImpl(networkService);
   }

   @Provides
   Presenter<FwView> provideSearchPresenter(NetworkService networkService) {
      return new SearchPresenterImpl(networkService);
   }

}
因此,在阅读在线文档时,我有几个问题不清楚:

  • 如何修复presenter组件中的错误,因为它依赖于AppComponent中定义的单一项NetworkService
  • 我有一个HomeFragment,它应该用“new HomePresenter(networkService)”实现HomePresenter,但现在我不知道如何使用定义的DI
编辑-修复:

HomeFragment.java:

public class HomeFragment extends Fragment {

private static final String TAG = "FW.HomeFragment";


@Inject
HomePresenterImpl mHomePresenter;

public static HomeFragment newInstance() {
    return new HomeFragment();
}

@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    FwApplication.component(getActivity()).inject(this);
}
然后,我以以下方式修改了presenter构造函数:

@Singleton
@Component(modules = {AppModule.class, DataModule.class, PrefsModel.class})
public interface AppComponent {

    void inject(HomeFragment homeFragment);

    QueryPreferences preferences();
    NetworkService networkService();
}
@Inject
public HomePresenterImpl(NetworkService networkService) {
    mNetworkService = networkService;
    mInteractor = new InteractorImpl(mNetworkService);
}
然后NetworkService被自动注入

我想知道这样做是否正确,因为我必须调用我所有的片段,这些片段需要一个演示者,其构造方式与下面代码中的相同:

FwApplication.component(getActivity()).inject(this);

你把事情搞混了。要提供演示者,您应该切换到以下内容:

如果可能,使用构造函数注入。这将使事情变得容易得多

要提供接口,请使用此构造函数注入并取决于实现:

Presenter<FwView> provideHomePresenter(HomePresenterImpl homePresenter) {
    return homePresenter;
}
Presenter提供homePresenter(HomePresenterImpl homePresenter){
返回homePresenter;
}
这样,您不必自己调用任何构造函数。要真正注入演示者

public class MyFragment extends Fragment {

    @Inject
    Presenter<FwView> mHomePresenter;

    public void onCreate(Bundle xxx) {
        // simplified. Add your modules / Singleton component
        PresenterComponent component = DaggerPresenterComponent.create().inject(this);
    }
}
公共类MyFragment扩展了片段{
@注入
主持人:主持人;
创建时的公共void(Bundle xxx){
//简化。添加模块/单体组件
PresenterComponent组件=DaggerPresenterComponent.create().inject(此);
}
}
这样你就可以把东西注射进去。请仔细阅读并试着理解它。这将解决您的主要问题,您仍然无法从同一模块(在同一范围内)提供两个相同类型的演示者

//不要
@提供
演示者提供家庭演示者(网络服务网络服务){/**/}
@提供
演示者提供搜索演示者(网络服务网络服务){/**/}

这是行不通的。不能提供两个相同类型的对象。它们无法区分。如果您确定这是您想要的方式,请查看like
@Named

如果构造函数中使用@Inject注释,则无需提供演示者@类的构造函数中使用的注入注释使该类成为依赖关系图的一部分。因此,它也可以在需要时注射


另一方面,如果将@Inject注释添加到字段,而不是构造函数,则必须提供该类。

修复presenter组件中的错误
请始终包含
onCreate()中使用的错误
getAactivity()
可能产生
NullPointerException
。非常感谢您的回答,我对问题进行了编辑,以显示我是如何按照您的建议进行修复的。(我不确定我是如何在片段中注入演示者的)@David,为您的
返回homePresenter
您可以使用
@Binds
注释,这可能会在幕后生成更好的代码。再见,非常感谢!我自己也在努力解决这个问题。这消除了我的一些疑虑。再次感谢您。@David唯一缺少的是您如何以可模仿的方式将视图传递给演示者
// DON'T
@Provides
Presenter<FwView> provideHomePresenter(NetworkService networkService) { /**/ }

@Provides
Presenter<FwView> provideSearchPresenter(NetworkService networkService) { /**/ }