Dagger 2によるAndroidへの依存注入

11559 ワード

依存注入このモード(モードはすでに腐っており,ここではもう一度腐っている)は,応用の各部分にデカップリングするために用いられる.アプリケーション開発をより拡張し、メンテナンスを容易にします.この文書では、Dagger 2を使用して依存を処理する方法を学びます.
概要
完全な機能を完了するには、オブジェクトが別のオブジェクトを必要とする場合、ここに依存があります.例えば、悟空は金箍棒で白骨精を三回打つことができ、筋闘雲で十万八千里を打つことができる.悟空は金箍棒と筋闘雲に依存している.悟空のオブジェクトにカチューシャを初期化したり、工場の方法でカチューシャを量産したりすることができます.依存注入を使用すると、これらの依存オブジェクトを初期化するために特別なクラスを必要としません.これによりデカップリングが実現された.
このチュートリアルでは、最新のDagger 2を使用します(現在のバージョンは2.2).こちらは公式サイトです.ここで最新のリリースを見つけることができます.
の準備を
Android Studioは必須です.その他:
1.Dagger 2ベース
注記:
  • @Moduleこのannotation修飾クラスは、依存
  • を提供するために特別に使用される.
  • @Providesこのannotation修飾の方法はModule類の中で
  • に用いられる.
  • @Injectは、annotation依存性(構築方法、field、または一般的な方法であってもよい)
  • に使用される.
  • @Componentは、@Moduleと注入橋梁
  • とを接続する.
    これらの名詞は非常に抽象的に見える.以下、少し説明します.反射に頼る不思議なところはない.ただ,初期化依存を単独で書く必要がある場所は他のフレームワークに取って代わったにすぎない.この依存関係には、私たちがよく書くコードが「プロファイル」に移行していることもあります.
    以前、依存注入のフレームワークは、プロファイルの依存関係を読み出し、反射的に依存オブジェクトを初期化し、呼び出し依存オブジェクトに値を割り当てる依存注入を処理していました.例えば、私たちは悟空類で金箍棒を初期化しました.
    public class Wukong {
        private Jingubang jingubang;
    
        public Wukong(){
            //   
            this.jingubang = Jingubang();
        }
    }

    その後、プロファイルを使用する依存注入が行われました(ここでは架空のファイルフォーマットです):
    <xml>
        <com.xiyou.Wukong>
            <dependency field="jingubang">
                <com.xiyou.Jingubang />
            </dependency>
        </com.xiyou.Wukong>
    </xml>

    悟空がカチューシャを使用すると、注入フレームに依存して自動的にカチューシャが初期化され、悟空に付与される.
    現在はDagger 2を使用しています.ここには言わざるを得ない牛Xの場所があります.Androidで使える資源なのでバックエンドほど多くありません.特に反射消費が大きい!したがって,Daggerはモバイル開発の省資源化のニーズを満たすために,反射を用いて依存注入を実現しなかった.コンパイル時に依存注入の関連コードを同時に生成する.コードを生成する根拠は、前述した注釈(annotation)およびこれらのannotationを使用するクラス、インタフェースである.
    まとめると、Daggerはあなたが悟空類に書く必要があるカチューシャ類の初期化コードを注釈に基づいて自動的に生成しました!ただし、この生成されたコードは、newを使用して初期化する方法よりも複雑である.
    Dagger 2開発手順
    象を冷蔵庫に入れるには全部でいくつかのステップに分けます.
  • は、依存および依存対象のクラス、悟空クラス、およびカチューシャクラスを定義する.「悟空類」と「金箍棒類」の構造関数は@Inject注釈で修飾されている.
  • @Module注記のクラスを定義します.一般的にXXXModuleと呼ばれます.中に書いてある@Provides注釈修飾の方法.これらの@Providesメソッドは、「悟空類」と「カチューシャ類」のオブジェクトを返します.例えば@Provides Wukong provideWukong(){ return new Wukong(); }
  • インターフェースを作成し、@Component注記で修飾します.一般的にはXXXComponentと呼ばれています.注入方法はvoid inject(Wukong wk);と書かれています.ここでWukongは一例にすぎない.注入する準備ができているクラスは、上記のパラメータのWukongクラスに代わることができます.
  • 注入が必要な場所に@Injectのfieldと書きます.

  • 最後に、Daggerは、上記の内容と最後の@Componentインタフェースに基づいてDaggerXXXComponentのタイプを生成し、このタイプを使用して注入を実現する.上記の1~3ステップは、依存する構成と理解できます.最後のXXXComponentは古いReflect方式に代わって注入を実現した.
        @Inject        `@Module` `provideXXX`          。
    Dagger                    。          。

    前に何度も述べた.Dagger 2のすごいところは,このライブラリが完全に反射することなく,コンパイル期間にコードを生成する方式で実現される依存注入にある.この特徴により、Android Studioの構成時に追加の作業が必要になります.
    ここでは、新しいAndroidアプリケーションを作成したと仮定します.次にbuild.gradleファイルを開き、Dagger 2の構成を一歩一歩完了します.
    3.Android Studioの構成
    最初のステップ、
    apply plugin: 'kotlin-android'             //    
    apply plugin: 'kotlin-android-extensions'  //   !!!

    なぜ新しいpluginを追加するのですか?これは、後で使用されるkaptおよびprovidedに対してサポートされる.gradle自体はこの2つの操作をサポートしていません.
    ステップ2、
    buildscript {
        ext.kotlin_version = '1.0.1-2'
        repositories {
            mavenCentral()
        }
        dependencies {
            classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
            classpath "org.jetbrains.kotlin:kotlin-android-extensions:$kotlin_version"
        }
    }

    ステップ3、
    dependencies {
        // ...   ...
        compile 'com.google.dagger:dagger:2.2'
        kapt 'com.google.dagger:dagger-compiler:2.2'
        provided 'javax.annotation:jsr250-api:1.0'
    }
  • dagger、私たちが使う正主.
  • dagger-compiler、コードを生成するために使用されます.
  • java.annotation,提供Dagger意外な注釈
  • 最後に、Gradleを同期します.
    Dagger 2の使用
    次はダガーが活躍する時だ.
    まず、私たちはすでに悟空と金箍棒を持っています.コードは次のとおりです.
    悟空:
    import javax.inject.Inject;
    
    /**
     * Created by uncle_charlie on 6/4/2016.
     */
    public class Wukong {
    
        @Inject
        JinGuBang jinGuBang;
    
        @Inject
        public Wukong() {
    
        }
    
        public String useJinGuBang() {
            return this.jinGuBang.use();
        }
    }

    カチューシャ:
    import javax.inject.Inject;
    
    /**
     * Created by uncle_charlie on 6/4/2016.
     */
    public class JinGuBang {
    
        @Inject
        public JinGuBang() {
    
        }
    
        public String use() {
            return "user Jing gu bang";
        }
    }
  • 悟空は金箍棒に依存するため、金箍棒属性は@Inject注釈修飾がある.
  • 両クラスともDagger作成が必要なため、コンストラクション関数には@Inject注記があります.

  • ステップ2、@Moduleクラスの作成@Module注釈のクラスを作成し、@Provides注釈修飾メソッドを追加します.これらのメソッドは、依存するオブジェクトを作成します.
    import dagger.Module;
    import dagger.Provides;
    
    /**
     * Created by uncle_charlie on 6/4/2016.
     */
    @Module
    public class XiYouModule {
        @Provides
    // @Singleton
        Wukong provideWukong() {
            return new Wukong();
        }
    
        @Provides
    // @Singleton
        JinGuBang provideJinGuBang() {
            return new JinGuBang();
        }
    }
  • @Singleton注記は、この依存オブジェクトがアプリケーションのライフサイクルに1つのインスタンスしかないことを示している.
  • この中の@Providesの方法と前に述べた@Injectの注釈の構造関数の2つは1つだけ書くことができます.

  • ステップ3、@Componentインターフェース、@Module@Injectを接続@Moduleおよび@Providesの方法は、依存対象を提供する.@Inject@Componentインタフェースに現れる場所は、注入が必要であることを示す場所(一般的にはfield)である.@Componentインタフェースは、彼らを接続するために使用されます.
    import android.app.Activity;
    import javax.inject.Singleton;
    import dagger.Component;
    
    /**
     * Created by uncle_charlie on 6/4/2016.
     */
    @Component(modules = {XiYouModule.class})
    @Singleton
    public interface XiYouComponent {
        void inject(Wukong wk);
        void inject(Activity a);
    }

    このうちinject()メソッドで使用されるオブジェクトは,@Injectのfieldを含む注入が必要なオブジェクトである.
    このインタフェースではinject()メソッドを使用しなくてもよいが、provideXXX()メソッドを使用すると後述する.
      :@Component           @Module  

    ステップ4、@Componentインタフェースを使用してオブジェクトを取得する
    前の手順では、依存オブジェクトと依存オブジェクトの関係が構成されています.次に、依存オブジェクトを取得して依存オブジェクトを注入します.
    public class MainActivity extends AppCompatActivity {
        private static final String TAG = "##MainActivity";
    
        @Inject
        Wukong wukong;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
    
            TextView welcomeTextView = (TextView) findViewById(R.id.welcome_textview);
            // 1
            XiYouComponent xiYouComponent = DaggerXiYouComponent
                    .builder()
                    // 2
                    .xiYouModule(new XiYouModule())
                    .build();
            xiYouComponent.inject(this);
            // 3
            welcomeTextView.setText(wukong.useJinGuBang());
        }
    }

    まず、主に属性@Inject Wukong wukong;に対してMainActivityで宣言された.ここでは依存関係を示した:このactivityは悟空に依存し,悟空の対象に注入する準備をしている.
  • Dagger 2はコンパイラで依存注入コードを自動的に生成するので、上のコードを追加する前にコンパイルする必要があります.DaggerXiYouComponentは、Daggerが私たちのXiYouModuleクラスに基づいて生成したコードです.
  • は、このステップでDaggerXiYouComponentbuilderXiYouModuleのインスタンスを追加する.このModuleが無パラメトリック関数のみを使用する場合は、create()の省略法を使用できます.以下のように簡単に書くことができます.
    DaggerXiYouComponent
                .builder()
                // 2
                //.xiYouModule(new XiYouModule())
                //.build()
                .create();

  • Componentインタフェースのオブジェクト呼び出しinject(this)メソッドの後に注入が完了する.したがって、@Inject Wukong wukong;のプロパティを直接使用してメソッドを呼び出すことができます.welcomeTextView.setText(wukong.useJinGuBang());は、最後にactivityにメソッドが返す文字を表示します.

  • コードを実行して、結果を見てみましょう.
    結論
    以上の内容は,何が依存されているか,何が@Moduleクラスに置かれているか(あるいは何が依存されているか,何が@Injectの無パラメトリック構造関数を追加しているか)に要約できる.依存性(@Injectプロパティ)がある場合は、@Componentインタフェースのinject()メソッドパラメータに何かを入れます.(または、@Injectのプロパティがあれば、@Componentインタフェースでprovideがオブジェクトとして使用されます).この要約は必ずしも厳密ではないが、基本的な使い方はすべて含まれている.
    依存注入は有用である.以上の内容はDagger 2依存注入の一部にすぎない.読者の皆さんは、注入やDaggerに依存する様々な使い方をよりよく理解するには、公式ドキュメントに基づいて練習する必要があります.