如何设置DAGGER依赖注入从头Android项目? [英] How to set up DAGGER dependency injection from scratch in Android project?

查看:152
本文介绍了如何设置DAGGER依赖注入从头Android项目?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如何使用匕首?如何配置匕首在我的Andr​​oid项目的工作?

How to use Dagger? How to configure Dagger to work in my Android project?

我想用匕首在我的Andr​​oid项目,但我觉得迷惑。

I'd like to use Dagger in my Android project, but I find it confusing.

编辑:!Dagger2也是出于2015年以后04 15,这是更加混乱

Dagger2 is also out since 2015 04 15, and it's even more confusing!

[这个问题是一个存根上,我增加了我的答案,因为我更多地了解了Dagger1,并详细了解Dagger2。这个问题更多的是指南,而不是一个问题。]

[This question is a "stub" on which I am adding to my answer as I learned more about Dagger1, and learn more about Dagger2. This question is more of a guide rather than a "question".]

推荐答案

指南匕首2.0 (修订版5)的:

的步骤如下:

1)添加匕首 build.gradle 文件:

  • 在顶层的 build.gradle

// Top-level build file where you can add configuration options common to all sub-projects/modules.

buildscript {
    repositories {
        jcenter()
    }
    dependencies {
        classpath 'com.android.tools.build:gradle:1.3.0'
        classpath 'com.neenbedankt.gradle.plugins:android-apt:1.4' //added apt for source code generation
    }
}

