Dagger 2 - 注入非Android类 [英] Dagger 2 - injecting non Android classes

查看:82
本文介绍了Dagger 2 - 注入非Android类的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在我的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 , for context

如果他们是的一部分@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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