欧美一级特黄大片做受成人-亚洲成人一区二区电影-激情熟女一区二区三区-日韩专区欧美专区国产专区

dagger2怎么用

這篇文章主要為大家展示了“dagger2怎么用”,內(nèi)容簡而易懂,條理清晰,希望能夠幫助大家解決疑惑,下面讓小編帶領(lǐng)大家一起研究并學(xué)習(xí)一下“dagger2怎么用”這篇文章吧。

創(chuàng)新互聯(lián)服務(wù)項(xiàng)目包括尉氏網(wǎng)站建設(shè)、尉氏網(wǎng)站制作、尉氏網(wǎng)頁制作以及尉氏網(wǎng)絡(luò)營銷策劃等。多年來,我們專注于互聯(lián)網(wǎng)行業(yè),利用自身積累的技術(shù)優(yōu)勢、行業(yè)經(jīng)驗(yàn)、深度合作伙伴關(guān)系等,向廣大中小型企業(yè)、政府機(jī)構(gòu)等提供互聯(lián)網(wǎng)行業(yè)的解決方案,尉氏網(wǎng)站推廣取得了明顯的社會效益與經(jīng)濟(jì)效益。目前,我們服務(wù)的客戶以成都為中心已經(jīng)輻射到尉氏省份的部分城市,未來相信會繼續(xù)擴(kuò)大服務(wù)區(qū)域并繼續(xù)獲得客戶的支持與信任!

前言

Dagger 這個(gè)庫的取名不僅僅來自它的本意“匕首”,同時(shí)也暗示了它的原理。Jake Wharton 在對 Dagger 的介紹中指出,Dagger 即 DAG-er,這里的 DAG 即數(shù)據(jù)結(jié)構(gòu)中的 DAG——有向無環(huán)圖(Directed Acyclic Graph)。也就是說,Dagger 是一個(gè)基于有向無環(huán)圖結(jié)構(gòu)的依賴注入庫,因此Dagger的使用過程中不能出現(xiàn)循環(huán)依賴。

Android開發(fā)從一開始的MVC框架,到MVP,到MVVM,不斷變化?,F(xiàn)在MVVM的data-binding還在實(shí)驗(yàn)階段,傳統(tǒng)的MVC框架Activity內(nèi)部可能包含大量的代碼,難以維護(hù),現(xiàn)在主流的架構(gòu)還是使用MVP(Model + View + Presenter)的方式。但是 MVP 框架也有可能在Presenter中集中大量的代碼,引入DI框架Dagger2 可以實(shí)現(xiàn) Presenter 與 Activity 之間的解耦,Presenter和其它業(yè)務(wù)邏輯之間的解耦,提高模塊化和可維護(hù)性。

現(xiàn)在的公司項(xiàng)目用到了Dagger2,之前只是稍微了解一些,沒有用過,然后查了查資料,整理如下,方便快速上手

四個(gè)基本注解

1、@Inject 主要有兩個(gè)作用,一個(gè)是使用在構(gòu)造函數(shù)上,通過標(biāo)記構(gòu)造函數(shù)讓Dagger2來使用(Dagger2通過Inject標(biāo)記可以在需要這個(gè)類實(shí)例的時(shí)候來找到這個(gè)構(gòu)造函數(shù)并把相關(guān)實(shí)例new出來)從而提供依賴,另一個(gè)作用就是標(biāo)記在需要依賴的變量讓Dagger2為其提供依賴。

@Inject注解的字段不能是private和protected的

2、@Module 用Module標(biāo)注的類是專門用來提供依賴的。有的人可能有些疑惑,看了上面的@Inject,需要在構(gòu)造函數(shù)上標(biāo)記才能提供依賴,那么如果我們需要提供的類構(gòu)造函數(shù)無法修改怎么辦,比如一些jar包里的類,我們無法修改源碼。這時(shí)候就需要使用Module了。Module可以給不能修改源碼的類提供依賴,當(dāng)然,能用Inject標(biāo)注的通過Module也可以提供依賴。

這里需要注意,Module和Inject這兩個(gè)注解還是有區(qū)別的,@Inject使用在構(gòu)造函數(shù)上的時(shí)候,這個(gè)構(gòu)造函數(shù)有沒有參數(shù)都可以,如果有參數(shù)的話這個(gè)Module也需要有其他Module或者@Inject構(gòu)造函數(shù)提供實(shí)例,適合在提供該類自己的時(shí)候使用。但是如果用@Module的話,@Module注解的這個(gè)類需要有默認(rèn)無參構(gòu)造函數(shù)(顯示隱式都可以),否則會報(bào)“”xxx must be set”。如果沒有默認(rèn)無參構(gòu)造函數(shù),就需要手動把這個(gè)Module的實(shí)例傳入Component,一般在MVP模式里使用該方式,用來提供Activity實(shí)例給Presenter實(shí)例。

