AndroidでDI(依存性注入)やってみた
普段Springというサーバサイドフレームワークで開発している僕。
DIをAndroidでもやりたいなと思ってたので、Google謹製のdagger2を使ってみた。
DIとは?
こちらの記事で軽く概要を理解することが出来るはずです。
使用ライブラリ
dagger2
概念
まず、dagger2には以下の概念が存在する模様。
- @Inject 依存性の注入(はぁと)
- @Provides 依存性を解決するためのインスタンスを提供
- @Module インスタンスをProvideするためのメソッドたちを提供
- @Component InjectとModule間の関係を定義
なんのことやら。
とりあえず必要なクラスたちを挙げてみた。
- Module
- Component
- DIする対象のインターフェース(HelperクラスやControllerクラス)
- 上記インターフェースの実装クラス
ModuleとComponenの関係に関しては以下の図を見るとなんとなく理解が出来るかも。
サンプルコード
こちらにサンプルプロジェクトを公開してあります。
ライブラリ追加
dagger2を使用するためにgradleに依存性を記述していきます
ProjectRootのbuild.gradle
dependencies { classpath 'com.neenbedankt.gradle.plugins:android-apt:1.8' }
AppRootのbuild.gradle
apply plugin: 'com.neenbedankt.android-apt' // 略 dependencies { apt 'com.google.dagger:dagger-compiler:2.0.2' compile 'com.google.dagger:dagger:2.0.2' provided 'org.glassfish:javax.annotation:10.0-b28' }
DI環境作成
まずModuleから
@Module public class ApplicationModule { private final MyApplication mApplication; public ApplicationModule(MyApplication application) { mApplication = application; } @Provides @Singleton Context provideApplicationContext() { return mApplication.getApplicationContext(); } @Provides @Singleton SchoolIdol provideHoge() { return new Nozomi(); } }
続いてComponentを作成
@Singleton @Component(modules = ApplicationModule.class) public interface ApplicationComponent { void inject(MainActivity activity); }
そしてInject対象のインターフェースと実装クラスを作成
public interface SchoolIdol { String sing(String songName); void joinLive(int money); Context context(); }
public class Nozomi impliments SchoolIdol { @Override public String sing(String songName) { return songName.equals("僕らは○の中で") ? "楽しいだけじゃない 試されるだろう" : "わしわしMAXやで~"; } @Override public void joinLive(int money) { while (true) { if (finishedLive()) break; } goToYakiniku(money); } // ===以下略=== }
Injectしてみる
そしてこれをActivity or FragmentでInject!!
public class MainActivity { @Inject SchoolIdol nozomi; protected void onCreate(Bundle savedInstanceState) { DaggerApplicationComponent.builder() .applicationModule(new ApplicationModule(this)) .build() .inject(this); nozomi.sing("僕らは○の中で"); nozomi.joinLive(100000); } }
感想
Androidでもいつもやってる@Autowiredが出来たので灰テンションになりました!
DIについてはこれからも深堀していく予定。
ComponentやModuleの設計やスコープの問題に着手していこうと思っています。