我正在尝试通过构造函数注入为Fragment
注入一个演示者(这样我就不需要为演示者创建@Provides
方法了。)
我相信我正确地做到了,但我仍然收到以下错误:
如果没有@ Provide-或@ Produces-annotation方法,则无法提供MainFragmentPresenter。
这是我的设置:
ApplicationComponent.java
@Singleton
@Component(
modules = {
NetworkModule.class
}
)
public interface ApplicationComponent {
NetworkService networkService();
}
MainFragmentComponent.java
@PerFragment
@Component(
dependencies = ApplicationComponent.class,
modules = MainFragmentPresenterModule.class
)
public interface MainFragmentComponent {
MainFragmentView view();
void inject(MainFragment mainFragment);
}
MainFragmentPresenterModule.java
@Module
public class MainFragmentPresenterModule {
private final MainFragmentView _view;
public MainFragmentPresenterModule(MainFragmentView view) {
_view = view;
}
@Provides
@PerFragment
MainFragmentView provideMainFragmentView() {
return _view;
}
}
NetworkModule.java
@Module
public class NetworkModule {
@Provides
@Singleton
OkHttpClient provide_OkHttpClient() {
return new OkHttpClient();
}
@Provides
@Singleton
OpenWeatherEndpoints provide_OpenWeatherAPI(OkHttpClient client) {
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("http://api.openweathermap.org/data/2.5/")
.addConverterFactory(GsonConverterFactory.create())
.addCallAdapterFactory(RxJava2CallAdapterFactory.create())
.client(client)
.build();
return retrofit.create(OpenWeatherEndpoints.class);
}
@Provides
@Singleton
YoutubeEndpoints provide_YoutubeEndpoints(OkHttpClient client) {
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("https://www.googleapis.com/youtube/v3/")
.addConverterFactory(GsonConverterFactory.create())
.addCallAdapterFactory(RxJava2CallAdapterFactory.create())
.client(client)
.build();
return retrofit.create(YoutubeEndpoints.class);
}
@Provides
@Singleton
NetworkService provide_NetworkService(OpenWeatherEndpoints openWeatherEndpoints, YoutubeEndpoints youtubeEndpoints) {
return new NetworkService(openWeatherEndpoints, youtubeEndpoints);
}
}
PerFragment.java
@Scope
@Retention(RUNTIME)
@interface PerFragment {
}
MainFragmentPresenterImpl.java
public class MainFragmentPresenterImpl implements MainFragmentPresenter {
private final MainFragmentView _view;
private NetworkService _service;
@Inject MainFragmentPresenterImpl(MainFragmentView view, NetworkService networkService) {
_view = view;
_service = networkService;
}
}
当我尝试在我的片段中注入演示者时......
public class MainFragment extends Fragment implements MainFragmentView {
public static final String TAG = "MainFragment";
@Inject
MainFragmentPresenter _presenter;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
DaggerMainFragmentComponent.builder()
.applicationComponent(WeatherForecastApp.get(getContext()).getAppComponent())
.mainFragmentPresenterModule(new MainFragmentPresenterModule(this))
.build()
.inject(this);
}
}
非常感谢所有帮助!感谢。
答案 0 :(得分:1)
您需要将MainFragmentPresenterImpl中的绑定添加到MainFragmentPresenter。 Dagger不会在类型之间进行转换,因此您需要使用@Binds方法明确地执行此操作。 @Binds相当于一个只返回其参数的@Provides方法,但它的实现效率更高。只需像这样更改模块:
@Module
public abstract class MainFragmentPresenterModule {
...
@Binds
abstract MainFragmentPresenter(MainFragmentPresenterImpl impl);
}
此外,您可以使用@BindsInstance删除模块中的@Provides方法,_view
字段和构造函数。
public interface MainFragmentComponent {
@Component.Builder
interface Builder {
@BindsInstance
Builder mainFragmentView(MainFragmentView mainFragmentView);
}
void inject(MainFragment mainFragment);
}
现在,由于您的模块没有构造函数,因此不需要为Dagger提供实例,因此您可以像这样构造组件:
DaggerMainFragmentComponent.builder()
.applicationComponent(WeatherForecastApp.get(getContext()).getAppComponent())
.mainFragmentView(this)
.build()
.inject(this);