java - Dagger 2 - 注入(inject)非 Android 类

标签 java android dagger-2

我正在我的 Android 应用中实现 Dagger 2。我通过以下方式设置它:

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
  }
}

最后在 MyApplication.Java 中的 onCreate 方法中,我只是像这样调用 AppInjector:AppInjector.init(this );

所有这些都有效,我放入 AppComponent 模块中的任何内容,我都可以注入(inject)到 Activities、Fragments 和 ViewModels 中。

但是,在某些情况下,我需要一个 utility 类,它依赖于 Application,用于 contex - 我使用该实用程序在不同的地方上课。或者我将有一个 Manager 类,它依赖于应用程序,或者需要来自 AppModule 的某些东西。但是,由于我在 Activities、Fragments 和 ViewModels 之外使用这些类,所以我不能直接注入(inject)。我将如何为我的 utility 类提供它们的依赖项和任何其他类型的类——比如管理器类?

我的第一个想法是创建一个 UtilityComponent 和一个 ManagerCompoent 之类的,但是我不知道如何让它们与 AppModuel 中的任何东西一起工作 或通过我的 AppComponent

最佳答案

请不要只对所有内容使用 component.inject(myObject)。始终喜欢构造函数注入(inject)或从可以执行其他设置步骤的模块中提供它。 .inject(myObject) 适用于您无权访问构造函数的框架组件。

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.

您不需要单独的组件。见下文。

However, since I use these classes outside of Activities, Fragments and ViewModels I cannot just inject.

这与注入(inject)无关。你在谈论范围,听起来你的实用程序是 @Singleton。您的 AppComponent 是一个 @Singleton 作用域组件,因此它也可用于提供您的实用程序。

However, I have cases where I would need a utility class, that depends on Application, for context

如果它们是可以访问您的应用程序的 @Singleton 组件的一部分,那么它们也可以在其他任何地方提供。不需要更多的组件或任何东西。只需声明您的依赖关系,不要想太多。


只需声明您的 util,用 @Singleton 注释它并用 @Inject 标记构造函数以进行构造函数注入(inject)。 @Singleton 确保它将由您的 AppComponent 提供,并且可以访问它所依赖的 Application

@Singleton public class MyUtil {

  private Application application;

  @Inject public MyUtil(Application application) {
    this.application = application;
  }

}

然后您可以将它注入(inject)到您的 Activity、Fragments 中,甚至注入(inject)到其他实用程序中....

@Singleton public class MyUtilWrapper {

  private MyUtil myUtil;

  @Inject public MyUtilWrapper(MyUtil myUtil) {
    this.myUtil = myUtil;
  }

}

您可以将其中一个或两者注入(inject)到您的 Activity 或 fragment 中...

@Inject MyUtil myUtil;
@Inject MyUtilWrapper myUtilWrapper;

void onCreate(..) {
  AndroidInjection.inject(this);
}

不需要任何模块、方法或组件来提供简单的类。只需确保添加正确的范围即可!

关于java - Dagger 2 - 注入(inject)非 Android 类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46298107/

相关文章:

Java 大文件磁盘 IO 性能

java - 读取未知编码的文本行

android - Dagger 2 问题 : cannot be provided without a @Provides method

android - Dagger 2 : No implementation generated for component interface

java - 如何使用 Dagger2 实现工厂

java - 测试 MySql 数据库中字符串的编码和正确性

java - Maven 添加生成的文件夹(使用 Maven 插件)作为源文件夹,IntelliJ 无法识别

java - 检查 URL 在 Android 中是否有效而不捕获异常?

android - add 方法如何在 kotlin 中对 List<E> type val 起作用

android - 如何突出显示搜索词