初心者のAndroid開発者向けの短剣2。 ダガー2.アドバンス。 パート2

この記事は、著者によると、 依存関係Dagger 2フレームワークの実装を理解できない、またはそれをやろうとしている人を対象とした一連の記事の第7部です。 オリジナルは2017年12月30日に書かれました。 無料翻訳。



ダガー2アドバンストパート2画像



これは、 初心者の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 { //       private RandomUserComponent randomUserApplicationComponent; public static RandomUserApplication get(Activity activity){ return (RandomUserApplication) activity.getApplication(); } @Override public void onCreate() { super.onCreate(); Timber.plant(new Timber.DebugTree()); randomUserApplicationComponent = DaggerRandomUserComponent.builder() .contextModule(new ContextModule(this)) .build(); } public RandomUserComponent getRandomUserApplicationComponent(){ return randomUserApplicationComponent; }
      
      





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



アノテーションでマークされたフィールドをクラスで初期化します。



必要なもの! これでコードを実行できます。

GIF
画像



まとめ



Activity



レベルでの依存性注入の例を見てみました。 @Inject



アノテーションの使用例も見ました。



結論として



この一連の記事を読んでサポートしてくれてありがとう。 依存関係とDagger 2についての洞察が得られることを願っています。この一連の記事を書いた理由は、さまざまなブログで多くの記事を読んでDagger 2の知識を向上させたが、あなたのための記事。 したがって、私はすべての読者に可能な限りの方法で彼らの知識を共有することを勧めます。 私はダガー2の専門家ではありません。自分は学生だと思っています。



これでDagger 2をさらに学習し続けることができます。この一連の記事は、それがどのように機能するかを十分に理解しているはずです。



他のリソースへのリンク(英語)






All Articles