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() {
}
}
特定の実装をとのインターフェースに「バインド」する必要があります@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();
}
}
依存関係として指定できるスコープコンポーネントは1つだけであることに注意してください。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に関する他のスタックオーバーフローの質問も確認してください。多くの情報が提供されています。たとえば、現在のDagger2構造はこの回答で指定されています。
ありがとう
Github、TutsPlus、Joe Steele、Froger MCS、Googleのガイドに感謝します。
また、この記事の執筆後に見つけたこの段階的な移行ガイドについても説明します。
そして、キリルによるスコープの説明のために。
公式ドキュメントにさらに詳しい情報があります。