I am trying out dagger2 and want to inject a presenter into the activity, i searched the internet as to why the presenter is null but then i get different implementations of injecting an activity with several modules. Can someone please help me understand where i am going wrong when trying to create the dagger dependencies?
I have the following classes defined:
ActivityComponent.class
@PerActivity
@Component(modules = {ActivityModule.class}, dependencies = {AppComponent.class, GitHubComponent.class})
public interface ActivityComponent {
void inject(AppCompatActivity activity);
}
ActivityModule.class
@Module
public class ActivityModule {
private AppCompatActivity activity;
public ActivityModule(AppCompatActivity activity) {
this.activity = activity;
}
@Provides
AppCompatActivity provideActivity() {
return activity;
}
@Provides
@PerActivity public MainView provideMainView() {
return new MainViewImpl(activity);
}
@Provides
@ActivityScope
Context providesContext() {
return activity;
}
}
AppModule.class
@Singleton
@Module
public class AppModule {
private final GitHubApp application;
public AppModule(final GitHubApp application) {
this.application = application;
}
@Provides
Application provideApplication() {
return application;
}
@Provides
public GitHubLog provideGithubLog() {
return new GitHubLog();
}
}
GitHubModule.class
@Module
public class GitHubModule {
@Provides
public MainInteractor provideMainInteractor() {
return new MainInteractorImpl();
}
@Provides
@PerActivity
public MainPresenter provideMainPresenter(){
return new MainPresenterImpl();
}
}
AppComponent.class
@Singleton
@Component(modules = AppModule.class)
public interface AppComponent {
void inject(GitHubApp gitHubApp);
void inject(GitHubLog gitHubLog);
Application application();
GitHubLog getGitHubLog();
}
GithubComponent.class
@Component(modules = {GitHubModule.class, AppModule.class})
public interface GitHubComponent {
void inject(MainPresenterImpl presenter);
}
Inside the application class, i am created an appcomponent
instance and also githubcomponent
instance, that i use in the BaseActivity to create the activitycomponent
.
And i inject the presenter inside MainAcitivity that extends BaseActivity
and i get a null-pointer exception saying presenter is null.
Is my implementation incorrect? What could i be missing?
EDIT: GithubApp.class
public class GitHubApp extends Application {
public static GitHubApp INSTANCE;
private AppComponent appComponent;
private GitHubComponent gitHubComponent;
@Override
public void onCreate() {
super.onCreate();
INSTANCE = this;
getAppComponent().inject(this);
}
public AppComponent getAppComponent() {
if (appComponent == null) {
appComponent = DaggerAppComponent.builder()
.appModule(new AppModule(this))
.gitHubModule(new GitHubModule())
.build();
}
return appComponent;
}
public GitHubComponent getGitHubComponent() {
if (gitHubComponent == null) {
gitHubComponent = DaggerGitHubComponent.builder()
.gitHubModule(new GitHubModule())
.build();
}
return gitHubComponent;
}
}
How i inject the presenter into the activity is as under: BaseActivity.class has a method that returns the activity component
return DaggerActivityComponent.builder()
.appComponent(((GitHubApp)getApplication()).getAppComponent())
.gitHubComponent(((GitHubApp)getApplication()).getGitHubComponent())
.activityModule(new ActivityModule(this))
.build();
In the MainActivity.class i use it like this:
before super.onCreate()
is called, call getActivityComponent().inject(this);
@Inject MainPresenter mainPresenter is the variable declaration
EDIT2:
Changes suggested by Chisko and Muhammad Babar work together, as it is also required to change the inject(AppCompatActivity activity)
to inject(MainActivity activity)