所以,如果該類只需要提供自己,建議直接使用@Inject函數(shù),如果是用來提供其他類的實(shí)例,建議使用@Module的方式。

3、@Provides 用Provides來標(biāo)注一個(gè)方法,該方法可以在需要提供依賴時(shí)被調(diào)用,從而把預(yù)先提供好的對象當(dāng)做依賴給標(biāo)注了@Inject的變量賦值。provides主要用于標(biāo)注Module里的方法。

4、@Component 一般用來標(biāo)注接口,被標(biāo)注了Component的接口在編譯時(shí)會產(chǎn)生相應(yīng)的類的實(shí)例來作為提供依賴方和需要依賴方之間的橋梁,把相關(guān)依賴注入到其中。

四個(gè)擴(kuò)展注解

1、@Qulifier 這里有個(gè)概念,叫依賴迷失,就是在Module注解的類里,有2個(gè)Provides都提供某個(gè)類的實(shí)例,這時(shí)候不用@Qulifier注解的話Component會不知道用哪個(gè)實(shí)例,這時(shí)候就要使用@Qulifier,下面直接提供代碼

@Qualifier
@Retention(RetentionPolicy.RUNTIME)
public @interface A {}
@Qualifier
@Retention(RetentionPolicy.RUNTIME)
public @interface B {}
@Module
public class SimpleModule {
 @Provides
 @A
 Cooker provideCookerA(){
 return new Cooker("James","Espresso");
 }

 @Provides
 @B
 Cooker provideCookerB(){
 return new Cooker("Karry","Machiato");
 }
}
public class ComplexMaker implements CoffeeMaker {
 Cooker cookerA;
 Cooker cookerB;
 @Inject
 public ComplexMaker(@A Cooker cookerA,@B Cooker cookerB){
 this.cookerA = cookerA;
 this.cookerB = cookerB;
 }
}

2、@Named 和@Qulifier一樣,并且@Named就是繼承@Qulifier的,而且用起來比@Qulifier方便,示例代碼如下:

@Module
public class MainModule {
 @Provides
 @Named("red")
 public Cloth getRedCloth() {
 Cloth cloth = new Cloth();
 cloth.setColor("紅色");
 return cloth;
 }

 @Provides
 @Named("blue")
 public Cloth getBlueCloth() {
 Cloth cloth = new Cloth();
 cloth.setColor("藍(lán)色");
 return cloth;
 }

 @Provides
 public Clothes getClothes(@Named("blue") Cloth cloth){
 return new Clothes(cloth);
 }
}
public class MainActivity extends AppCompatActivity {
 ...
 @Inject
 @Named("red")
 Cloth redCloth;
 @Inject
 @Named("blue")
 Cloth blueCloth;
 @Override
 protected void onCreate(Bundle savedInstanceState) {
 ...
 tv.setText("我現(xiàn)在有" + redCloth + "和" + blueCloth );
 }
}

3、@Scope 局部單例,意思就是在被注入類里只有一個(gè)該類的實(shí)例,局部范圍是啥,那就是它生命周期范圍內(nèi)。直接上代碼

//PerActivity.java
@Scope
@Retention(RetentionPolicy.RUNTIME)
public @interface PerActivity {}
//ActivityModule.java
@Module
public class ActivityModule {
 @Provides
 CoffeeShop provideCoffeeShop(){
 return CoffeeShop.getInstance();//一個(gè)普通的單例
 }

 /**
 * 直接在這里說結(jié)果,@PerActivity是用@Scope注解的,除了在這里注解還需要在用到該Module類的Component的類名上方也要注解,然后該實(shí)例在注入到某個(gè)類里的時(shí)候用同一個(gè)Component就會不管有幾個(gè)字段都會只有一個(gè)實(shí)例。注意:如果用不同的Component實(shí)例的話仍然會新的CookerFactory實(shí)例,單例CookerFactory只存在一個(gè)Component實(shí)例里。所以叫局部單例。
 */
 @Provides
 @PerActivity
 CookerFactory provideCookerFactory(){
 return new CookerFactory();
 }

 @Provides
 CookerFactoryMulty provideCookerFactoryMulty(){
 return new CookerFactoryMulty();//非單例
 }
}
//CoffeeShop.java
public class CoffeeShop {
 private static CoffeeShop INSTANCE;
 private CoffeeShop(){
 Log.d("TAG","CoffeeShop New Instance");
 }

 public static CoffeeShop getInstance(){
 if(INSTANCE == null){
 INSTANCE = new CoffeeShop();
 }
 return INSTANCE;
 }
}

//CookerFactory.java
public class CookerFactory {
 public CookerFactory(){
 Log.d("TAG","CookerFactory New Instance");
 }
}