allprojects {
    repositories {
        jcenter()
    }
}

  • 在应用层面的 build.gradle
    • app level build.gradle:
    • apply plugin: 'com.android.application'
      apply plugin: 'com.neenbedankt.android-apt' //needed for source code generation
      
      android {
          compileSdkVersion 22
          buildToolsVersion "22.0.1"
      
          defaultConfig {
              applicationId "your.app.id"
              minSdkVersion 10
              targetSdkVersion 22
              versionCode 1
              versionName "1.0"
          }
          buildTypes {
              debug {
                  minifyEnabled false
                  proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
              }
              release {
                  minifyEnabled false
                  proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
              }
          }
      }
      
      dependencies {
          apt 'com.google.dagger:dagger-compiler:2.0.1' //needed for source code generation
          compile fileTree(dir: 'libs', include: ['*.jar'])
          compile 'com.android.support:appcompat-v7:21.0.3'
          compile 'com.google.dagger:dagger:2.0.1' //dagger itself
          provided 'org.glassfish:javax.annotation:10.0-b28' //needed to resolve compilation errors, thanks to tutplus.org for finding the dependency
      }
      

      2。)创建你的 AppContextModule 类,它提供的依赖。

      2.) Create your AppContextModule class that provides the dependencies.

      @Module //a module could also include other modules
      public class AppContextModule {
          private final CustomApplication application;
      
          public AppContextModule(CustomApplication application) {
              this.application = application;
          }
      
          @Provides
          public CustomApplication application() {
              return this.application;
          }
      
          @Provides 
          public Context applicationContext() {
              return this.application;
          }
      
          @Provides
          public LocationManager locationService(Context context) {
              return (LocationManager) context.getSystemService(Context.LOCATION_SERVICE);
          }
      }
      

      3。)创建 AppContextComponent 类,它提供的接口来获取的是可注射的类。

      3.) create the AppContextComponent class that provides the interface to get the classes that are injectable.

      public interface AppContextComponent {
          CustomApplication application(); //provision method
          Context applicationContext(); //provision method
          LocationManager locationManager(); //provision method
      }
      

      3.1)这是你将如何创建一个模块的实现:

      3.1.) This is how you would create a module with an implementation:

      @Module //this is to show that you can include modules to one another
      public class AnotherModule {
          @Provides
          @Singleton
          public AnotherClass anotherClass() {
              return new AnotherClassImpl();
          }
      }
      
      @Module(includes=AnotherModule.class) //this is to show that you can include modules to one another
      public class OtherModule {
          @Provides
          @Singleton
          public OtherClass otherClass(AnotherClass anotherClass) {
              return new OtherClassImpl(anotherClass);
          }
      }
      
      public interface AnotherComponent {
          AnotherClass anotherClass();
      }
      
      public interface OtherComponent extends AnotherComponent {
          OtherClass otherClass();
      }
      
      @Component(modules={OtherModule.class})
      @Singleton
      public interface ApplicationComponent extends OtherComponent {
          void inject(MainActivity mainActivity);
      }
      

      请注意::您需要提供 @Scope 标注(如 @Singleton @ActivityScope @Provides 注释的方法,让您的生成组件中的作用域提供者,否则>)将无范围,你会在每次注射时间得到一个新的实例。

      Beware:: You need to provide the @Scope annotation (like @Singleton or @ActivityScope) on the module's @Provides annotated method to get a scoped provider within your generated component, otherwise it will be unscoped, and you'll get a new instance each time you inject.

      3.2)。创建应用程序范围的组件,指定你可以注入什么(这是一样的注入= {MainActivity.class} 中的匕首1.x中):

      3.2.) Create an Application-scoped component that specifies what you can inject (this is the same as the injects={MainActivity.class} in Dagger 1.x):

      @Singleton
      @Component(module={AppContextModule.class}) //this is where you would add additional modules, and a dependency if you want to subscope
      public interface ApplicationComponent extends AppContextComponent { //extend to have the provision methods
          void inject(MainActivity mainActivity);
      }
      

      4。)创建一个注射器类来处理应用程序级的组件(它取代了单片 ObjectGraph

      4.) create an Injector class to handle your application-level component (it replaces the monolithic ObjectGraph)

      (注:重建项目以创建使用 DaggerApplicationComponent 生成器类APT)

      (note: Rebuild Project to create the DaggerApplicationComponent builder class using APT)

      public enum Injector {
          INSTANCE;
      
          private ApplicationComponent applicationComponent;
      
          private Injector(){
          }
      
          void initializeApplicationComponent(CustomApplication customApplication) {
              ApplicationComponent applicationComponent = DaggerApplicationComponent.builder()
                 .appContextModule(new AppContextModule(customApplication))
                 .build();
              this.applicationComponent = applicationComponent;
      
          }
      
          public ApplicationComponent getApplicationComponent() {
              return applicationComponent;
          }
      }
      

      5。)创建 CustomApplication

      public class CustomApplication
              extends Application {
          @Override
          public void onCreate() {
              super.onCreate();
              Injector.INSTANCE.initializeApplicationComponent(this);
          }
      }
      

      6。)添加 CustomApplication 的Andr​​oidManifest.xml

      <application
          android:name=".CustomApplication"
          ...
      

      7。)注入的类 MainActivity

      public class MainActivity
              extends AppCompatActivity {
          @Inject
          CustomApplication customApplication;
      
          @Override
          protected void onCreate(Bundle savedInstanceState) {
              super.onCreate(savedInstanceState);
              setContentView(R.layout.activity_main);
              Injector.INSTANCE.getApplicationComponent().inject(this);
              //customApplication is injected from component
          }
      }
      

      8。)享受!

      +1)您可以指定范围为组件与您可以创建的活动级别范围的成分。 Subscop​​es允许您提供的依赖关系,你只只需要一个给定的子范围,而不是在整个应用程序。通常情况下,每个活动都有自己的模块,这种设置。请注意,一个作用域提供商存在的每个组件,这意味着为了保持实例的活动,本身要生存配置更改的组件。例如,它可以通过 onRetainCustomNonConfigurationInstance生存(),或砂浆的范围。

      +1.) You can specify Scope for your components with which you can create Activity-level scoped components. Subscopes allow you to provide dependencies that you only need only for a given subscope, rather than throughout the whole application. Typically, each Activity gets its own module with this setup. Please note that a scoped provider exists per component, meaning in order to retain the instance for that activity, the component itself must survive configuration change. For example, it could survive through onRetainCustomNonConfigurationInstance(), or a Mortar scope.

      有关subscop​​ing更多信息,请查看由谷歌的指导。另请参阅本网站关于计提方法,也是<一个HREF =htt​​p://google.github.io/dagger/api/latest/dagger/Component.html>组件的依赖部分)和的这里

      For more info on subscoping, check out the guide by Google. Also please see this site about provision methods and also the component dependencies section) and here.

      要创建一个自定义的范围,您必须指定范围的限定词注释:

      To create a custom scope, you must specify the scope qualifier annotation:

      @Scope
      @Retention(RetentionPolicy.RUNTIME)
      public @interface YourCustomScope {
      }
      

      要创建一个子范围,你需要指定你的组件的范围,并指定 ApplicationComponent 作为它的依赖。显然,你需要指定的模块提供方法子范围了。

      To create a subscope, you need to specify the scope on your component, and specify ApplicationComponent as its dependency. Obviously you need to specify the subscope on the module provider methods too.

      @YourCustomScope
      @Component(dependencies = {ApplicationComponent.class}, modules = {CustomScopeModule.class})
      public interface YourCustomScopedComponent
              extends ApplicationComponent {
          CustomScopeClass customScopeClass();
      
          void inject(YourScopedClass scopedClass);
      }
      

      @Module
      public class CustomScopeModule {
          @Provides
          @YourCustomScope
          public CustomScopeClass customScopeClass() {
              return new CustomScopeClassImpl();
          }
      }
      

      请注意,只有一个范围的组件可以被指定为一个依赖。你可以把它酷似如何多重继承,不支持Java中。

      Please note that only one scoped component can be specified as a dependency. Think of it exactly like how multiple inheritance is not supported in Java.

      +2)关于 @Subcomponent :从本质上讲,一个范围的 @Subcomponent 可更换组件的依赖;但不是使用由注解处理器提供了一个建设者,你需要使用一个组件工厂方​​法。

      +2.) About @Subcomponent: essentially, a scoped @Subcomponent can replace a component dependency; but rather than using a builder provided by the annotation processor, you would need to use a component factory method.

      所以这样的:

      @Singleton
      @Component
      public interface ApplicationComponent {
      }
      
      @YourCustomScope
      @Component(dependencies = {ApplicationComponent.class}, modules = {CustomScopeModule.class})
      public interface YourCustomScopedComponent
              extends ApplicationComponent {
          CustomScopeClass customScopeClass();
      
          void inject(YourScopedClass scopedClass);
      }
      

      成为本:

      @Singleton
      @Component
      public interface ApplicationComponent {
          YourCustomScopedComponent newYourCustomScopedComponent(CustomScopeModule customScopeModule);
      }
      
      @Subcomponent(modules={CustomScopeModule.class})
      @YourCustomScope
      public interface YourCustomScopedComponent {
          CustomScopeClass customScopeClass();
      }
      

      和这样的:

      DaggerYourCustomScopedComponent.builder()
            .applicationComponent(Injector.INSTANCE.getApplicationComponent())
            .customScopeModule(new CustomScopeModule())
            .build();
      

      成为本:

      Injector.INSTANCE.newYourCustomScopedComponent(new CustomScopeModule());
      

      +3):您可以创建懒注射用 @注入懒&LT; T&GT; lazyT; 字段注射,然后调用 lazyT.get()来访问您的实例。它创建了一个仔细检查懒人实例从范围提供初始化它的实例,因此它是线程安全的。

      +3.): You can create lazy injection using @Inject Lazy<T> lazyT; field injections, then calling lazyT.get() to access your instance. It creates a double-checking Lazy instance that initializes its instance from the scoped provider, therefore it is threadsafe.

      延缓注入可以提高应用程序的启动时间。

      Lazy injection can improve application start-up time.

      注意:的,我个人也得到了一个僵局与它在应用程序启动,所以要知道自己在做什么的

      NOTE: I personally also managed to get a deadlock with it on app start, so be aware of what you are doing.

      +4):请检查其他堆栈溢出有关Dagger2还有问题,他们提供了大量的信息。例如,我目前Dagger2结构中指定这个答案

      +4.): Please check other Stack Overflow questions regarding Dagger2 as well, they provide a lot of info. For example, my current Dagger2 structure is specified in this answer.

      感谢

      感谢您的导游在 Github上,<一个href="http://$c$c.tutsplus.com/tutorials/dependency-injection-with-dagger-2-on-android--cms-23345">TutsPlus, <一href="https://github.com/joesteele/dagger2-component-scopes-test/blob/master/app/src/main/java/net/joesteele/daggercomponentstest/MainActivity.java">Joe斯蒂尔, Froger MCS 和的谷歌

      Thank you for the guides at Github, TutsPlus, Joe Steele, Froger MCS and Google.

      也因为这个一步,我写这篇文章后发现,

      而对于范围的解释由基里尔的。

      官方文档。

      这篇关于如何设置DAGGER依赖注入从头Android项目?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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