I have Shared Preferences
as a dagger singleton component. I need to inject it into background services like FirebaseInstanceService
. Here's 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);
}
}
It is used in this way:
<service android:name="com.fcm.InstanceIDListenerService">
<intent-filter>
<action android:name="com.google.firebase.INSTANCE_ID_EVENT" />
</intent-filter>
</service>
Should I use ((MyApp) getApplication()).getSingletonComponent().inject(this);
in the onTokenRefresh
listener? Is this the correct listener to inject dependencies?
With the @Inject annotation on the constructor, we instruct Dagger that an object of this class can be injected into other objects. Dagger automatically calls this constructor, if an instance of this class is requested.
Dagger automatically generates code that mimics the code you would otherwise have hand-written. Because the code is generated at compile time, it's traceable and more performant than other reflection-based solutions such as Guice. Note: Use Hilt for dependency injection on Android.
I know this question is old, but I've just been hitting my head on this over the last few hours, and found the solution.
With the new Dagger2 version, you can now have your application implement the HasServiceInjector interface, which lets you inject stuff into services.
A simple example:
1) Create your services 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 said 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 the example, but my actual use case was with FirebaseInstanceIdService as well. And this worked.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With