question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

@ContributesAndroidInjector: Cannot be provided without an @Provides-annotated method.

See original GitHub issue

@ContributesAndroidInjector could not inject the fragment view interface on presenter constructor (MVP) but the same approach works fine with activity flow.

Error.

 error: [Dagger/MissingBinding] [dagger.android.AndroidInjector.inject(T)] com.jega.android.example.dagger2.login.LoginView cannot be provided without an @Provides-annotated method.
com.jega.android.example.dagger2.login.LoginView is injected at
com.jega.android.example.dagger2.login.LoginPresenter.<init>(…, callback)
com.jega.android.example.dagger2.login.LoginPresenter is injected at
com.jega.android.example.dagger2.login.LoginFragment.presenter
com.jega.android.example.dagger2.login.LoginFragment is injected at
com.jega.android.example.dagger2.MainActivity.login
com.jega.android.example.dagger2.MainActivity is injected at
dagger.android.AndroidInjector.inject(T)
component path: com.jega.android.example.dagger2.di.MyAppComponent → com.jega.android.example.dagger2.di.MyActivityModule_AccountActivityInjector.MainActivitySubcomponent

Source Code https://github.com/jega-ms/android-dagger2-mvp-rx/blob/master/app/src/main/java/com/jega/android/example/dagger2/MainActivity.java


@Module
public abstract class MainActivityModule {

    @ContributesAndroidInjector(modules = LoginFragmentModule.class)
    abstract LoginFragment LoginFragmentInjector();

    @Binds
    abstract MainActivityView bindMainActivityView(MainActivity mainActivity);

    @Binds
    abstract Activity activity(MainActivity mainActivity);

}

public class LoginFragment extends BaseFragment implements LoginView {
    @Inject
    LoginPresenter presenter;

    @Inject  // If we comment this code and create a instance from activity it works fine.
    public LoginFragment() {
    }
}

@Module
public abstract class LoginFragmentModule {

    @Binds
    abstract LoginView activityLoginFragment(LoginFragment login);
}

public class LoginPresenter {

    private AccountManager accountManager;
    private LoginView callback;

    @Inject
    public LoginPresenter(AccountManager accountManager, LoginView callback) {
        this.accountManager = accountManager;
        this.callback = callback;

    }

    public void login() {
        accountManager.login();
        callback.onSuccess();

    }
}



Issue Analytics

  • State:closed
  • Created 5 years ago
  • Reactions:1
  • Comments:6

github_iconTop GitHub Comments

1reaction
jega-mscommented, Oct 24, 2018

i didn’t get chance to get deeper into this issue. In my case, i just removed @Inject constructor annotation on all the fragments, later it’s started working fine.

On Sat, Oct 20, 2018 at 6:19 PM SQSong notifications@github.com wrote:

@jega-ms https://github.com/jega-ms Thanks for your reply, bro.

Yes, my fragment’s constructor has @Inject annotation, but it didn’t work. here are my code: The application component:

@Singleton@Component(modules = [AppModule::class, CommonModule::class, HttpModule::class, AndroidSupportInjectionModule::class, ActivityBindingModule::class])interface ApplicationComponent : AndroidInjector<BaseApplication> { @dagger.Component.Builder interface Builder { @BindsInstance fun application(application: Application): Builder fun build(): ApplicationComponent } }

Then ActivityBindingModule:

@Moduleabstract class ActivityBindingModule { @ActivityScope @ContributesAndroidInjector(modules = [MainModule::class]) abstract fun contributeHomeActivity(): HomeActivity }

The MainModule for the HomeActivity, HomeActivity has four Fragment:

@Moduleabstract class MainModule { @FragmentScope @ContributesAndroidInjector(modules = [HomeModule::class]) abstract fun contributeHomeFragment(): HomeFragment … }

The HomeModule for the first HomeFragment:

@Moduleclass HomeModule { @FragmentScope @Provides fun provideHomeView(homeFragment: HomeFragment): HomeContract.HomeView { return homeFragment } @FragmentScope @Provides fun provideHomeModel(apiService: ApiService): HomeModel { return HomeModel(apiService) } }

HomeFragment implement HomeContract.HomeView, and the constructor has @Inject annotation:

class HomeFragment @Inject constructor() : BaseFragment<HomePresenter>(), HomeContract.HomeView, SwipeRefreshLayout.OnRefreshListener, RecyclerScrollListener.OnLoadMoreListener { … }

BaseFragment inject the Presenter:

