Collectives™ on Stack Overflow
Find centralized, trusted content and collaborate around the technologies you use most.
Learn more about Collectives
Teams
Q&A for work
Connect and share knowledge within a single location that is structured and easy to search.
Learn more about Teams
I wanna to make a simple project with one main activity and multiple fragments.
here I have two fragments at one activity and I want to inject presenter to login fragment but it doesn't work. where is my mistake?
MainApplication.java
public class MainApplication extends DaggerApplication{
private static ApplicationComponent component;
@Override
public void onCreate() {
super.onCreate();
Utils.init(this);
public static ApplicationComponent getComponent() {
return component;
protected AndroidInjector<? extends DaggerApplication> applicationInjector()
component =
DaggerApplicationComponent.builder().application(this).build();
component.inject(this);
return component;
MainActivity.java
public class MainActivity extends DaggerAppCompatActivity {
private Fragment[] mFragments = new Fragment[2];
private int curIndex;
@Inject
HomeFragment homeFragment;
@Inject
LoginFragment loginFragment;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
if (savedInstanceState != null) {
curIndex = savedInstanceState.getInt("curIndex");
mFragments[AppConstant.HOME_FRAGMENT] = homeFragment;
mFragments[AppConstant.LOGIN_FRAGMENT] = loginFragment;
FragmentUtils.add(getSupportFragmentManager(), mFragments,
R.id.container, curIndex);
showCurrentFragment(AppConstant.LOGIN_FRAGMENT);
private void showCurrentFragment(int index) {
FragmentUtils.showHide(curIndex = index, mFragments);
@Override
public void onSaveInstanceState(Bundle outState, PersistableBundle
outPersistentState) {
super.onSaveInstanceState(outState, outPersistentState);
outState.putInt("curIndex", curIndex);
ApplicationComponent.java
@Singleton
@Component(modules = {
ContextModule.class,
ApiServiceModule.class,
AndroidSupportInjectionModule.class,
ActivityBuilder.class
public interface ApplicationComponent extends
AndroidInjector<DaggerApplication> {
void inject(MainApplication component);
@Component.Builder
interface Builder {
ApplicationComponent build();
@BindsInstance
Builder application(MainApplication application);
LoginFragment.java
public class LoginFragment extends DaggerFragment{
View mRootView;
@Inject
HomeFragment homeFragment;
@Inject
LoginContract.Presenter mPresenter;
@Inject
public LoginFragment() {
// Required empty public constructor
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
mRootView =inflater.inflate(R.layout.fragment_login, container, false);
ButterKnife.bind(this,mRootView);
// Inflate the layout for this fragment
return mRootView;
@OnClick(R.id.button)
public void goToHome(){
FragmentUtils.replace(this,homeFragment,false);
@Override
public void onAttach(Context context) {
super.onAttach(context);
@Override
public void onDetach() {
super.onDetach();
ActivityBuilder.java
@Module
public abstract class ActivityBuilder {
@ContributesAndroidInjector(modules = {MainActivityModule.class ,
FragmentContainerModule.class, AndroidSupportInjectionModule.class} )
abstract MainActivity bindMainActivity();
FragmentContainerModule.java
@Module
public abstract class FragmentContainerModule {
@ContributesAndroidInjector(modules =
{HomeFragmentModule.class,
AndroidSupportInjectionModule.class})
abstract HomeFragment contributeHomeFragmentInjector();
@FragmentScope
@ContributesAndroidInjector(modules =
{LoginFragmentModule.class,
AndroidSupportInjectionModule.class})
abstract LoginFragment contributeLoginFragmentInjector();
and this is the error :
error: [Dagger/MissingBinding] [dagger.android.AndroidInjector.inject(T)]
ir.heart.heartproject.utils.MvpUtils.LoginContract.Presenter cannot be
provided without an @Provides-annotated method.
A binding with matching key exists in component:
ir.heart.heartproject.utils.di.
modules.FragmentContainerModule_ContributeLoginFr
agmentInjector.LoginFragmentSubcomponent
ir.heart.heartproject.utils.MvpUtils.
LoginContract.Presenter is injected at
ir.heart.heartproject.views.fragments.LoginFragment.mPresenter
ir.heart.heartproject.views.fragments.LoginFragment is injected at
ir.heart.heartproject.views.activities.MainActivity.loginFragment
ir.heart.heartproject.views.activities.MainActivity is injected at
dagger.android.AndroidInjector.inject(T)
component path:
ir.heart.heartproject.utils.di.component.ApplicationComponent ?
ir.heart.heartproject.utils.di.modules.
ActivityBuilder_BindMainActivity.MainActivitySubcomponent
–
You use @inject to annotate the constructor of LoginFragment, when a new instance is requested, Dagger constructs instances of your LoginFragment class and satisfies their dependencies (like the mPresenter field). Because MainActivitySubcomponent doesn’t access LoginFragmentModule, Dagger gives you an error that can not provide LoginContract.Presenter. instead of using constructor injection, if you use another approach for providing LoginFragment for MainActivity, the problem will be solved. You should remove @inject from LoginFragment constructor and create a module to provide it like the following example:
@Module
public class MainModule {
@Provides
public static LoginFragment provideLoginFragment() {
return LoginFragment.newInstance("param1", "param2");
Dagger tips: don't use Constructor injection for an object that system instantiate it. in android, for injecting dependency in activity and fragment, you should use field injection approach.
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.