Dagger 2.x 가이드 (개정판 6) :
단계는 다음과 같습니다.
1) 추가 Dagger
귀하에 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:2.2.0'
classpath 'com.neenbedankt.gradle.plugins:android-apt:1.8' //added apt for source code generation
}
}
allprojects {
repositories {
jcenter()
}
}
.
apply plugin: 'com.android.application'
apply plugin: 'com.neenbedankt.android-apt' //needed for source code generation
android {
compileSdkVersion 24
buildToolsVersion "24.0.2"
defaultConfig {
applicationId "your.app.id"
minSdkVersion 14
targetSdkVersion 24
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.7' //needed for source code generation
compile fileTree(dir: 'libs', include: ['*.jar'])
compile 'com.android.support:appcompat-v7:24.2.1'
compile 'com.google.dagger:dagger:2.7' //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
종속성을 제공하는 클래스를 만듭니다 .
@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
주입 가능한 클래스를 얻기 위해 인터페이스를 제공 하는 클래스를 만듭니다 .
public interface AppContextComponent {
CustomApplication application(); //provision method
Context applicationContext(); //provision method
LocationManager locationManager(); //provision method
}
3.1.) 다음은 구현으로 모듈을 만드는 방법입니다.
@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
. 그렇지 않으면 범위가 지정되지 않으며 삽입 할 때마다 새 인스턴스를 받게됩니다.
3.2.) 주입 할 수있는 항목을 지정하는 응용 프로그램 범위 구성 요소를 만듭니다 ( injects={MainActivity.class}
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);
}
3.3.) 생성자를 통해 직접 생성 할 수 있고를 사용하여 재정의하고 싶지 않은 종속성의 경우 @Module
(예 : 구현 유형을 변경하기 위해 빌드 플레이버를 사용하는 경우) @Inject
주석이있는 생성자를 사용할 수 있습니다 .
public class Something {
OtherThing otherThing;
@Inject
public Something(OtherThing otherThing) {
this.otherThing = otherThing;
}
}
또한 @Inject
생성자 를 사용 하면 명시 적으로 호출하지 않고도 필드 주입을 사용할 수 있습니다 component.inject(this)
.
public class Something {
@Inject
OtherThing otherThing;
@Inject
public Something() {
}
}
이러한 @Inject
생성자 클래스는 모듈에서 명시 적으로 지정할 필요없이 동일한 범위의 구성 요소에 자동으로 추가됩니다.
@Singleton
범위 @Inject
생성자 클래스에서 볼 수됩니다 @Singleton
범위의 구성 요소.
@Singleton // scoping
public class Something {
OtherThing otherThing;
@Inject
public Something(OtherThing otherThing) {
this.otherThing = otherThing;
}
}
3.4.) 주어진 인터페이스에 대한 특정 구현을 정의한 후 다음과 같이하십시오.
public interface Something {
void doSomething();
}
@Singleton
public class SomethingImpl {
@Inject
AnotherThing anotherThing;
@Inject
public SomethingImpl() {
}
}
.NET Framework를 사용하여 인터페이스에 특정 구현을 "바인딩"해야합니다 @Module
.
@Module
public class SomethingModule {
@Provides
Something something(SomethingImpl something) {
return something;
}
}
Dagger 2.4 이후의 약어는 다음과 같습니다.
@Module
public abstract class SomethingModule {
@Binds
abstract Something something(SomethingImpl something);
}
4.)Injector
애플리케이션 수준 구성 요소를 처리 할 클래스를 만듭니다 (모 놀리 식을 대체 함 ObjectGraph
).
(참고 : APT Rebuild Project
를 사용하여 DaggerApplicationComponent
빌더 클래스 생성 )
public enum Injector {
INSTANCE;
ApplicationComponent applicationComponent;
private Injector(){
}
static void initialize(CustomApplication customApplication) {
ApplicationComponent applicationComponent = DaggerApplicationComponent.builder()
.appContextModule(new AppContextModule(customApplication))
.build();
INSTANCE.applicationComponent = applicationComponent;
}
public static ApplicationComponent get() {
return INSTANCE.applicationComponent;
}
}
5.)CustomApplication
수업 만들기
public class CustomApplication
extends Application {
@Override
public void onCreate() {
super.onCreate();
Injector.initialize(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.get().inject(this);
//customApplication is injected from component
}
}
8.) 즐기십시오!
+1.) 활동 수준 범위 구성 요소를Scope
만들 수있는 구성 요소를 지정할 수 있습니다 . 하위 범위를 사용하면 전체 응용 프로그램이 아닌 지정된 하위 범위에 대해서만 필요한 종속성을 제공 할 수 있습니다. 일반적으로 각 활동은이 설정으로 자체 모듈을 가져옵니다. 범위가 지정된 공급자 는 구성 요소별로 존재합니다 . 즉, 해당 활동에 대한 인스턴스를 유지하려면 구성 요소 자체가 구성 변경을 유지해야합니다. 예를 들어, 또는 모르타르 범위를 통해 생존 할 수 있습니다.onRetainCustomNonConfigurationInstance()
하위 범위 지정에 대한 자세한 내용 은 Google 가이드를 확인하세요 . 또한 제공 방법 및 구성 요소 종속성 섹션 에 대한이 사이트 와 여기를 참조하십시오 .
사용자 지정 범위를 만들려면 범위 한정자 주석을 지정해야합니다.
@Scope
@Retention(RetentionPolicy.RUNTIME)
public @interface YourCustomScope {
}
하위 범위를 만들려면 구성 요소에 범위를 지정 ApplicationComponent
하고 종속성으로 지정해야 합니다. 분명히 모듈 공급자 메서드에도 하위 범위를 지정해야합니다.
@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에서 다중 상속이 지원되지 않는 것과 똑같이 생각하십시오.
+2.) 정보 @Subcomponent
: 본질적으로 범위 @Subcomponent
는 구성 요소 종속성을 대체 할 수 있습니다. 그러나 주석 프로세서가 제공하는 빌더를 사용하는 대신 컴포넌트 팩토리 메소드를 사용해야합니다.
그래서 이거:
@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.get())
.customScopeModule(new CustomScopeModule())
.build();
이렇게됩니다 :
Injector.INSTANCE.newYourCustomScopedComponent(new CustomScopeModule());
+3.) : Dagger2에 관한 다른 Stack Overflow 질문도 확인하세요. 많은 정보를 제공합니다. 예를 들어, 현재 Dagger2 구조 가이 답변에 지정되어 있습니다.
감사
Github , TutsPlus , Joe Steele , Froger MCS 및 Google 의 가이드에 감사드립니다 .
또한 이 게시물을 작성한 후이 단계별 마이그레이션 가이드를 찾았습니다.
그리고 Kirill의 범위 설명 을 위해 .
공식 문서 에 더 많은 정보가 있습니다 .