abstract class BaseFragment<P : IPresenter<*>> : DaggerFragment(), IView { @Inject lateinit var mPresenter: P }

HomePresenter code:

class HomePresenter @Inject constructor(private val homeModel: HomeModel, private val homeView: HomeContract.HomeView, private val disposable: CompositeDisposable) : BasePresenter<HomeContract.HomeView, HomeContract.Model>(homeModel, disposable) { … }

But when i build the project, it still tips: HomeContract.HomeView cannot be provided without an @Provides-annotated method.

Like you said, the Activity inject View is ok. but in the fragment, it was compile error, i don’t know why?

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/google/dagger/issues/1249#issuecomment-431577539, or mute the thread https://github.com/notifications/unsubscribe-auth/APJShougu1AFwanwYGNKJJX-TsCsoPOsks5umxvxgaJpZM4V4eUb .

– Jegadeesan M

0reactions
sqsong66commented, Oct 20, 2018

@jega-ms Thanks for your reply, bro.

Yes, my fragment’s constructor has @Inject annotation, but it didn’t work. here are my code: The application component:

@Singleton
@Component(modules = [AppModule::class, CommonModule::class, HttpModule::class,
    AndroidSupportInjectionModule::class, ActivityBindingModule::class])
interface ApplicationComponent : AndroidInjector<BaseApplication> {
    @dagger.Component.Builder
    interface Builder {
        @BindsInstance
        fun application(application: Application): Builder
        fun build(): ApplicationComponent
    }
}

Then ActivityBindingModule:

@Module
abstract class ActivityBindingModule {
    @ActivityScope
    @ContributesAndroidInjector(modules = [MainModule::class])
    abstract fun contributeHomeActivity(): HomeActivity
}

The MainModule for the HomeActivity, HomeActivity has four Fragment:

@Module
abstract class MainModule {
    @FragmentScope
    @ContributesAndroidInjector(modules = [HomeModule::class])
    abstract fun contributeHomeFragment(): HomeFragment
    ...
}

The HomeModule for the first HomeFragment:

@Module
class HomeModule {
    @FragmentScope
    @Provides
    fun provideHomeView(homeFragment: HomeFragment): HomeContract.HomeView {
        return homeFragment
    }
    @FragmentScope
    @Provides
    fun provideHomeModel(apiService: ApiService): HomeModel {
        return HomeModel(apiService)
    }
}

HomeFragment implement HomeContract.HomeView, and the constructor has @Inject annotation:

class HomeFragment @Inject constructor() : BaseFragment<HomePresenter>(), HomeContract.HomeView,
        SwipeRefreshLayout.OnRefreshListener, RecyclerScrollListener.OnLoadMoreListener {
    ...
}

BaseFragment inject the Presenter:

abstract class BaseFragment<P : IPresenter<*>> : DaggerFragment(), IView {
    @Inject
    lateinit var mPresenter: P
}

HomePresenter code:

class HomePresenter @Inject constructor(private val homeModel: HomeModel,
                                        private val homeView: HomeContract.HomeView,
                                        private val disposable: CompositeDisposable) :
        BasePresenter<HomeContract.HomeView, HomeContract.Model>(homeModel, disposable) {
    ...
}

But when i build the project, it still tips: HomeContract.HomeView cannot be provided without an @Provides-annotated method.

Like you said, the Activity inject View is ok. but in the fragment, it was compile error, i don’t know why?

Read more comments on GitHub >

github_iconTop Results From Across the Web

Android dagger cannot be provided without ... - Stack Overflow
In this way this application instance is bound inside the component. ... class ActivityModule { @ContributesAndroidInjector public abstract ...
Read more >
cannot be provided without an @Provides-annotated method ...
Coding example for the question cannot be provided without an @Provides-annotated method, A binding with matching key exists in component-kotlin.
Read more >
dagger/missing binding cannot be provided without an ...
WorkerParameters cannot be provided without an @Inject constructor or an @Provides-annotated method. public abstract interface AppComponent extends dagger.
Read more >
Dagger by Tutorials, Chapter 16: Dagger & Android | Kodeco ...
Activity cannot be provided without an @Inject constructor or an @Provides-annotated method. public abstract interface ApplicationComponent { ^ android.app.
Read more >
Dagger 2 annotations: can @Provides and @Binds coexist?
Theoretically, Dagger modules cannot simultaneously contain abstract and ... Note: @Provides annotated methods require a concrete class in order to ...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found