//CookerFactoryMulty.java
public class CookerFactoryMulty {
 public CookerFactoryMulty(){
 Log.d("TAG","CookerFactoryMulty New Instance");
 }
}
//除了在Module的Provides方法里寫上@Scope還需要在Component類名上方寫上,這里自定義的@Scope名字叫PerActivity
@PerActivity
@Component(modules = {ActivityModule.class})
public interface ActivityComponent {
 void inject(MainActivity simpleActivity);
}
public class MainActivity extends Activity {
 ActivityComponent activityComponent;
 @Inject
 CoffeeShop coffeeShop1;

 @Inject
 CoffeeShop coffeeShop2;

 @Inject
 CookerFactory cookerFactory1;

 @Inject
 CookerFactory cookerFactory2;

 @Inject
 CookerFactoryMulty cookerFactoryMulty1;

 @Inject
 CookerFactoryMulty cookerFactoryMulty2;

 @Override
 protected void onCreate(Bundle savedInstanceState) {
 super.onCreate(savedInstanceState);
 setContentView(R.layout.activity_main);
 activityComponent = DaggerActivityComponent.builder()
 //下面這句話可以不寫,因?yàn)镸odule有默認(rèn)構(gòu)造函數(shù)。如果Module的構(gòu)造器里有參數(shù),并且該參數(shù)不是注入進(jìn)去的,就需要用類似下面的方法手動設(shè)置實(shí)例到Component中
 .activityModule(provideModule())
 .applicationComponent(MyApplication.getComponent()).build();
 activityComponent.inject(this);
 coffeeFactory.run();
 }
 
 private ActivityModule provideModule(){
 return new ActivityModule();
 }
}

運(yùn)行結(jié)果

07-11 16:53:27.978 1927-1927/? D/TAG﹕ CoffeeShop New Instance
07-11 16:53:27.978 1927-1927/? D/TAG﹕ CookerFactory New Instance
07-11 16:53:27.978 1927-1927/? D/TAG﹕ CookerFactoryMulty New Instance
07-11 16:53:27.978 1927-1927/? D/TAG﹕ CookerFactoryMulty New Instance

@Singleton 該注解繼承@Scope,用的時(shí)候區(qū)別就是不用去自定義@Scope了,比如上面定義@PerActivity的這步就不需要了,其他的用法和使用@PerActivity一模一樣,也是在Component類名上面和Module的Provides方法里都寫上注解。

注意注意注意:再次提醒,局部單例是在同一個(gè)Component實(shí)例提供依賴的前提下才有效的,不同的Component實(shí)例只能通過Component依賴才能實(shí)現(xiàn)單例。也就是說,你雖然在兩個(gè)Component接口上都添加了PerActivity注解或者Singleton注解,但是這兩個(gè)Component提供依賴時(shí)是沒有聯(lián)系的,他們只能在各自的范圍內(nèi)實(shí)現(xiàn)單例
在@Inject標(biāo)注的構(gòu)造器上使用局部單例直接在類名上聲明作用范圍(類名上添加@Singleton或自定義Scope)

依賴:dependencies

Component依賴Component的情況下,兩個(gè)Component的@Scope不能相同,否則會編譯錯(cuò)誤,為什么這么設(shè)計(jì)我還不是很清楚,有知道的小伙伴請告訴我謝謝。

依賴的示例代碼如下:

//Person.java
public class Person {
}

//PerActivity.java
@Scope
@Retention(RetentionPolicy.RUNTIME)
public @interface PerActivity {}

//BaseModule.java
@Module
public class BaseModule {

 @Singleton
 @Provides
 public Person providePerson(){
 return new Person();
 }
}

//Module1.java
@Module
public class Module1 {

}

//Module2.java
@Module
public class Module2 {

}

//BaseComponent.java
@Singleton
@Component(modules = BaseModule.class)
public interface BaseComponent {
 public Person providePerson();
}

//Component1.java
@PerActivity
//@Singleton
//因?yàn)橐蕾嚕╠ependencies)的BaseComponent中用到了@Singleton,所以這個(gè)Component就不能再用了,否則會編譯錯(cuò)誤,為什么這么設(shè)計(jì)還不是很清楚
@Component(modules = Module1.class,dependencies = BaseComponent.class)
public interface Component1 {
 void inject(TestScopeActivity1 simpleActivity);
}

//Component2.java
@PerActivity
//@Singleton 為什么不能用?原理同上
@Component(modules = Module2.class,dependencies = BaseComponent.class)
public interface Component2 {
 void inject(TestScopeActivity2 simpleActivity);
}

//MyApplication.java
public class MyApplication extends Application {

 private static BaseComponent baseComponent;

 @Override
 public void onCreate() {
 super.onCreate();
 baseComponent = DaggerBaseComponent.builder().build();
 }

