Android Dagger 2ゼロ単列(3)@Scopeから
5880 ワード
転送は出典を明記してください.https://www.jianshu.com/p/b26024bc3107Android界で最も殺傷力のあるナイフとして、Dagger 2は、このシリーズの文章で最も通俗的な言語でその正体を明らかにします. 边缘OB:零単排から低分局から高分局まで、First BloodからHoly Shitまで、Rampage(暴走)は何も言わない! Android Dagger 2ゼロ単列(一)基礎注釈 Android Dagger 2ゼロ単列(二)@Qualifier Android Dagger 2ゼロ単列(三)@Scope Android Dagger 2ゼロ単列(四)DependenciesとSubComponent
前編では限定識別子@Qualifierの使用について詳しく紹介したが,本稿では役割ドメイン@Scopeの用途を検討し,役割範囲やライフサイクルとしても理解できる. @Scopeは注釈にのみ使用できます.@Scopeで役割ドメイン注釈をカスタマイズし、提供される依存ライフサイクルを制御し、提供される依存がビューのライフサイクルと同じ、ローカル、またはグローバルの単一例などになるようにする必要があります.例1、まず例を見てみましょう.
ゼロ単列(一)から見た印象があるはずですが、これは例2に基づいてActivity注入コードを修正したもので、mBusは2回注入し、1回のアドレス値を印刷すると、2回のアドレス値が異なり、注入に依存するたびにインスタンスが新規作成されますが、注入するたびに返されるインスタンスが同じだと思いますか?まず、BusクラスでBusインスタンスを維持し、静的メソッドを書くことができます.インスタンスが空でない限り、このインスタンスを返すたびに、依存する場所で直接この静的メソッドを呼び出すことができます.このような乱暴な解決に感心します.もし現在複数のActivityがある場合、Activityごとに独立した単一の例が要求されますか?実はもっと霊的な解決策があるのは@Scope注釈です.@Scope注記をカスタマイズします.
@Componentコメントのインタフェースにカスタムコメントを追加します.
@Moduleクラスの@Provides方注のメソッドにも追加されます.
このとき再コンパイル実行すると,驚くべきことに,アドレス値が同じ,すなわち2回注入したインスタンスが同じであることが分かった.実は何度も注入しても、一度に複数注入しても、彼らは同じ例です! また、構築方法提供依存の方式であれば、Module提供Bus依存の方法注釈をBusクラスに@SignLocalを注記し、効果は同じです.
@Scope注記この時点では、提供された依存がコンテナのライフサイクルと同じになり、コンテナが依存をキャッシュする単一の例が実現されます. @Scopeは相対性があり、構築方法または@Provides方法で注釈した場合、@Componentインタフェースには必ず注釈が必要です.@Componentインタフェースの注釈は,必ずしも構造方法や@Provides方法が注釈されなければならないとは限らない.抽象クラスには必ずしも抽象的な方法があるとは限らないが、抽象的な方法があれば抽象クラスでなければならない. @Scopeは、@Qualifierと同様に独自のメンバー変数を持つことも可能であり、デフォルトでもvalueであり、同様のデータ型も基本データ型、String、Enum、Classであり、その1次元配列タイプを含むが、比較的少ない.次に、ModuleがBus依存を提供する方法に@SignLocalを追加していない場合、Busクラスに@SignLocalを注釈するとどうなるかという問題を示します.
このような状況依存は@Providesから提供され、Busクラスの@SignLocal注釈の加算と非加算は同じであり、結果としてインスタンスが再作成されるたびに行われる.@Scope注記@Providesメソッドを使用する場合、@Providesを使用して提供される依存性が有効になります.@Scope注釈クラスでは,@Inject注釈を用いた構築方法への依存が有効となる.さらに、Activity注入時に同じParkingComponentインスタンスが使用されていることに注意して、コードを変更すると、次のようになります.
2回のParkingComponentインスタンスは再生成され、この時点で再実行、&^%$#@!,@SignLocalも役に立たない!実は、これこそ正常で、依存を提供する容器はすべて異なって、提供する依存はまたどのように同じことができます!次に、ローカル・インスタンスとグローバル・インスタンスの定義を引き出します.@Scope注釈を付けたインスタンスは、同じコンテナに対してのみ使用されるため、このコンテナをどのように維持するかに重点を置いていることがわかります. 例二、ユーザー登録のシーンをシミュレートしてローカル単例の概念を深める.コードが多すぎる.ここではすべて貼らない.プロセス全体を説明するだけだ.シミュレート登録のLoginActivity登録に成功した場合、ApplicationでUserComponentをメンテナンスし、登録を終了するときにUserComponentを空にし、このときUserComponentが提供するユーザー情報Userは、ライフサイクルは登録後からログアウトまでである.またこの期間は単例であり,Demoに対応する例2を見ることができる. 例3,グローバル単例をシミュレートするには,Applicationで@Componentを1つ維持するだけであり,その後注入する際には,いずれもApplicationから注入を取得するが,容器のグローバル一意性のため,毎回注入する例は同じであるが,例はParkingComponentの初期化手法をApplicationに移動しただけであるため,文章に貼らず,対応するDemoの例3を見ることができる.さらに、例3で使用されている注釈は@Singletonです.これは@Scopeのデフォルト実装クラスです.実際には、私たちがカスタマイズした注釈とは違いません.まったく意味のない文字を定義してもいいです.コードを見ている人があなたを地面に強く押して摩擦しようとする可能性があります.実は私が言いたいのは、すべてのカスタマイズされた@Scopeが上記の機能を実現することができ、異なる@Scope注釈の最大の役割は実は可読性を高めるためであり、Singletonがグローバル単例を表し、ByActivityがActivityのライフサイクル内を表すなど、この@Componentコンテナがどこで使われているかがわかります.最後に,@Scopeの役割は,提供される依存ライフサイクルをコンテナのライフサイクルと同じように制御し,局所的な単例またはグローバル単例を実現することである.Scope注釈の名前は可読性を高めるためなので、名前をつけるときは、必ず簡潔にしなければなりません.@Retention(RetentionPolicy.RUNTIME)カスタム注釈をつけるかどうか、誰も私の顔を殴ってくれない...しばらくの観念はやはり前の1篇と同じで、コンパイルの期间はすでに関连を生成して、プラスしてもプラスしても何の区别もなくて、もし间违いがあるならば、伝言の指摘を歓迎します.
DemoソースカットdaggerThreeパケット名 Dagger 2 GitHubアドレス Dagger 2公式サイトアドレス すべてのテストインスタンスは2.15バージョンに基づいています.次の記事では、DependenciesとSubComponentの使用について検討します.
前編では限定識別子@Qualifierの使用について詳しく紹介したが,本稿では役割ドメイン@Scopeの用途を検討し,役割範囲やライフサイクルとしても理解できる. @Scopeは注釈にのみ使用できます.@Scopeで役割ドメイン注釈をカスタマイズし、提供される依存ライフサイクルを制御し、提供される依存がビューのライフサイクルと同じ、ローカル、またはグローバルの単一例などになるようにする必要があります.例1、まず例を見てみましょう.
public class Bus {
private String driver;
public Bus(String driver) {
this.driver = driver;
}
}
public class ParkingActivity extends Activity {
@Inject
Bus mBus;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_dagger);
ParkingComponent component = DaggerParkingComponent.builder().parkingModule(new ParkingModule(" ")).build();
component.inject(this);
((TextView) findViewById(R.id.text)).setText(" = " + mBus.toString());
component.inject(this);
((TextView) findViewById(R.id.text2)).setText(" = " + mBus.toString());
}
}
@Component(modules = ParkingModule.class)
public interface ParkingComponent {
void inject(ParkingActivity activity);
}
@Module
public class ParkingModule {
private String driver;
public ParkingModule(String driver) {
this.driver = driver;
}
@Provides
public String provideDriver() {
return driver;
}
@Provides
public Bus provideBus(String driver) {
return new Bus(driver);
}
}
ゼロ単列(一)から見た印象があるはずですが、これは例2に基づいてActivity注入コードを修正したもので、mBusは2回注入し、1回のアドレス値を印刷すると、2回のアドレス値が異なり、注入に依存するたびにインスタンスが新規作成されますが、注入するたびに返されるインスタンスが同じだと思いますか?まず、BusクラスでBusインスタンスを維持し、静的メソッドを書くことができます.インスタンスが空でない限り、このインスタンスを返すたびに、依存する場所で直接この静的メソッドを呼び出すことができます.このような乱暴な解決に感心します.もし現在複数のActivityがある場合、Activityごとに独立した単一の例が要求されますか?実はもっと霊的な解決策があるのは@Scope注釈です.@Scope注記をカスタマイズします.
@Scope
public @interface SignLocal {
}
@Componentコメントのインタフェースにカスタムコメントを追加します.
@SignLocal
@Component(modules = ParkingModule.class)
public interface ParkingComponent {
void inject(ParkingActivity activity);
}
@Moduleクラスの@Provides方注のメソッドにも追加されます.
@SignLocal
@Provides
public Bus provideBus(String driver) {
return new Bus(driver);
}
このとき再コンパイル実行すると,驚くべきことに,アドレス値が同じ,すなわち2回注入したインスタンスが同じであることが分かった.実は何度も注入しても、一度に複数注入しても、彼らは同じ例です! また、構築方法提供依存の方式であれば、Module提供Bus依存の方法注釈をBusクラスに@SignLocalを注記し、効果は同じです.
@SignLocal
public class Bus {
private String driver;
@Inject
public Bus(String driver) {
this.driver = driver;
}
}
@Scope注記この時点では、提供された依存がコンテナのライフサイクルと同じになり、コンテナが依存をキャッシュする単一の例が実現されます. @Scopeは相対性があり、構築方法または@Provides方法で注釈した場合、@Componentインタフェースには必ず注釈が必要です.@Componentインタフェースの注釈は,必ずしも構造方法や@Provides方法が注釈されなければならないとは限らない.抽象クラスには必ずしも抽象的な方法があるとは限らないが、抽象的な方法があれば抽象クラスでなければならない. @Scopeは、@Qualifierと同様に独自のメンバー変数を持つことも可能であり、デフォルトでもvalueであり、同様のデータ型も基本データ型、String、Enum、Classであり、その1次元配列タイプを含むが、比較的少ない.次に、ModuleがBus依存を提供する方法に@SignLocalを追加していない場合、Busクラスに@SignLocalを注釈するとどうなるかという問題を示します.
@Provides
public Bus provideBus(String driver) {
return new Bus(driver);
}
@SignLocal
public class Bus {
...
}
このような状況依存は@Providesから提供され、Busクラスの@SignLocal注釈の加算と非加算は同じであり、結果としてインスタンスが再作成されるたびに行われる.@Scope注記@Providesメソッドを使用する場合、@Providesを使用して提供される依存性が有効になります.@Scope注釈クラスでは,@Inject注釈を用いた構築方法への依存が有効となる.さらに、Activity注入時に同じParkingComponentインスタンスが使用されていることに注意して、コードを変更すると、次のようになります.
@Override
protected void onCreate(Bundle savedInstanceState) {
...
ParkingComponent component = DaggerParkingComponent.builder().parkingModule(new ParkingModule(" ")).build();
component.inject(this);
((TextView) findViewById(R.id.text)).setText(" = " + mBus.toString());
ParkingComponent component1 = DaggerParkingComponent.builder().parkingModule(new ParkingModule(" ")).build();
component1.inject(this);
((TextView) findViewById(R.id.text2)).setText(" = " + mBus.toString());
}
2回のParkingComponentインスタンスは再生成され、この時点で再実行、&^%$#@!,@SignLocalも役に立たない!実は、これこそ正常で、依存を提供する容器はすべて異なって、提供する依存はまたどのように同じことができます!次に、ローカル・インスタンスとグローバル・インスタンスの定義を引き出します.@Scope注釈を付けたインスタンスは、同じコンテナに対してのみ使用されるため、このコンテナをどのように維持するかに重点を置いていることがわかります. 例二、ユーザー登録のシーンをシミュレートしてローカル単例の概念を深める.コードが多すぎる.ここではすべて貼らない.プロセス全体を説明するだけだ.シミュレート登録のLoginActivity登録に成功した場合、ApplicationでUserComponentをメンテナンスし、登録を終了するときにUserComponentを空にし、このときUserComponentが提供するユーザー情報Userは、ライフサイクルは登録後からログアウトまでである.またこの期間は単例であり,Demoに対応する例2を見ることができる. 例3,グローバル単例をシミュレートするには,Applicationで@Componentを1つ維持するだけであり,その後注入する際には,いずれもApplicationから注入を取得するが,容器のグローバル一意性のため,毎回注入する例は同じであるが,例はParkingComponentの初期化手法をApplicationに移動しただけであるため,文章に貼らず,対応するDemoの例3を見ることができる.さらに、例3で使用されている注釈は@Singletonです.これは@Scopeのデフォルト実装クラスです.実際には、私たちがカスタマイズした注釈とは違いません.まったく意味のない文字を定義してもいいです.コードを見ている人があなたを地面に強く押して摩擦しようとする可能性があります.実は私が言いたいのは、すべてのカスタマイズされた@Scopeが上記の機能を実現することができ、異なる@Scope注釈の最大の役割は実は可読性を高めるためであり、Singletonがグローバル単例を表し、ByActivityがActivityのライフサイクル内を表すなど、この@Componentコンテナがどこで使われているかがわかります.最後に,@Scopeの役割は,提供される依存ライフサイクルをコンテナのライフサイクルと同じように制御し,局所的な単例またはグローバル単例を実現することである.Scope注釈の名前は可読性を高めるためなので、名前をつけるときは、必ず簡潔にしなければなりません.@Retention(RetentionPolicy.RUNTIME)カスタム注釈をつけるかどうか、誰も私の顔を殴ってくれない...しばらくの観念はやはり前の1篇と同じで、コンパイルの期间はすでに関连を生成して、プラスしてもプラスしても何の区别もなくて、もし间违いがあるならば、伝言の指摘を歓迎します.
DemoソースカットdaggerThreeパケット名 Dagger 2 GitHubアドレス Dagger 2公式サイトアドレス すべてのテストインスタンスは2.15バージョンに基づいています.次の記事では、DependenciesとSubComponentの使用について検討します.