名前はまだない。

プログラミングのことや趣味のことに関して綴ります。

AndroidでDI(依存性注入)やってみた

普段Springというサーバサイドフレームワークで開発している僕。
DIをAndroidでもやりたいなと思ってたので、Google謹製のdagger2を使ってみた。

DIとは?

こちらの記事で軽く概要を理解することが出来るはずです。

qiita.com

使用ライブラリ

dagger2

github.com

概念

まず、dagger2には以下の概念が存在する模様。

なんのことやら。
とりあえず必要なクラスたちを挙げてみた。

  • Module
  • Component
  • DIする対象のインターフェース(HelperクラスやControllerクラス)
  • 上記インターフェースの実装クラス

ModuleとComponenの関係に関しては以下の図を見るとなんとなく理解が出来るかも。

f:id:kobaken0029:20151125060310p:plain:w500

サンプルコード

こちらにサンプルプロジェクトを公開してあります。

github.com

ライブラリ追加

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の設計やスコープの問題に着手していこうと思っています。

参考サイト

Android: Dagger2でDIをする. 基本編 Part1 · Don't Stop The World