[英]Dagger 2 - injecting non Android classes
I'm implimenting Dagger 2
in my Android app. 我在我的Android应用程序中恭维
Dagger 2
。 I have it setup in the following way: 我按以下方式设置它:
AppComponent.java AppComponent.java
@Singleton
@Component(modules = {
AndroidInjectionModule.class,
AndroidSupportInjectionModule.class,
ActivityBuilder.class,
AppModule.class,
DataBaseDaoModule.class
})
public interface AppComponent {
@Component.Builder
interface Builder {
@BindsInstance
Builder application(Application aApplication);
AppComponent build();
}
Application application();
void inject(MyApplication aApplication);
}
AppInjector.java AppInjector.java
ublic class AppInjector {
public static void init(MyApplication aApplication) {
//Initialize dagger and inject the aApplication
DaggerAppComponent.builder().application(aApplication).build().inject(aApplication);
aApplication.registerActivityLifecycleCallbacks(new Application.ActivityLifecycleCallbacks() {
@Override
public void onActivityCreated(Activity aActivity, Bundle aBundle) {
handleActivity(aActivity);
}
@Override
public void onActivityStarted(Activity aActivity) {
}
@Override
public void onActivityResumed(Activity aActivity) {
}
@Override
public void onActivityPaused(Activity aActivity) {
}
@Override
public void onActivityStopped(Activity aActivity) {
}
@Override
public void onActivitySaveInstanceState(Activity aActivity, Bundle aBundle) {
}
@Override
public void onActivityDestroyed(Activity aActivity) {
}
});
}
private static void handleActivity(Activity aActivity) {
if (aActivity instanceof HasActivityInjector) {
AndroidInjection.inject(aActivity);
Timber.d("injected Activity");
}
if (aActivity instanceof FragmentActivity) {
((FragmentActivity) aActivity).getSupportFragmentManager()
.registerFragmentLifecycleCallbacks(
new FragmentManager.FragmentLifecycleCallbacks() {
@Override
public void onFragmentCreated(FragmentManager fm, Fragment f,
Bundle savedInstanceState) {
if (f instanceof Injectable) {
Timber.d("injected Fragment");
AndroidSupportInjection.inject(f);
}
}
}, true);
}
}
}
AppModule.java AppModule.java
Module(includes = ViewModelModule.class)
class AppModule {
@Singleton
@Provides
ApiService providesApiService(OkHttpClient aClient, MyInterceptor aInterceptor) {
//Build a Retrofit object here
}
@Singleton
@Provides
OkHttpClient providesOkHTTPClient(MyInterceptor aInterceptor) {
//Setup OKHTTP here
}
}
And finally in MyApplication.Java in the onCreate
method I just call the AppInjector
like so: AppInjector.init(this);
最后在
onCreate
方法的MyApplication.Java中,我只是像这样调用AppInjector
: AppInjector.init(this);
All of this works and anything I put in my AppComponent's moduels, I can inject into Activities, Fragments and ViewModels
. 所有这些工作以及我在AppComponent的模块中放置的任何内容,我都可以注入
Activities, Fragments and ViewModels
。
However, I have cases where I would need a utility
class, that depends on Application
, for contex
- and I use the utility class in various places. 但是,我有一些情况需要一个
utility
类,它依赖于Application
,用于contex
- 我在各个地方使用实用程序类。 Or I will have a Manager
class, that depends on Application, or needs something from AppModule. 或者我将有一个
Manager
类,它取决于Application,或者需要来自AppModule的东西。 However, since I use these classes outside of Activities, Fragments and ViewModels
I cannot just inject. 但是,由于我在
Activities, Fragments and ViewModels
之外使用这些类Activities, Fragments and ViewModels
我不能只注入。 How would I provide my utility
classes with their dependencies and any other type of class - like a manager class? 我如何为我的
utility
类提供它们的依赖项和任何其他类型的类 - 比如管理器类?
My first thought was to create a UtilityComponent
and a ManagerCompoent
of sorts, however I have no idea how I would get them to work with anything in AppModuel
or through my AppComponent
. 我的第一个想法是创建一个
UtilityComponent
和一个ManagerCompoent
,但我不知道如何让他们在AppModuel
或我的AppComponent
。
Please don't just use component.inject(myObject)
for everything. 请不要只使用
component.inject(myObject)
。 Always prefer constructor injection or provide it from a module where you can do additional setup steps. 始终更喜欢构造函数注入,或者从可以执行其他设置步骤的模块提供构造函数注入。
.inject(myObject)
is intended for Framework components where you don't have access to the constructor. .inject(myObject)
适用于您无权访问构造函数的Framework组件。
My first thought was to create a UtilityComponent and a ManagerCompoent of sorts, however I have no idea how I would get them to work with anything in AppModuel or through my AppComponent.
我的第一个想法是创建一个UtilityComponent和一个ManagerCompoent,但我不知道如何让他们在AppModuel或我的AppComponent中使用它们。
You don't need a separate component for that. 您不需要单独的组件。 See below.
见下文。
However, since I use these classes outside of Activities, Fragments and ViewModels I cannot just inject.
但是,由于我在Activities,Fragments和ViewModels之外使用这些类,我不能只注入。
That has nothing to do with injection. 这与注射无关。 You're talking about scopes, and it sound like your utilities are a
@Singleton
. 你在讨论范围,听起来你的工具是
@Singleton
。 Your AppComponent
is a @Singleton
scoped component, hence it can be used to provide your utils, too. 你
AppComponent
是@Singleton
域组件,因此它可以用来提供您utils的,太。
However, I have cases where I would need a utility class, that depends on
Application
, forcontext
但是,我有一些情况需要一个实用程序类,它取决于
Application
,用于context
If they are part of the @Singleton
component, which has access to your Application, they can also be provided anywhere else. 如果它们是可以访问您的应用程序的
@Singleton
组件的一部分,那么它们也可以在其他任何地方提供。 No need for more components or anything. 无需更多组件或任何东西。 Just declare your dependencies and don't overthink it.
只需声明你的依赖关系,不要过度思考它。
Just declare your util, annotate it with @Singleton
and mark the constructor with @Inject
for constructor injection. 只需声明你的util,用
@Singleton
注释它,并使用@Inject
标记构造函数以进行构造函数注入。 @Singleton
ensures that it will be provided by your AppComponent
and can access the Application
on which it depends. @Singleton
确保它将由您的AppComponent
提供,并可以访问它所依赖的Application
。
@Singleton public class MyUtil {
private Application application;
@Inject public MyUtil(Application application) {
this.application = application;
}
}
And then you can just inject it in your Activities, Fragments, or even into other Utilities.... 然后你可以将它注入你的活动,片段甚至其他工具......
@Singleton public class MyUtilWrapper {
private MyUtil myUtil;
@Inject public MyUtilWrapper(MyUtil myUtil) {
this.myUtil = myUtil;
}
}
And you can inject either or both into your activity or fragment... 您可以将一个或两个注入您的活动或片段......
@Inject MyUtil myUtil;
@Inject MyUtilWrapper myUtilWrapper;
void onCreate(..) {
AndroidInjection.inject(this);
}
You do not need any modules, provides methods, or components to provide simple classes. 你不需要任何模块,提供了一些方法,或组件,以提供简单的类。 Just make sure to add the right scope!
只需确保添加正确的范围!
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.