この記事は、著者によると、 依存関係と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をさらに学習し続けることができます。この一連の記事は、それがどのように機能するかを十分に理解しているはずです。
他のリソースへのリンク(英語)