添加链接
link之家
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接
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
                I think you need to include FragmentContainerModule at AppModule and make sure in Your Application implements HasFragmentInjector and inside the Fragment you should write Android.inject(this).
– Urvish rana
                Aug 22, 2018 at 11:29

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.