Dagger 2 - 注入非Android类 [英] Dagger 2 - injecting non Android classes
问题描述
我在我的Android应用中恭维 Dagger 2
。我按以下方式设置它:
I'm implimenting Dagger 2
in my Android app. I have it setup in the following way:
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
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
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
}
}
最后在 onCreate
方法的 MyApplication.Java 中我只是像这样调用 AppInjector
: AppInjector.init(this);
And finally in MyApplication.Java in the onCreate
method I just call the AppInjector
like so: AppInjector.init(this);
所有这些工作以及我放在AppComponent的模块中的任何内容,我都可以注入 Activities,Fragments和ViewModels
。
All of this works and anything I put in my AppComponent's moduels, I can inject into Activities, Fragments and ViewModels
.
但是,我的情况是需要一个实用程序
类,这取决于应用程序
,对于 contex
- 我在各个地方使用实用程序类。或者我将有一个 Manager
类,它取决于Application,或者需要来自AppModule的东西。但是,由于我在 Activities,Fragments和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. Or I will have a Manager
class, that depends on Application, or needs something from AppModule. However, since I use these classes outside of Activities, Fragments and ViewModels
I cannot just inject. How would I provide my utility
classes with their dependencies and any other type of class - like a manager class?
我的第一个想法是创建一个 UtilityComponent
和一个 ManagerCompoent
各种各样,但我不知道如何让他们在 AppModuel
或通过我的 AppComponent
。
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
.
推荐答案
请不要只使用 component.inject(myObject)
为了一切。始终更喜欢构造函数注入,或者从可以执行其他设置步骤的模块中提供构造函数。 .inject(myObject)
适用于您无权访问构造函数的Framework组件。
Please don't just use component.inject(myObject)
for everything. 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.
我的第一个想法是创建一个UtilityComponent和一个ManagerCompoent,但我不知道如何让他们在AppModuel或我的AppComponent中使用它们。
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.
您不需要单独的组件。见下文。
You don't need a separate component for that. See below.
但是,由于我在Activities,Fragments和ViewModels之外使用这些类,我不能只注入。
However, since I use these classes outside of Activities, Fragments and ViewModels I cannot just inject.
这与注射无关。你在讨论范围,听起来你的工具是 @Singleton
。您的 AppComponent
是 @Singleton
作用域组件,因此它也可用于提供您的工具。
That has nothing to do with injection. You're talking about scopes, and it sound like your utilities are a @Singleton
. Your AppComponent
is a @Singleton
scoped component, hence it can be used to provide your utils, too.
但是,我有需要实用程序类的情况,这取决于
Application
, forcontext
如果他们是的一部分@Singleton
组件,可以访问您的应用程序,也可以在其他任何地方提供。无需更多组件或任何东西。只需声明你的依赖关系,不要过度思考它。
If they are part of the @Singleton
component, which has access to your Application, they can also be provided anywhere else. No need for more components or anything. Just declare your dependencies and don't overthink it.
只需声明你的util,用 @Singleton
并使用 @Inject
标记构造函数以进行构造函数注入。 @Singleton
确保它将由您的 AppComponent
提供,并且可以访问应用程序
取决于它。
Just declare your util, annotate it with @Singleton
and mark the constructor with @Inject
for constructor injection. @Singleton
ensures that it will be provided by your AppComponent
and can access the Application
on which it depends.
@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!
这篇关于Dagger 2 - 注入非Android类的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!