Dagger 2 - 注入非Android类

Rob*_*egg 3 java android dagger-2

Dagger 2在我的Android应用程序中恭维.我按以下方式设置它:

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);
}
Run Code Online (Sandbox Code Playgroud)

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);
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

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
  }
}
Run Code Online (Sandbox Code Playgroud)

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

所有这些工作以及我在AppComponent的模块中放入的任何内容,我都可以注入Activities, Fragments and ViewModels.

不过,我在那里我会需要一个案例utility类,这取决于Application,对contex-我用的是实用类在不同的地方.或者我将有一个Manager类,它取决于Application,或者需要来自AppModule的东西.但是,由于我在外面使用这些类,Activities, Fragments and ViewModels我不能只注入.我如何为我的utility类提供其依赖项和任何其他类型的类 - 比如经理类?

我的第一个想法是创造一种UtilityComponent和一种ManagerCompoent,但我不知道如何让他们在AppModuel我或通过我的任何事情AppComponent.

Dav*_*jak 8

请不要只是component.inject(myObject)用于一切.始终更喜欢构造函数注入,或者从可以执行其他设置步骤的模块提供构造函数注入..inject(myObject)适用于您无权访问构造函数的Framework组件.

我的第一个想法是创建一个UtilityComponent和一个ManagerCompoent,但我不知道如何让他们在AppModuel或我的AppComponent中使用它们.

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

但是,由于我在Activities,Fragments和ViewModels之外使用这些类,我不能只注入.

这与注射无关.你在谈论范围,听起来你的实用程序是一个@Singleton.您AppComponent是一个@Singleton范围组件,因此它也可以用来提供您的工具.

不过,我在那里我会需要一个实用工具类的情况下,依赖于Application,对于context

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


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

@Singleton public class MyUtil {

  private Application application;

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

}
Run Code Online (Sandbox Code Playgroud)

然后你可以将它注入你的活动,片段甚至其他工具......

@Singleton public class MyUtilWrapper {

  private MyUtil myUtil;

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

}
Run Code Online (Sandbox Code Playgroud)

您可以将一个或两个注入您的活动或片段......

@Inject MyUtil myUtil;
@Inject MyUtilWrapper myUtilWrapper;

void onCreate(..) {
  AndroidInjection.inject(this);
}
Run Code Online (Sandbox Code Playgroud)

不会需要任何模块,提供了一些方法,或组件,以提供简单的类.只需确保添加正确的范围!