Just wanted to supplement @anton-kazakov's answer, to provide a way to supply activity/service context in addition to application context:
ApplicationContext
import javax.inject.Qualifier;
@Qualifier
public @interface ApplicationContext {
}
ServiceScope
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import javax.inject.Scope;
@Scope
@Retention(RetentionPolicy.RUNTIME)
public @interface ServiceScope {
}
ApplicationModule
@Module
public class ApplicationModule {
private MyApplication mMyApplication;
public ApplicationModule(@NonNull MyApplication myApplication) {
mMyApplication = myApplication;
}
@Singleton
@Provides
@NonNull
@ApplicationContext
public Context provideApplicationContext() {
return mMyApplication;
}
}
ServiceModule (or, activity etc.)
import dagger.Module;
import dagger.Provides;
@Module
public class ServiceModule {
private final MyService mMyService;
public ServiceModule(MyService myService) {
mMyService = myService;
}
@ServiceScope
@Provides
public Context provideContext() {
return mMyService;
}
}
ApplicationComponent
import javax.inject.Singleton;
import dagger.Component;
@Singleton
@Component(modules = {ApplicationModule.class})
public interface ApplicationComponent {
ServiceComponent newMyServiceComponent(ServiceModule serviceModule);
// This is optional, just putting here to show one possibility
void inject(BootCompleteReceiver bootCompleteReceiver);
}
ServiceComponent
import dagger.Subcomponent;
@ServiceScope
@Subcomponent(modules = {ServiceModule.class})
public interface ServiceComponent {
void inject(MyService myService);
}
Application
public class MyApplication extends Application {
private ApplicationComponent mApplicationComponent;
@Override
public void onCreate() {
// mApplicationComponent = DaggerApplicationModule.builder()
// .applicationModule(new ApplicationModule(this))
// .build();
super.onCreate();
}
/**
* Note: {@link ContentProvider#onCreate} is called before
* {@link Application#onCreate}, hence if you have a
* {@link ContentProvider}, inject here instead of
* in {@link Application#onCreate}.
* <p>
* https://stackoverflow.com/a/44413873
* <p>
* https://stackoverflow.com/questions/9873669/how-do-i-catch-content-provider-initialize
*
* @param base The base Context.
*/
@Override
protected void attachBaseContext(Context base) {
super.attachBaseContext(base);
mApplicationComponent = DaggerApplicationComponent.builder()
.applicationModule(new ApplicationModule(this))
.build();
}
public ApplicationComponent getApplicationComponent() {
return mApplicationComponent;
}
}
Service
import javax.inject.Inject;
public class MyService extends Service {
@Override
public void onCreate() {
((MyApplication) getApplicationContext())
.getApplicationComponent()
.newMyServiceComponent(new ServiceModule(this))
.inject(this);
super.onCreate();
}
}
References
https://dagger.dev/api/2.19/dagger/Component.html
https://dagger.dev/api/2.19/dagger/Module.html#subcomponents--