この記事は、著者によると、 依存関係とDagger 2フレームワークの実装を理解できない、またはそれをやろうとしている人を対象とした一連の記事の第7部です。 オリジナルは2017年12月30日に書かれました。 無料翻訳。
これは、
初心者のAndroid開発者向けのDagger 2シリーズの7番目の記事です。 前のものを読んでいない場合、
ここにいます。
一連の記事
一連の記事の前半
サンプルプロジェクトを見て、Dagger 2と注釈を使用した依存関係の注入を使用して、強い結び付きをなくそうとしました。
また、3つの新しい注釈についても検討しました。 単一のインスタンス
(シングルトン)でオブジェクトを作成する
@Scope 。
@Namedは、同じタイプのオブジェクトを提供するメソッドを分離します。
@Qualifierの代替としての
@Named複数のComponent作成
前の記事では、アプリケーションレベルの依存関係を作成しました。 しかし、依存関係が
Activityレベルにのみ必要な場合はどうでしょうか。
Activityはライフサイクルで作成および破棄されますが、依存関係はどうなりますか?
Activity内で作成された依存関係は、
Activityとともに破棄されます。
最善の解決策は、ライフサイクルが異なるオブジェクト用に個別のモジュールとコンポーネントを作成することです。
これを説明するために、以前検討したプロジェクトに新しいオブジェクトを追加したくありません。 代わりに、
MainActivityを別個のオブジェクトと
MainActivity 、独自のモジュールとコンポーネントを作成します。
Dagger2Part2 ブランチを見てください 。
ステップ1. Activityレベルエリアの作成
今後の変更のために、
MainActivityFeatureという別のパッケージを作成しました。
MainActivity新しい
スコープを作成します。
@Scope public @interface MainActivityScope {}
ステップ2. MainActivityコンポーネントを作成する
次に、
MainActivity用に別の
コンポーネントを作成し、新しく作成した注釈でマークします。
@Component(dependencies = RandomUserComponent.class) @MainActivityScope public interface MainActivityComponent { RandomUserAdapter getRandomUserAdapter(); RandomUsersApi getRandomUserService(); }
MainActivityComponentを参照できるようにする必要があります。これには、
dependencies属性が使用されます。 つまり、この属性は、追加の依存関係が必要な場合に、Dagger 2に
RandomUserComponentを呼び出すように
RandomUserComponentします。
この例では、
Activityレベルで、API用のアダプターと
RandomUsersAPIを呼び出すオブジェクトが必要
RandomUsersAPI 。 したがって、
getRandomUserAdapter()および
getRandomUserService()メソッドを実装します。

ステップ3. MainActivityモジュールを作成する
次に、アダプターを提供するモジュールを作成します。
@Module public class MainActivityModule { private final MainActivity mainActivity; public MainActivityModule(MainActivity mainActivity) { this.mainActivity = mainActivity; } @Provides @MainActivityScope public RandomUserAdapter randomUserAdapter(Picasso picasso){ return new RandomUserAdapter(mainActivity, picasso); } }
注:アダプターを介した
MainActivity実装はオプションであり、例としてこれを行いました。
Picassoコンテキストが必要な場合は、
holder.imageView.getContext()使用できます。
注釈
@MainActivityScope注意して
@MainActivityScope 。これは
randomUserAdapter()メソッドに追加され、依存関係の範囲を
Activityレベルに制限します。
このモジュールを対応するコンポーネントにマップすることも必要です。
modules属性を使用し
modules 。
@Component(modules = MainActivityModule.class, dependencies = RandomUserComponent.class) @MainActivityScope public interface MainActivityComponent { RandomUserAdapter getRandomUserAdapter(); RandomUsersApi getRandomUserService(); }

ステップ4. Applicationクラスの作成
public class RandomUserApplication extends Application {
Applicationから継承されたこのクラスには、すべてのアプリケーションレベルの依存関係
RandomUserApplicationComponentが含まれています。
ステップ5. MainActivity
プロジェクトをビルドすると、Dagger 2は
DaggerMainActivityComponentクラスを生成します。
Activityレベルの依存関係を使用するには、アプリケーションレベルの依存関係を取得する必要があります。
public class MainActivity extends AppCompatActivity { ... @Override protected void onCreate(Bundle savedInstanceState) { .... MainActivityComponent mainActivityComponent = DaggerMainActivityComponent.builder() .mainActivityModule(new MainActivityModule(this)) .randomUserComponent(RandomUserApplication.get(this).getRandomUserApplicationComponent()) .build(); randomUsersApi = mainActivityComponent.getRandomUserService(); mAdapter = mainActivityComponent.getRandomUserAdapter(); .... } }
注:プロジェクトブランチの
afterActivityLevelComponent()メソッドを見て
ください 。
ステップ6.おめでとうございます
かなりサポートされたコードを作成しました。 彼らは、
Activityレベルの依存関係を作りました。 おめでとうございます。
しかし、コンポーネントに50個の依存関係がある場合はどうでしょうか?
本当に多くの依存関係がある場合、以下のような式を絶えず書く必要がありますか?
randomUserApi = mainActivityComponent.getRandomUserService();
mAdapter = mainActivityComponent.getRandomUserAdapter();
…これは自分にとって重要ではないと判断できますが、この問題の解決策があります。
@Injectアノテーションを使用する
RandomUserServiceと
RandomUserAdapterが必要であることをDagger 2に伝える代わりに、Dagger 2に@Injectアノテーションでマークしたフィールドを処理させます。
以下のようにクラスを変更することで、できるだけ早く
@Injectアノテーションの使用を開始できます。
次のスレッドで完全な例
を見ることができ
ます 。
MainActivityComponent
getRandomUserService()および
getRandomUserAdapter()メソッドを削除し、
getRandomUserService()を実装するメソッドを追加しましょう。
@Component(modules = MainActivityModule.class, dependencies = RandomUserComponent.class) @MainActivityScope public interface MainActivityComponent { void injectMainActivity(MainActivity mainActivity); }
MainActivity
public class MainActivity extends AppCompatActivity { .... @Inject RandomUsersApi randomUsersApi; @Inject RandomUserAdapter mAdapter; .... @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); ..... MainActivityComponent mainActivityComponent = DaggerMainActivityComponent.builder() .mainActivityModule(new MainActivityModule(this)) .randomUserComponent(RandomUserApplication.get(this).getRandomUserApplicationComponent()) .build(); mainActivityComponent.injectMainActivity(this); .... } }
どのように機能しますか? Dagger 2は、戻り値(
void )のないメソッドを見つけると、クラスに必要なものがあることを認識します。つまり、
@Injectアノテーションでマークされたフィールドをクラスで初期化します。
必要なもの! これでコードを実行できます。
まとめ
Activityレベルでの依存性注入の例を見てみました。
@Injectアノテーションの使用例も見ました。
結論として
この一連の記事を読んでサポートしてくれてありがとう。 依存関係とDagger 2についての洞察が得られることを願っています。この一連の記事を書いた理由は、さまざまなブログで多くの記事を読んでDagger 2の知識を向上させたが、あなたのための記事。 したがって、私はすべての読者に可能な限りの方法で彼らの知識を共有することを勧めます。 私はダガー2の専門家ではありません。自分は学生だと思っています。
これでDagger 2をさらに学習し続けることができます。この一連の記事は、それがどのように機能するかを十分に理解しているはずです。
他のリソースへのリンク(英語)