Reputation: 949
Hi im trying to figure out how to do a clean third party injection. I want to inject Otto bus properly into my services and activities. Iv seen that you can use inject on constructor, but since I dont have any constructor with Android, i wonder how I can then inject my bus.
Iv created a module which provides a new instance of the bus. Iv also created a component which has an interface for the Bus object.
But how can I get this injected and where should I initiate my graph?
Since the objectGraph from Dagger 1 is removed, i use the Dagger_.... component and create() in the application class, but how should I inject it into whatever activity or service?
Should I create the component in every onCreate and get the bus from there? Or is it possible to @Inject like Dagger 1? Please tell me because right now it seems much more clumpy and complicated than Dagger 1 way of doing it.
@Component(modules = EventBusModule.class)
@Singleton
public interface EventBus {
Bus bus();
}
@Module
public class EventBusModule {
@Provides
@Singleton
public Bus provideBus() {
return new Bus(ThreadEnforcer.ANY);
}
}
All i want to be able to do is:
public class WearService extends WearableListenerService {
private static final String TAG = WearService.class.getSimpleName();
@Inject
protected Bus bus;
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
bus.register(this);
return START_STICKY;
}
}
I look at this example(https://github.com/LiveTyping/u2020-mvp) and see that its possible, but not sure how things is hanging together.
Upvotes: 4
Views: 4601
Reputation: 100358
It is quite usual to instantiate the Dagger component in the Application
instance. Since you probably don't have a reference to your WearService
from your Application
class, you'll need to make the WearService
ask your Application
to provide the Bus
.
You can do this in two ways:
By adding an inject(WearService wearService)
method to your EventBus
component:
@Component(modules = EventBusModule.class)
@Singleton
public interface EventBus {
Bus bus();
void inject(WearService wearService);
}
You can now keep a reference to your Component in your Application
:
public class MyApplication extends Application {
private EventBus mEventBusComponent;
@Override
public void onCreate() {
super.onCreate();
mEventBusComponent = Dagger_EventBus.create();
}
public void inject(WearService wearService) {
mEventBusComponent.inject(wearService);
}
}
From your WearService
, ask your Application
to inject it:
public class WearService extends WearableListenerService {
private static final String TAG = WearService.class.getSimpleName();
@Inject
protected Bus bus;
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
((MyApplication) getApplicationContext()).inject(this);
bus.register(this);
return START_STICKY;
}
}
By retrieving the Bus
manually. Add a getter method for the EventBus
component in the Application
:
public class MyApplication extends Application {
private EventBus mEventBusComponent;
@Override
public void onCreate() {
super.onCreate();
mEventBusComponent = Dagger_EventBus.create();
}
public EventBus getEventBusComponent() {
return mEventBusComponent;
}
}
Then, in your WearService
, call the bus()
method:
public class WearService extends WearableListenerService {
private static final String TAG = WearService.class.getSimpleName();
private Bus bus;
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
bus = ((MyApplication) getApplicationContext()).getEventBusModule().bus();
bus.register(this);
return START_STICKY;
}
}
For injecting the Bus
into classes you can instantiate, you can use constructor injection:
public class MyClass() {
private final Bus mBus;
@Inject
public MyClass(final Bus bus) {
mBus = bus;
}
}
Since Dagger knows how to create a Bus
instance (because of your @Provides
method), Dagger will now also know how to create a MyClass
instance, no @Provides
method necessary. For example, this will work:
public class WearService extends WearableListenerService {
private static final String TAG = WearService.class.getSimpleName();
@Inject
protected Bus bus;
@Inject
protected MyClass myClass;
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
((MyApplication) getApplicationContext()).inject(this);
bus.register(this);
return START_STICKY;
}
}
The MyClass
instance will automatically be created for you, with the same instance of Bus
(since it is marked as @Singleton
).
Upvotes: 3