Dagger2 learning is still difficult and am trying to learn. Have setup a project using new dagger android to avoid injecting inside activity class. So far it's working but need to use retrofit injected in presenter class. Added retrofit module in AppComponent but apiService class method getting null when call from presenter class. Need to know how to inject properly.
@Singleton
@Component(modules = {
/* Use AndroidInjectionModule.class if you're not using support library */
AndroidSupportInjectionModule.class,
AppModule.class,
BuildersModule.class,
RetrofitModule.class})
public interface AppComponent {
@Component.Builder
interface Builder {
@BindsInstance
Builder application(BaseApplication application);
Builder retrofitModule(RetrofitModule retrofitModule);
AppComponent build();
}
void inject(BaseApplication app);
}
@Module
class AppModule {
@Provides
Context provideContext(BaseApplication application) {
return application.getApplicationContext();
}
}
@Module
public abstract class BuildersModule {
@ContributesAndroidInjector(modules = {SplashViewModule.class, SplashModule.class})
abstract SplashActivity bindSplashActivity();
// Add bindings for other sub-components here
}
public class BaseApplication extends Application implements HasActivityInjector {
@Inject
DispatchingAndroidInjector<Activity> dispatchingAndroidInjector;
@Override
public void onCreate() {
super.onCreate();
//configure timber for logging
if (BuildConfig.DEBUG) {
Timber.plant(new Timber.DebugTree());
}
DaggerAppComponent
.builder()
.application(this)
.retrofitModule(new RetrofitModule())
.build()
.inject(this);
}
@Override
public AndroidInjector<Activity> activityInjector() {
return dispatchingAndroidInjector;
}
}
@Module
public class RetrofitModule {
//get retrofit instance
@Singleton
@Provides
public UserAuthService getRestService() {
Gson gson = new GsonBuilder()
.setLenient()
.create();
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(ApiConstants.BASE_URL)
.addConverterFactory(GsonConverterFactory.create(gson))
.addCallAdapterFactory(RxJava2CallAdapterFactory.create())
.client(getOkHttpClient())
.build();
return retrofit.create(UserAuthService.class);
}
}
public interface UserAuthService {
@GET("v2/5be345062f00006b00ca22c4")
Observable<Example> getExampleResponse();
}
@Module
public class SplashModule {
@Provides
SplashPresenter provideSplashPresenter(SplashView splashView) {
return new SplashPresenter(splashView);
}
}
@Module
public abstract class SplashViewModule {
@Binds
abstract SplashView provideSplashView(SplashActivity splashActivity);
}
class SplashPresenter extends BasePresenter<SplashView> {
@Inject
@Named(ValueConstants.MAIN_THREAD)
Scheduler mMainThread;
@Inject
@Named(ValueConstants.NEW_THREAD)
Scheduler mNewThread;
@Inject
UserAuthService userAuthService;
SplashPresenter(SplashView view) {
super(view);
}
//test purpose
public void sayHello() {
userAuthService.getExampleResponse()
.observeOn(mMainThread)
.subscribeOn(mNewThread)
.subscribe(new Observer<Example>() {
@Override
public void onSubscribe(Disposable d) {
}
@Override
public void onNext(Example example) {
Timber.d("example %s", example.toString());
}
@Override
public void onError(Throwable e) {
e.printStackTrace();
}
@Override
public void onComplete() {
}
});
}
}
here "userAuthService.getExampleResponse()" getting null. I think presenter need to know about RetrofitModule injection. So I need to fix this and how?
I would add those dependencies to the constructor of SplashPresenter
and add the @Inject
annotation to it. Dagger2 supports constructor injection and all the dependencies you need are resolvable (and you can also get rid of SplashModule
)
class SplashPresenter extends BasePresenter<SplashView> {
private Scheduler mMainThread;
private Scheduler mNewThread;
private UserAuthService userAuthService;
@Inject
SplashPresenter(SplashView view, UserAuthService userAuthService, @Named(ValueConstants.NEW_THREAD) Scheduler newThread, @Named(ValueConstants.MAIN_THREAD) Scheduler mainThread) {
super(view);
this.userAuthService = userAuthService;
mNewThread = newThread;
mMainThread = mainThread;
}