如何设置DAGGER依赖注入从头Android项目? [英] How to set up DAGGER dependency injection from scratch in Android project?
问题描述
如何使用匕首?如何配置匕首在我的Android项目的工作?
How to use Dagger? How to configure Dagger to work in my Android project?
我想用匕首在我的Android项目,但我觉得迷惑。
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
您的AndroidManifest.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)您可以指定范围
为组件与您可以创建的活动级别范围的成分。 Subscopes允许您提供的依赖关系,你只只需要一个给定的子范围,而不是在整个应用程序。通常情况下,每个活动都有自己的模块,这种设置。请注意,一个作用域提供商存在的每个组件,这意味着为了保持实例的活动,本身要生存配置更改的组件。例如,它可以通过 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.
有关subscoping更多信息,请查看由谷歌的指导。另请参阅本网站关于计提方法,也是<一个HREF =http://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屋!