我如何使用 Dagger2 注入我的 Retrofit DataService
How can i inject my Retrofit DataService using Dagger2
在我的 MVP 架构中,我有改造实例
public class RetrofitInstance {
private static Retrofit retrofit;
private static final String BASE_URL = "http://api.openweathermap.org/data/2.5/";
/**
* Create an instance of Retrofit object
* */
public static Retrofit getRetrofitInstance() {
if (retrofit == null) {
retrofit = new retrofit2.Retrofit.Builder()
.baseUrl(BASE_URL)
.addConverterFactory(GsonConverterFactory.create())
.addCallAdapterFactory(RxJava2CallAdapterFactory.create())
.build();
}
return retrofit;
}
}
还有它的数据服务
public interface GetNoticeDataService {
@GET("weather?appid=0194877ecdcac230396a119c01d46100")
Observable<NoticeList> getNoticeData(@Query("lat") double lat , @Query("lon") double lon );
}
我还有 DataInteractor,它使用 RxJava Observable 服务来调用 api
public class GetNoticeIntractorImpl implements MainContract.GetNoticeIntractor {
private LatLng getloc(){
return currentLocation;
}
@SuppressLint("CheckResult")
@Override
public void getNoticeArrayList(final OnFinishedListener onFinishedListener) {
/** Create handle for the RetrofitInstance interface*/
GetNoticeDataService service = RetrofitInstance.getRetrofitInstance().create(GetNoticeDataService.class);
/** Using RxJava Observable response to handle retrofit api*/
if(currentLocation!=null) {
service.getNoticeData(getloc().latitude, getloc().longitude)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(items -> onFinishedListener.onFinished(items.getNoticeArrayList(), items.getMain(), items.getWind()), onFinishedListener::onFailure);
}
}
}
主持人来了
public class MainPresenterImpl implements MainContract.presenter, MainContract.GetNoticeIntractor.OnFinishedListener {
private MainContract.MainView mainView;
private MainContract.GetNoticeIntractor getNoticeIntractor;
@Inject
public MainPresenterImpl(MainContract.MainView mainView, MainContract.GetNoticeIntractor getNoticeIntractor) {
this.mainView = mainView;
this.getNoticeIntractor = getNoticeIntractor;
}
@Override
public void onDestroy() {
mainView = null;
}
@Override
public void onRefreshButtonClick() {
if(mainView != null){
mainView.showProgress();
}
getNoticeIntractor.getNoticeArrayList(this);
}
@Override
public void requestDataFromServer() {
getNoticeIntractor.getNoticeArrayList(this);
}
@Override
public void onFinished(ArrayList<Notice> noticeArrayList, Main main, Wind wind) {
if(mainView != null){
mainView.setDataToRecyclerView(noticeArrayList,main,wind);
mainView.hideProgress();
}
}
@Override
public void onFailure(Throwable t) {
if(mainView != null){
mainView.onResponseFailure(t);
mainView.hideProgress();
}
}
}
和主合约
public interface MainContract {
/**
* Call when user interact with the view and other when view OnDestroy()
* */
interface presenter{
void onDestroy();
void onRefreshButtonClick();
void requestDataFromServer();
}
/**
* showProgress() and hideProgress() would be used for displaying and hiding the progressBar
* while the setDataToRecyclerView and onResponseFailure is fetched from the GetNoticeInteractorImpl class
**/
interface MainView {
void showProgress();
void hideProgress();
void setDataToRecyclerView(ArrayList<Notice> noticeArrayList, Main main, Wind wind);
void onResponseFailure(Throwable throwable);
}
/**
* Intractors are classes built for fetching data from your database, web services, or any other data source.
**/
interface GetNoticeIntractor {
interface OnFinishedListener {
void onFinished(ArrayList<Notice> noticeArrayList, Main main, Wind wind);
void onFailure(Throwable t);
}
void getNoticeArrayList(OnFinishedListener onFinishedListener);
}
}
MyActivity 的适配器
public class NoticeAdapter extends RecyclerView.Adapter<NoticeAdapter.EmployeeViewHolder> {
private static Wind wind;
private static ArrayList<Notice> dataList;
private static Main main;
private Date currentTime = Calendar.getInstance().getTime();
public static String date;
private Context mContext;
private RecyclerItemClickListener recyclerItemClickListener;
public NoticeAdapter(ArrayList<Notice> dataList, Main main, Wind wind, RecyclerItemClickListener recyclerItemClickListener,Context context) {
NoticeAdapter.dataList = dataList;
NoticeAdapter.main = main;
NoticeAdapter.wind = wind;
this.recyclerItemClickListener = recyclerItemClickListener;
this.mContext=context;
}
@NonNull
@Override
public EmployeeViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
LayoutInflater layoutInflater = LayoutInflater.from(parent.getContext());
View view = layoutInflater.inflate(R.layout.single_view_row, parent, false);
return new EmployeeViewHolder(view);
}
@SuppressLint("SetTextI18n")
@Override
public void onBindViewHolder(@NonNull EmployeeViewHolder holder, @SuppressLint("RecyclerView") final int position) {
setDate(currentTime.toString().substring(0,currentTime.toString().length()-18));
if(getAddressMap()!=null){holder.txtNoticeAddress.setText("Loc: "+getAddressMap());}else{holder.txtNoticeAddress.setText("Loc: Unknown location");}
holder.imageIcon.setImageURI(Uri.parse("android.resource://com.locweather/drawable/i"+dataList.get(position).getIcon()));
holder.txtNoticeWind.setText("Wind: "+roundUp(+wind.getSpeed())+"m/s, "+arrow());
holder.txtNoticeTempMain.setText(roundUp(+main.getTemp())+"°C");
holder.txtNoticeWeather.setText(dataList.get(position).getWeather()+" : "+dataList.get(position).getInfo());
holder.txtNoticeTemp.setText("Feels: "+roundUp(+main.getFeelsLike())+"°C ");
holder.txtNoticeTime.setText(date);
holder.txtNoticeHumidity.setText("Humidity: "+main.getHumidity()+"%");
holder.txtNoticePressure.setText("Pressure: "+main.getPressure()+"hPa");
holder.itemView.setOnClickListener(v -> {
recyclerItemClickListener.onItemClick();
saveNoticeList(mContext,dataList); });
holder.saveButton.setOnClickListener(v -> {
recyclerItemClickListener.onItemClick();
saveNoticeList(mContext,dataList); });
}
private static String getAddressMap() {
return MapsActivity.addressMap;
}
private static void setDate(String date) {
NoticeAdapter.date = date;
}
@Override
public int getItemCount() {
return dataList.size();
}
private static LatLng getloc(){
return currentLocation;
}
class EmployeeViewHolder extends RecyclerView.ViewHolder {
ImageView imageIcon;
Button saveButton;
TextView txtNoticeWeather, txtNoticeTempMain,txtNoticeTemp, txtNoticeHumidity,txtNoticeAddress,txtNoticePressure,txtNoticeWind,txtNoticeTime;
EmployeeViewHolder(View itemView) {
super(itemView);
saveButton=itemView.findViewById(R.id.save_button);
imageIcon=itemView.findViewById(R.id.image_icon);
txtNoticeTime= itemView.findViewById(R.id.txt_time);
txtNoticeWind= itemView.findViewById(R.id.txt_notice_wind);
txtNoticeAddress= itemView.findViewById(R.id.txt_notice_title);
txtNoticeWeather = itemView.findViewById(R.id.txt_notice_weather);
txtNoticeTemp = itemView.findViewById(R.id.txt_notice_temp);
txtNoticeHumidity = itemView.findViewById(R.id.txt_notice_humidity);
txtNoticePressure = itemView.findViewById(R.id.txt_notice_pressure);
txtNoticeTempMain = itemView.findViewById(R.id.txt_notice_temp_main);
}
}
private static void saveNoticeList(Context context, List<Notice> noticeList) {
if (context != null && noticeList != null) {
WeatherData weatherData = new WeatherData(getAddressMap(), wind.getSpeed(), wind.getDeg(), dataList.get(0).getIcon(), dataList.get(0).getInfo(), dataList.get(0).getWeather(), main.getTemp(), main.getFeelsLike(), main.getHumidity(), main.getPressure(), date, getloc().latitude, getloc().longitude);
WeatherDatabase.getInstance(context)
.weatherDao()
.save(weatherData);
}
}
如何使用 Dagger2 将此数据服务注入我的交互器?我应该使用 Singleton 或 Component 还是其他什么?
我很乐意提供任何帮助。
@Module
object WebServiceModule {
@Singleton
@Provides
fun providesGetNoticeDataService(retrofit: Retrofit): GetNoticeDataService =
retrofit.create<GetNoticeDataService>(GetNoticeDataService::class.java)
@Provides
fun providesGsonConverterFactory(): GsonConverterFactory = GsonConverterFactory.create()
@Provides
fun providesOkHttpClient(loggingInterceptor: HttpLoggingInterceptor): OkHttpClient =
OkHttpClient.Builder()
.connectTimeout(20, TimeUnit.SECONDS)
.readTimeout(20, TimeUnit.SECONDS)
.addInterceptor(loggingInterceptor)
.build()
@Provides
fun providesOkHttpLoggingInterceptor(): HttpLoggingInterceptor =
HttpLoggingInterceptor().apply {
level = HttpLoggingInterceptor.Level.BODY
}
@Provides
fun provideRxJava2CallAdapterFactory(): RxJava2CallAdapterFactory =
RxJava2CallAdapterFactory.create()
@Provides
fun providesRetrofit(
client: OkHttpClient,
converterFactory: GsonConverterFactory,
adapterFactory: RxJava2CallAdapterFactory
): Retrofit = Retrofit.Builder()
.baseUrl(BASE_URL)
.addConverterFactory(converterFactory)
.addCallAdapterFactory(adapterFactory)
.client(client)
.build()
}
我假设您希望 RetrofitInstance
单例暂时可用,至少在您将所有 Retrofit 用途迁移到 Dagger 2 之前是这样。
为了注入一个接口,或者一个你无法控制其构造函数的class,你需要使用一个Module
。这告诉 Dagger 如何创建 class 的实例或给定一些依赖项的接口:
@Module
public class WebServiceModule {
@Singleton
@Provides
Retrofit provideRetrofit() {
// This method tells Dagger all it needs to know about creating
// a Retrofit instance. This will be replaced by something closer
// to BWappsandmore's answer after RetrofitInstance is no longer needed.
return RetrofitInstance.getRetrofitInstance();
}
@Singleton
@Provides
GetNoticeDataService provideGetNoticeDataService(Retrofit retrofit) {
return retrofit.create(GetNoticeDataService.class);
}
然后可以将此模块包含在您的 Component
中,这将依次创建它知道如何创建的任何对象,或者从模块、@BindsInstance
传递到您的组件工厂方法的值,或者classes 与 @Inject
构造函数。由于您控制了交互器的构造函数,因此您可以简单地用 @Inject
:
对其进行注释
// @Reusable or @Singleton if you only need one interactor of this type.
public class GetNoticeInteractorImpl implements MainContract.GetNoticeInteractor {
private GetNoticeDataService service
@Inject
GetNoticeInteractorImpl(GetNoticeDataService service) {
this.service = service;
}
private LatLng getloc(){
return currentLocation;
}
@SuppressLint("CheckResult")
@Override
public void getNoticeArrayList(final OnFinishedListener onFinishedListener) {
// Our service was injected in the constructor, so there
// is no need to create it here.
// You might also consider injecting your schedulers in the future
// for unit testing.
if(currentLocation!=null) {
service.getNoticeData(getloc().latitude, getloc().longitude)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(items -> onFinishedListener.onFinished(items.getNoticeArrayList(), items.getMain(), items.getWind()), onFinishedListener::onFailure);
}
}
}
@Module
abstract class AnotherModule { // or interface
@Binds
abstract MainContract.GetNoticeInteractor bindGetNoticeInteractor(GetNoticeInteractorImpl implementation);
}
当然,如果您最终无法访问您的交互器,这将毫无用处。由于您甚至没有创建 Activity
classes,因此您需要从 Component
请求注入。在 Android 应用程序中,这通常是在 onCreate()
中的 Application
对象中创建的。
@Component(modules = {WebServicesModule.class, AnotherModule.class})
@Singleton
public interface AppComponent {
@Component.Factory
interface Factory {
AppComponent create(@BindsInstance Application application); // or whatever
}
void bindMainActivity(MainActivity activity);
}
// Probably not a singleton, but if you create an activity scope later, this might use that scope.
class MainPresenter {
@Inject
public MainPresenter(MainContract.GetNoticeInteractor interactor) {
this.getNoticeInteractor = interactor
}
// ...
}
class MainActivity {
@Inject
MainPresenter presenter;
@Override
public void onCreate(Bundle savedInstanceState) {
somehowGetComponent().inject(this);
super(savedInstanceState);
// ...
}
// ...
}
现在,由于您的 MainActivity
需要 MainPresenter
,Dagger 会在您请求注入时为您创建一个。这又需要 GetNoticeInteractor
,后者需要 GetNoticeInteractorImpl
,等等,Dagger 将在幕后处理所有这些。
如果您的演示者的构造函数需要其他参数(例如视图),现在 MainActivity 请求直接注入演示者可能更简单。最终,您将希望所有 inject(SomeClass target)
方法都引用活动、服务等,因为在您的 minSdkVersion
为 28 或更高之前,没有其他方法可以注入这些。
在我的 MVP 架构中,我有改造实例
public class RetrofitInstance {
private static Retrofit retrofit;
private static final String BASE_URL = "http://api.openweathermap.org/data/2.5/";
/**
* Create an instance of Retrofit object
* */
public static Retrofit getRetrofitInstance() {
if (retrofit == null) {
retrofit = new retrofit2.Retrofit.Builder()
.baseUrl(BASE_URL)
.addConverterFactory(GsonConverterFactory.create())
.addCallAdapterFactory(RxJava2CallAdapterFactory.create())
.build();
}
return retrofit;
}
}
还有它的数据服务
public interface GetNoticeDataService {
@GET("weather?appid=0194877ecdcac230396a119c01d46100")
Observable<NoticeList> getNoticeData(@Query("lat") double lat , @Query("lon") double lon );
}
我还有 DataInteractor,它使用 RxJava Observable 服务来调用 api
public class GetNoticeIntractorImpl implements MainContract.GetNoticeIntractor {
private LatLng getloc(){
return currentLocation;
}
@SuppressLint("CheckResult")
@Override
public void getNoticeArrayList(final OnFinishedListener onFinishedListener) {
/** Create handle for the RetrofitInstance interface*/
GetNoticeDataService service = RetrofitInstance.getRetrofitInstance().create(GetNoticeDataService.class);
/** Using RxJava Observable response to handle retrofit api*/
if(currentLocation!=null) {
service.getNoticeData(getloc().latitude, getloc().longitude)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(items -> onFinishedListener.onFinished(items.getNoticeArrayList(), items.getMain(), items.getWind()), onFinishedListener::onFailure);
}
}
}
主持人来了
public class MainPresenterImpl implements MainContract.presenter, MainContract.GetNoticeIntractor.OnFinishedListener {
private MainContract.MainView mainView;
private MainContract.GetNoticeIntractor getNoticeIntractor;
@Inject
public MainPresenterImpl(MainContract.MainView mainView, MainContract.GetNoticeIntractor getNoticeIntractor) {
this.mainView = mainView;
this.getNoticeIntractor = getNoticeIntractor;
}
@Override
public void onDestroy() {
mainView = null;
}
@Override
public void onRefreshButtonClick() {
if(mainView != null){
mainView.showProgress();
}
getNoticeIntractor.getNoticeArrayList(this);
}
@Override
public void requestDataFromServer() {
getNoticeIntractor.getNoticeArrayList(this);
}
@Override
public void onFinished(ArrayList<Notice> noticeArrayList, Main main, Wind wind) {
if(mainView != null){
mainView.setDataToRecyclerView(noticeArrayList,main,wind);
mainView.hideProgress();
}
}
@Override
public void onFailure(Throwable t) {
if(mainView != null){
mainView.onResponseFailure(t);
mainView.hideProgress();
}
}
}
和主合约
public interface MainContract {
/**
* Call when user interact with the view and other when view OnDestroy()
* */
interface presenter{
void onDestroy();
void onRefreshButtonClick();
void requestDataFromServer();
}
/**
* showProgress() and hideProgress() would be used for displaying and hiding the progressBar
* while the setDataToRecyclerView and onResponseFailure is fetched from the GetNoticeInteractorImpl class
**/
interface MainView {
void showProgress();
void hideProgress();
void setDataToRecyclerView(ArrayList<Notice> noticeArrayList, Main main, Wind wind);
void onResponseFailure(Throwable throwable);
}
/**
* Intractors are classes built for fetching data from your database, web services, or any other data source.
**/
interface GetNoticeIntractor {
interface OnFinishedListener {
void onFinished(ArrayList<Notice> noticeArrayList, Main main, Wind wind);
void onFailure(Throwable t);
}
void getNoticeArrayList(OnFinishedListener onFinishedListener);
}
}
MyActivity 的适配器
public class NoticeAdapter extends RecyclerView.Adapter<NoticeAdapter.EmployeeViewHolder> {
private static Wind wind;
private static ArrayList<Notice> dataList;
private static Main main;
private Date currentTime = Calendar.getInstance().getTime();
public static String date;
private Context mContext;
private RecyclerItemClickListener recyclerItemClickListener;
public NoticeAdapter(ArrayList<Notice> dataList, Main main, Wind wind, RecyclerItemClickListener recyclerItemClickListener,Context context) {
NoticeAdapter.dataList = dataList;
NoticeAdapter.main = main;
NoticeAdapter.wind = wind;
this.recyclerItemClickListener = recyclerItemClickListener;
this.mContext=context;
}
@NonNull
@Override
public EmployeeViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
LayoutInflater layoutInflater = LayoutInflater.from(parent.getContext());
View view = layoutInflater.inflate(R.layout.single_view_row, parent, false);
return new EmployeeViewHolder(view);
}
@SuppressLint("SetTextI18n")
@Override
public void onBindViewHolder(@NonNull EmployeeViewHolder holder, @SuppressLint("RecyclerView") final int position) {
setDate(currentTime.toString().substring(0,currentTime.toString().length()-18));
if(getAddressMap()!=null){holder.txtNoticeAddress.setText("Loc: "+getAddressMap());}else{holder.txtNoticeAddress.setText("Loc: Unknown location");}
holder.imageIcon.setImageURI(Uri.parse("android.resource://com.locweather/drawable/i"+dataList.get(position).getIcon()));
holder.txtNoticeWind.setText("Wind: "+roundUp(+wind.getSpeed())+"m/s, "+arrow());
holder.txtNoticeTempMain.setText(roundUp(+main.getTemp())+"°C");
holder.txtNoticeWeather.setText(dataList.get(position).getWeather()+" : "+dataList.get(position).getInfo());
holder.txtNoticeTemp.setText("Feels: "+roundUp(+main.getFeelsLike())+"°C ");
holder.txtNoticeTime.setText(date);
holder.txtNoticeHumidity.setText("Humidity: "+main.getHumidity()+"%");
holder.txtNoticePressure.setText("Pressure: "+main.getPressure()+"hPa");
holder.itemView.setOnClickListener(v -> {
recyclerItemClickListener.onItemClick();
saveNoticeList(mContext,dataList); });
holder.saveButton.setOnClickListener(v -> {
recyclerItemClickListener.onItemClick();
saveNoticeList(mContext,dataList); });
}
private static String getAddressMap() {
return MapsActivity.addressMap;
}
private static void setDate(String date) {
NoticeAdapter.date = date;
}
@Override
public int getItemCount() {
return dataList.size();
}
private static LatLng getloc(){
return currentLocation;
}
class EmployeeViewHolder extends RecyclerView.ViewHolder {
ImageView imageIcon;
Button saveButton;
TextView txtNoticeWeather, txtNoticeTempMain,txtNoticeTemp, txtNoticeHumidity,txtNoticeAddress,txtNoticePressure,txtNoticeWind,txtNoticeTime;
EmployeeViewHolder(View itemView) {
super(itemView);
saveButton=itemView.findViewById(R.id.save_button);
imageIcon=itemView.findViewById(R.id.image_icon);
txtNoticeTime= itemView.findViewById(R.id.txt_time);
txtNoticeWind= itemView.findViewById(R.id.txt_notice_wind);
txtNoticeAddress= itemView.findViewById(R.id.txt_notice_title);
txtNoticeWeather = itemView.findViewById(R.id.txt_notice_weather);
txtNoticeTemp = itemView.findViewById(R.id.txt_notice_temp);
txtNoticeHumidity = itemView.findViewById(R.id.txt_notice_humidity);
txtNoticePressure = itemView.findViewById(R.id.txt_notice_pressure);
txtNoticeTempMain = itemView.findViewById(R.id.txt_notice_temp_main);
}
}
private static void saveNoticeList(Context context, List<Notice> noticeList) {
if (context != null && noticeList != null) {
WeatherData weatherData = new WeatherData(getAddressMap(), wind.getSpeed(), wind.getDeg(), dataList.get(0).getIcon(), dataList.get(0).getInfo(), dataList.get(0).getWeather(), main.getTemp(), main.getFeelsLike(), main.getHumidity(), main.getPressure(), date, getloc().latitude, getloc().longitude);
WeatherDatabase.getInstance(context)
.weatherDao()
.save(weatherData);
}
}
如何使用 Dagger2 将此数据服务注入我的交互器?我应该使用 Singleton 或 Component 还是其他什么? 我很乐意提供任何帮助。
@Module
object WebServiceModule {
@Singleton
@Provides
fun providesGetNoticeDataService(retrofit: Retrofit): GetNoticeDataService =
retrofit.create<GetNoticeDataService>(GetNoticeDataService::class.java)
@Provides
fun providesGsonConverterFactory(): GsonConverterFactory = GsonConverterFactory.create()
@Provides
fun providesOkHttpClient(loggingInterceptor: HttpLoggingInterceptor): OkHttpClient =
OkHttpClient.Builder()
.connectTimeout(20, TimeUnit.SECONDS)
.readTimeout(20, TimeUnit.SECONDS)
.addInterceptor(loggingInterceptor)
.build()
@Provides
fun providesOkHttpLoggingInterceptor(): HttpLoggingInterceptor =
HttpLoggingInterceptor().apply {
level = HttpLoggingInterceptor.Level.BODY
}
@Provides
fun provideRxJava2CallAdapterFactory(): RxJava2CallAdapterFactory =
RxJava2CallAdapterFactory.create()
@Provides
fun providesRetrofit(
client: OkHttpClient,
converterFactory: GsonConverterFactory,
adapterFactory: RxJava2CallAdapterFactory
): Retrofit = Retrofit.Builder()
.baseUrl(BASE_URL)
.addConverterFactory(converterFactory)
.addCallAdapterFactory(adapterFactory)
.client(client)
.build()
}
我假设您希望 RetrofitInstance
单例暂时可用,至少在您将所有 Retrofit 用途迁移到 Dagger 2 之前是这样。
为了注入一个接口,或者一个你无法控制其构造函数的class,你需要使用一个Module
。这告诉 Dagger 如何创建 class 的实例或给定一些依赖项的接口:
@Module
public class WebServiceModule {
@Singleton
@Provides
Retrofit provideRetrofit() {
// This method tells Dagger all it needs to know about creating
// a Retrofit instance. This will be replaced by something closer
// to BWappsandmore's answer after RetrofitInstance is no longer needed.
return RetrofitInstance.getRetrofitInstance();
}
@Singleton
@Provides
GetNoticeDataService provideGetNoticeDataService(Retrofit retrofit) {
return retrofit.create(GetNoticeDataService.class);
}
然后可以将此模块包含在您的 Component
中,这将依次创建它知道如何创建的任何对象,或者从模块、@BindsInstance
传递到您的组件工厂方法的值,或者classes 与 @Inject
构造函数。由于您控制了交互器的构造函数,因此您可以简单地用 @Inject
:
// @Reusable or @Singleton if you only need one interactor of this type.
public class GetNoticeInteractorImpl implements MainContract.GetNoticeInteractor {
private GetNoticeDataService service
@Inject
GetNoticeInteractorImpl(GetNoticeDataService service) {
this.service = service;
}
private LatLng getloc(){
return currentLocation;
}
@SuppressLint("CheckResult")
@Override
public void getNoticeArrayList(final OnFinishedListener onFinishedListener) {
// Our service was injected in the constructor, so there
// is no need to create it here.
// You might also consider injecting your schedulers in the future
// for unit testing.
if(currentLocation!=null) {
service.getNoticeData(getloc().latitude, getloc().longitude)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(items -> onFinishedListener.onFinished(items.getNoticeArrayList(), items.getMain(), items.getWind()), onFinishedListener::onFailure);
}
}
}
@Module
abstract class AnotherModule { // or interface
@Binds
abstract MainContract.GetNoticeInteractor bindGetNoticeInteractor(GetNoticeInteractorImpl implementation);
}
当然,如果您最终无法访问您的交互器,这将毫无用处。由于您甚至没有创建 Activity
classes,因此您需要从 Component
请求注入。在 Android 应用程序中,这通常是在 onCreate()
中的 Application
对象中创建的。
@Component(modules = {WebServicesModule.class, AnotherModule.class})
@Singleton
public interface AppComponent {
@Component.Factory
interface Factory {
AppComponent create(@BindsInstance Application application); // or whatever
}
void bindMainActivity(MainActivity activity);
}
// Probably not a singleton, but if you create an activity scope later, this might use that scope.
class MainPresenter {
@Inject
public MainPresenter(MainContract.GetNoticeInteractor interactor) {
this.getNoticeInteractor = interactor
}
// ...
}
class MainActivity {
@Inject
MainPresenter presenter;
@Override
public void onCreate(Bundle savedInstanceState) {
somehowGetComponent().inject(this);
super(savedInstanceState);
// ...
}
// ...
}
现在,由于您的 MainActivity
需要 MainPresenter
,Dagger 会在您请求注入时为您创建一个。这又需要 GetNoticeInteractor
,后者需要 GetNoticeInteractorImpl
,等等,Dagger 将在幕后处理所有这些。
如果您的演示者的构造函数需要其他参数(例如视图),现在 MainActivity 请求直接注入演示者可能更简单。最终,您将希望所有 inject(SomeClass target)
方法都引用活动、服务等,因为在您的 minSdkVersion
为 28 或更高之前,没有其他方法可以注入这些。