I have sample project in which I am using dagger-android AndroidInjector to Inject dependencies.
In this sample app I have a class Navigator which does all the Activity to Activity navigation and it requires the instance of current Activity in it's Constructor.
I have a AppModule class which provides the Instances to the other component, which is also responsible for providing the instance of Navigator to my presenter, but the Navigator constructor takes Activity as parameter from the AppModule.
How can I access the activity instance to the Navigator constructor.
I have tried Injecting the instance of Activity directly in Navigator by annotating the Activity member variable with @Inject annotation but that throws error while building the project.
error: [dagger.android.AndroidInjector.inject(T)] android.app.Activity cannot be provided without an @Inject constructor or from an @Provides-annotated method. android.app.Activity is injected at
I have referred other SA post but that doesn't help with my query or may be I am failed to understand the solution given there. Below are the post I followed
How to inject current activity in a collaborator using Dagger 2.11 Android injector
How to get MainActivity inside a module using AndroidInjector
Below is the code which I have implemented:
Application.Java
public class MyApplication extends Application implements HasActivityInjector {
@Inject
DispatchingAndroidInjector<Activity> androidInjector;
@Override
public void onCreate() {
super.onCreate();
DaggerAppComponent
.builder()
.application(this)
.build()
.inject(this);
}
@Override
public AndroidInjector<Activity> activityInjector() {
return androidInjector;
}
}
MainActivity.java
public class MainActivity extends BaseActivity implements BaseView {
@Inject
Context application;
@Inject
MainPresenter mainPresenter;
@Override
protected void onCreate(Bundle savedInstanceState) {
AndroidInjection.inject(this);
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ButterKnife.bind(this);
}
}
MyPresenter.Java
public class MyPresenter extends BasePresenter<IActivityView> {
private final NavigationRouter mNavigationRouter;
@Inject
public MyPresenter(Navigator navigatr) {
mNavigationRouter = navigationRouter;
}
}
Navigator.Java
//This is how my Navigator is currently.
public class Navigator{
Activity mActivity;
@Inject
public Navigator(Activity activity){
mActivity = activity;
}
}
ActivityBuilder.java
@Module
public abstract class ActivityBuilder {
@ContributesAndroidInjector
abstract MainActivity bindMainActivity();
@ContributesAndroidInjector
abstract LoginActivity bindLoginActivity();
}
AppModule.Java
@Module
public class AppModule {
//How can i have the instance of current activity in this module class.
@Provides
@Singleton
NavigationRouter providesNavigationRouter(Activity activity) {
//Here I want the instance of current activity
return new NavigationRouter(activity);
}
}
AppComponent.Java
@Component(modules = {
AndroidInjectionModule.class,
AppModule.class,
ActivityBuilder.class})
@Singleton
public interface AppComponent {
@Component.Builder
interface Builder {
@BindsInstance
Builder application(Application application);
AppComponent build();
}
void inject(MyApplication application);
}
Any help on this will be much appreciated.
I have update the code snippet for more clarity
I'm a little confused on how this is expected to work. Does this mean that each
Activitycreates its ownNavigator? If the Activity is supplied via the constructor then I can't think of any other way this would be feasible.Anyway, assuming you do want to create a
Navigatorfor each of your Activities, then your Dagger setup would look like this:MainActivityModule.java
ActivityBuilder.java
MainActivity.java
Edit: I made a couple of points the comments that show a "Navigator" class that takes a single Activity in via its constructor isn't feasible. You could instead try this:
I use
WeakReferences because storing an Activity in a singleton is dangerous, and effectively begs memory leaks. However, you could use theActivityLifecycleCallbacksto remove Activities as they move into "onPause" as well.