Java – Activity Context cannot be provided using Dagger 2

Activity Context cannot be provided using Dagger 2… here is a solution to the problem.

Activity Context cannot be provided using Dagger 2

Resolved

I’m new to Dagger 2 and I’m trying to provide an Activity Context for a class without success. I searched a lot but didn’t find any suitable answers.

I can provide application context. But I also need to provide an Activity Context, but I don’t know of any good way to implement it.

I

need to clarify that I’m using Dagger as an Android dependency.

def dagger_version = "2.24"
implementation "com.google.dagger:dagger:$dagger_version"
annotationProcessor "com.google.dagger:dagger-compiler:$dagger_version"
implementation "com.google.dagger:dagger-android:$dagger_version"
implementation "com.google.dagger:dagger-android-support:$dagger_version"
annotationProcessor "com.google.dagger:dagger-android-processor:$dagger_version"

I also only have one AppComponent with the following code:

@Singleton
@Component(
        modules = {
                AndroidSupportInjectionModule.class,
                ActivityBuildersModule.class,
                AppModule.class,
                ViewModelFactoryModule.class,
        }
)
public interface AppComponent extends AndroidInjector<BaseApplication> {

SessionManager sessionManager();

@Component.Builder
    interface Builder{

@BindsInstance
        Builder application(Application application);

AppComponent build();
    }
}

Except that each of my activities has a module, I didn’t find a way to inject the activity context for AppComponent or from ActivityModule.

What is the right thing to do?

Update

I finally found the right way.

First I created a module for the class I wanted to provide

@Module
public class AlertsModule {

@Provides
    static Alerts provideAlerts(Activity activity){
        return new Alerts(activity);
    }

}

Then I go to the ActivityModules I want to inject into that custom class and do a similar binding

@Module
public abstract class MainActivityModule {

...

@Binds
    abstract Activity providesActivity(MainActivity activity);

...

}

Finally, I

included CustomClassModule in my ActivityBuildersModule, where I used @ContributesAndroidInjector to provide my activities.

    @MainScope
    @ContributesAndroidInjector(
            modules = {
                    AlertsModule.class,
            }
    )
    abstract MainActivity contributeMainActivity();

Solution

You can bind a (bind) activity instance in the same way as the current bind (bind) application instance by using the @Component.Builder or @Component.Factory

An example implementation looks like this:

@Subcomponent(...)
interface ActivitySubcomponent {

@Subcomponent.Factory
    interface Factory {
        ActivitySubcomponent create(@BindsInstance MyActivity activity)
    }
}
@Module(subcomponents = [ActivitySubcomponent.class])
class ApplicationModule {
    ....
}
public class MyActivity extends Activity {

@Override
    public void onCreate(Bundle savedInstanceState) {
        ...
        ((MyApplication) getApplication())
            .applicationComponent
            .activitySubcomponentFactory()
            .create(this)
            .inject(this)
    }
}

Related Problems and Solutions