问题
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.
回答1:
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 yourEventBus
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 yourApplication
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 theEventBus
component in theApplication
: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 thebus()
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
).
回答2:
After some discususins with Niek regarding my question, I went to the source to find my answer. I asked on the github repo of dagger 2, and the answer can be found here:
https://github.com/google/dagger/issues/128#issuecomment-86702574
Its very deliberate and posts different solutions to my issue.
来源:https://stackoverflow.com/questions/28871481/dagger-2-third-part-injection-android