Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

No injector was found for fragment dagger 2.11

Tags:

i have an Activity with one fragment. I am trying to inject the fragment but i am getting 'No injector was found for com.tsiro.dogvip.login.signin.SignInFrgmt' exception.

ActivityModule:

@Module(includes = BaseActivityModule.class)
public abstract class LoginActivityModule {

   @PerFragment
   @ContributesAndroidInjector(modules = SignInFragmentModule.class)
   abstract SignInFrgmt signInFrgmtInjector();

   @Binds
   @PerActivity
   abstract Activity activity(LoginActivity loginActivity);
}

FragmentModule:

@Module(includes = BaseFragmentModule.class)
public abstract class SignInFragmentModule {

@Binds
@Named(BaseFragmentModule.FRAGMENT)
@PerFragment
abstract Fragment fragment(SignInFrgmt signInFrgmt);

}

Fragment class extends BaseFragment where HasSupportFragmentInjector is implemented.

BaseFragment:

public abstract class BaseFragment extends Fragment implements HasSupportFragmentInjector, Lifecycle.View {

@Inject
DispatchingAndroidInjector<Fragment> fragmentInjector;
public abstract Lifecycle.ViewModel getViewModel();

@SuppressWarnings("deprecation")
@Override
public void onAttach(Activity activity) {
    if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
        // Perform injection here before M, L (API 22) and below because onAttach(Context)
        // is not yet available at L.
        AndroidSupportInjection.inject(this);
    }
    super.onAttach(activity);
}

@Override
public void onAttach(Context context) {
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
        // Perform injection here for M (API 23) due to deprecation of onAttach(Activity).
        AndroidSupportInjection.inject(this);
    }
    super.onAttach(context);
}

@Override
public void onStart() {
    super.onStart();
    getViewModel().onViewAttached(this);
}

@Override
public void onResume() {
    super.onResume();
    getViewModel().onViewResumed();
}

@Override
public void onPause() {
    super.onPause();
}

@Override
public void onStop() {
    super.onStop();
    getViewModel().onViewDetached();
}

@Override
public AndroidInjector<Fragment> supportFragmentInjector() {
    return fragmentInjector;
}

 }

Can anybody tell me what i am missing?

like image 270
tsiro Avatar asked Oct 19 '17 16:10

tsiro


People also ask

Why are my package names not generating code in dagger?

You may see this when using Java keywords, like new or short, long, etc., in your package names (even if you are using Kotlin throughout your app). Dagger generates Java code for your definition and classes. This code generation will fail for package names equal to reserved Java keywords.

What is the difference between dagger1 and dagger2 errors?

@Module abstract class FragmentProvider { @ContributesAndroidInjector // <- Do not forget this line. abstract fun contributeYourNewFragment (): YourNewFragment } Dagger2 Errors are more straightforward than dagger1 but it popup one by one depending on what issue dagger face in compilation time first.

Can I use @contributesandroidinjector with dagger?

You should really only use @ContributesAndroidInjector across modules (aka compilation units). As a result, it's very likely that there is no component defined which includes it in a way that Dagger can analyze.

How to create an appmodule instance in dagger?

If Your AppModule doesn't have any default constructor so Dagger can't create an instance of AppModule. so create an AppModule instance and set it to Dagger graph. mComponent = DaggerXComponent.builder () .appModule (new AppModule (....)) // create appModule instance .build ();


1 Answers

The problem with your code, is the incorrect implementation of the interface HasSupportFragmentInjector or HasFragmentInjector (it depends on whether you are using the support library for fragments or not).

You should implement this interface either in your Activity that is hosting the fragment, or in your Application class. Personally, I 'd recommend the following Application class so you don't bother implementing it on every Activity that hosts a Fragment:

public class MyApplication extends Application implements HasActivityInjector, HasSupportFragmentInjector {

    @Inject
    DispatchingAndroidInjector<Activity> mActivityInjector;

    @Inject
    DispatchingAndroidInjector<Fragment> mFragmentInjector;

    @Override
    public void onCreate() {
        super.onCreate();

        //The way you build your top-level Application component can vary. This is just an example
        DaggerApplicationComponent.builder()
            .application(this)
            .build()
            .inject(this);

    }

    @Override
    public AndroidInjector<Activity> activityInjector() {
        return mActivityInjector;
    }

    @Override
    public AndroidInjector<Fragment> supportFragmentInjector() {
        return mFragmentInjector;
    }
}

And then in you inject your Fragments (as you already do in your code):

@Override
public void onAttach(Context context) {
    AndroidSupportInjection.inject(this);
    super.onAttach(context);
}

If the above is not working, make sure you have created the appropriate Components/Subcomponents for the screen you are trying to inject. If you are using @ContributesAndroidInjector instead of manually defining components, make sure you have one entry for your screen in your binding Module:

@ContributesAndroidInjector(modules = MyScreenModule.class) abstract MyScreenActivity bindMyScreen();

If you still can't get it to work. I recommend reading the actual Dagger documentation:

Hope it helps.

like image 50
DimitrisCBR Avatar answered Sep 28 '22 11:09

DimitrisCBR