Java – inject dependencies into background services in Dagger2

inject dependencies into background services in Dagger2… here is a solution to the problem.

inject dependencies into background services in Dagger2

I have Shared Preferences as a Dagger singleton component. I need to inject it into a background service, such as FirebaseInstanceService. Here is my attempt :

public class InstanceIDListenerService extends FirebaseInstanceIdService {
    @Inject
    Preferences preferences;

@Override
    public void onTokenRefresh() {
        ((MyApp) getApplication()).getSingletonComponent().inject(this);
        String refreshedToken = FirebaseInstanceId.getInstance().getToken();
        preferences.setFcmToken(refreshedToken);

}
}

Its usage goes like this:

   <service android:name="com.fcm.InstanceIDListenerService">
            <intent-filter>
                <action android:name="com.google.firebase.INSTANCE_ID_EVENT" />
            </intent-filter>
   </service>

I should use ((MyApp) getApplication()).getSingletonComponent().inject(this) in the onTokenRefresh listener; Is it? Is this the right listener to inject dependencies?

Solution

I

know this issue is old, but I’ve been thinking about it for the last few hours and have found a solution.

With the new Dagger2 version, you can now enable your application to implement the HasServiceInjector interface, which allows you to inject content into your service.

A simple example:

1) Create your service module:

@Module
abstract class ServicesModule {

@ContributesAndroidInjector
  abstract SomeService ProvideSomeService();
}

2) Add it to your app component:

@Component(modules = {
  AndroidSupportInjectionModule.class,
  AppModule.class,
  ActivitiesModule.class,
  ServicesModule.class
})
public interface AppComponent {

@Component.Builder
  interface Builder {
    @BindsInstance
    Builder application(App application);

AppComponent build();
  }

void inject(App app);
}

3) Have your application implement the above interface:

public class App extends Application implements HasActivityInjector, HasServiceInjector {

@Inject
  DispatchingAndroidInjector<Activity> activityInjector;
  @Inject
  DispatchingAndroidInjector<Service> serviceInjector;

@Override
  public void onCreate() {
    super.onCreate();
    AppInjector.init(this);
  }

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

@Override
  public AndroidInjector<Service> serviceInjector() {
    return serviceInjector;
  }
}

4) Finally, inject your service:

public class SomeService extends Service {

@Inject
  SomeDependency dependency;

@Override
  public void onCreate() {
    AndroidInjection.inject(this);
    super.onCreate();
  }

 Do things with your dependencies

}

I’m using a service in my example, but my real-world use case is also using FirebaseInstanceIdService. And it worked.

Related Problems and Solutions