初心者の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アノテーションを使用する


RandomUserServiceRandomUserAdapterが必要であることを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をさらに学習し続けることができます。この一連の記事は、それがどのように機能するかを十分に理解しているはずです。

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


Source: https://habr.com/ru/post/J345898/


All Articles