 public static BaseComponent getBaseComponent() {
 return baseComponent;
 }
}

//TestScopeActivity1.java
public class TestScopeActivity1 extends Activity {

 @Inject
 Person p = null;

 @Override
 protected void onCreate(Bundle savedInstanceState) {
 super.onCreate(savedInstanceState);
 setContentView(R.layout.activity_main);
 DaggerComponent1.builder().baseComponent(MyApplication.getBaseComponent()).build().inject(this);
 TextView textView = findViewById(R.id.textView);
 textView.setText(p.toString());
 textView.setOnClickListener(new View.OnClickListener() {
  @Override
  public void onClick(View v) {
  startActivity(new Intent(TestScopeActivity1.this,TestScopeActivity2.class));
  }
 });
 }
}

//TestScopeActivity2.java
public class TestScopeActivity2 extends Activity {

 @Inject
 Person p = null;

 @Override
 protected void onCreate(Bundle savedInstanceState) {
 super.onCreate(savedInstanceState);
 setContentView(R.layout.activity_main);
 DaggerComponent2.builder().baseComponent(MyApplication.getBaseComponent()).build().inject(this);
 TextView textView = findViewById(R.id.textView);
 textView.setText(p.toString());
 }
}

daggar2如何選擇依賴呢,按照這樣的順序

當(dāng)Component調(diào)用inject方法的時(shí)候,會搜索被注入類中用@Inject注解的字段,然后會在該Component中查找在@Component(modules=。。。)注解中注冊的Module,如果搜索到Module有@Provides注解的方法提供該@Inject注解的字段所需的實(shí)例,就調(diào)用相應(yīng)的方法完成注入,否則就查找所有用@Inject注解構(gòu)造函數(shù)的類,如果找到就調(diào)用相應(yīng)的構(gòu)造函數(shù)完成注入,如果在獲得實(shí)例的時(shí)候還需要獲取參數(shù)的實(shí)例,再按照剛才的流程依次注入?yún)?shù)實(shí)例

畫個(gè)簡單的流程,如下所示

Component.inject->在Component搜索Module->找到就調(diào)用@Provides注解的方法提供實(shí)例

->沒找到就搜索@Inject注解的構(gòu)造函數(shù)

->都找不到就報(bào)錯(cuò)。。。

都沒找到肯定就報(bào)錯(cuò)了。。。但是會優(yōu)先尋找Component注冊的Module,而@Inject注冊的構(gòu)造器可以調(diào)用任何Component的inject方法完成注入,因?yàn)锧Inject注冊的構(gòu)造器不需要在Component里注冊,這里和Module有區(qū)別,Module是需要在某個(gè)Component中注冊的,而@Inject不需要。

以上是“dagger2怎么用”這篇文章的所有內(nèi)容,感謝各位的閱讀!相信大家都有了一定的了解,希望分享的內(nèi)容對大家有所幫助,如果還想學(xué)習(xí)更多知識,歡迎關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道!

當(dāng)前標(biāo)題:dagger2怎么用
瀏覽地址:http://aaarwkj.com/article34/pjcjse.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供ChatGPT、虛擬主機(jī)、靜態(tài)網(wǎng)站自適應(yīng)網(wǎng)站、服務(wù)器托管、域名注冊

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)

網(wǎng)站建設(shè)網(wǎng)站維護(hù)公司
四虎在线经典视频播放| 蜜臀国产综合久久第一页| 国产在线乱码一区二区| 国产精品一区二区高潮| 一区二区三区毛片免费| 免费在线一区二区av| 日韩暴露一区二区三区| 麻豆专区一区二区三区| 日本亚洲中文字幕网站| 国产美女直播亚洲一区色| 亚洲日本中文字幕免费观看| 亚洲精品国产精品粉嫩| 精品国产欧美亚洲91| 日本欧美高清一区二区| 国产精品一区二区久久| 日本一区中文字幕欧美| 色吊丝二区三区中文字幕| 国产成人精品无人区一区| 国产经典午夜福利在线| 欧美日韩在线观看黄色| 日本视频免费一区二区| 色人阁在线精品免费视频| 亚洲成人大片免费在线观看| 精品一区二区亚洲精品| 蜜桃av网站免费观看| 亚洲黄香蕉视频免费看| 午夜在线观看成人av| 国精品91人妻一区二区| 亚洲精品啪啪一区二区| 国产av综合一区二区三区最新| 午夜在线免费观看小视频| 亚洲成人免费电影久久| 国产经典午夜福利在线| 成人黄网站色大片免费观看| 欧美v日韩v亚洲综合国产高清| 人人妻人人澡人人揉| 国产成人大片一区二区三区| 欧美亚洲一区二区三区91| 精品国产a级黄毛网站| 欧美另类不卡在线观看| 亚洲久久精品一区二区|