日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 运维知识 > Android >内容正文

Android

Android注解使用之Dagger2实现项目依赖关系解耦

發(fā)布時(shí)間:2025/6/15 Android 29 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Android注解使用之Dagger2实现项目依赖关系解耦 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

Dagger2

? ? 一句話:一款快速的注解框架,應(yīng)用于Android、Java,由 Google 開發(fā)和維護(hù),是?Square?的?Dagger?項(xiàng)目的分支。

? ? gitHub:https://github.com/google/dagger

? ? Dagger2采用依賴注入方式,依賴注入是一種面向?qū)ο蟮木幊棠J?#xff0c;它的出現(xiàn)是為了降低耦合性,所謂耦合就是類之間依賴關(guān)系,所謂降低耦合就是降低類和類之間依賴關(guān)系。

依賴關(guān)系

? ?Java的面向?qū)ο缶幊烫匦?#xff0c;通常會(huì)在一個(gè)Java對(duì)象中引用另一個(gè)Java對(duì)象,舉例說明一下:


public?class?ClassA?{????private?ClassB?classB;????public?ClassA(){classB?=new?ClassB();}????public??void?doSomething(){classB.doSomething();} }


通過上面的例子可以看出,ClassA需要借助ClassB才能完成一些特定操作,但是我們?cè)贑lassA直接實(shí)例化了ClassB,這樣耦合就產(chǎn)生了,第一違背了單一職責(zé)原則,ClassB的實(shí)例化應(yīng)該由自己完成,不應(yīng)該由ClassA來完成,第二違背了開閉原則,一旦ClassB的構(gòu)造函數(shù)產(chǎn)生變化,就需要修改ClassA的構(gòu)造函數(shù)。

通過依賴注入降低這種耦合關(guān)系:

1.通過構(gòu)造參數(shù)傳參的方式


public?class?ClassA?{????private?ClassB?classB;????public?ClassA(ClassB?classB){????????this.classB?=classB;}????public??void?doSomething(){classB.doSomething();} }


2.通過set方法的方式


public?class?ClassA?{????private?ClassB?classB;????public?ClassA(){}????public?void?setClassB(ClassB?classB)?{????????this.classB?=?classB;}????public??void?doSomething(){classB.doSomething();} }


3.通過接口注入的方式


interface?ClassBInterface?{????void?setB(ClassB?classB); }public?class?ClassA?implements?ClassBInterface?{????private?ClassB?classB;????public?ClassA()?{}@Override????public?void?setB(ClassB?classB)?{????????this.classB?=?classB;}????public?void?doSomething()?{classB.doSomething();} }


4.通過注解注入


public?class?ClassA?{@InjectClassB?classB;????public?ClassA()?{}????public?void?doSomething()?{classB.doSomething();} }


Dagger2采用的就是注解注入的方式,然后編譯自動(dòng)生成目標(biāo)代碼的方式實(shí)現(xiàn)宿主與被依賴者之間的關(guān)系。

Dagger2在Android的使用方式及簡(jiǎn)單說明

在Android中的使用方式很簡(jiǎn)單:只需在Module的build.gradle中添加一下配置

dependencies?{compile?'com.google.dagger:dagger:2.x'annotationProcessor?'com.google.dagger:dagger-compiler:2.x'}

?Dagger2 annotation講解

  • @Module 修飾的類專門用來提供依賴

  • @Provides 修飾的方法用在Module類里

  • @Inject ?修飾需要依賴的地方(可以是構(gòu)造方法、field或者一般的方法)

  • @Component 連接@Module和注入的橋梁

Dagger2舉例說明

?以項(xiàng)目中實(shí)際場(chǎng)景緩存管理為例,來體驗(yàn)一下解耦效果。設(shè)計(jì)遵循單一職責(zé)原則。

?1.首先定義緩存類和多任務(wù)類。并且在其構(gòu)造函數(shù)上添加@Inject注解

LCache類


/***?Created?by?lichaojun?on?2017/3/30.*?處理緩存?*/public?class?LCache?{????private?static??final??String?DEFAULT_CACHE_NAME="LCache";//默認(rèn)緩存名字private?static??final??int?DEFAULT_MAX_CACHE_SIZE=1024;//默認(rèn)緩存名字private?String?cacheName=DEFAULT_CACHE_NAME;//緩存名字private?int?maxCacheSize=DEFAULT_MAX_CACHE_SIZE;????public?LCache?(){}@Inject????public??LCache(String?cacheName,int?maxCacheSize){????????this.cacheName=cacheName;????????this.maxCacheSize=maxCacheSize;}????public?void?saveCache(String?key?,String?value){Log.e(LCacheManager.TAG,"cacheName:??=?"+cacheName);Log.e(LCacheManager.TAG,"maxCacheSize:??=?"+maxCacheSize);Log.e(LCacheManager.TAG,"saveCache:?key?=?"+key?+"?value?=?"+value);}????public??void?readCache(String?key){Log.e(LCacheManager.TAG,"readCache:?key:??=?"+key);} }


LExecutor類


public?class?LExecutor?{????private?static?final?int?DEFAULT_CPU_CORE?=?Runtime.getRuntime().availableProcessors();//默認(rèn)線程池維護(hù)線程的最少數(shù)量private?int?coreSize?=?DEFAULT_CPU_CORE;//線程池維護(hù)線程的最少數(shù)量@Inject????public?LExecutor(int?coreSize)?{????????this.coreSize?=?coreSize;}????public?void?runTask(Runnable?runnable)?{????????if?(runnable?==?null)?{????????????return;}Log.e(LCacheManager.TAG,"coreSize:??=?"+coreSize);Log.e(LCacheManager.TAG,?"runTask");runnable.run();} }


2.使用@Module分別定義LCacheModule、LExecutorModule類來提供相關(guān)依賴

LCacheModule類


@Modulepublic?class?LCacheModule?{????/***?提供緩存對(duì)象*?@return?返回緩存對(duì)象?????*/@Provides@SingletonLCache?provideLCache()?{????????return?new?LCache("lcj",500);}}


LExecutorModule類


@Modulepublic?class?LExecutorModule?{????/***?提供app?多任務(wù)最少維護(hù)線程個(gè)數(shù)*?@return?返回多任務(wù)最少維護(hù)線程個(gè)數(shù)?????*/@Provides@SingletonLExecutor?provideLExecutor()?{????????return?new?LExecutor(10);} }


3.使用@Component 用來將@Inject和@Module關(guān)聯(lián)起來,新建LCacheComponent類


@Component(modules?=?{LCacheModule.class,LExecutorModule.class}) @Singletonpublic?interface?LCacheComponent?{LCache?lCache();???//?app緩存LExecutor?lExecutor();??//?app多任務(wù)線程池void?inject(LCacheManager?lCacheManager); }


4.在宿主中注入想要依賴的對(duì)象


/***?Created?by?lichaojun?on?2017/3/30.*?緩存處理管理*/ public?class?LCacheManager?{public?static??final??String?TAG=LCacheManager.class.getSimpleName();private??LCacheComponent?cacheComponent;private?static?class?SingletonHolder?{private?static?LCacheManager?instance?=?new?LCacheManager();}private?LCacheManager(){cacheComponent?=?DaggerLCacheComponent.builder().lCacheModule(new?LCacheModule()).build();cacheComponent.inject(this);}public?static?LCacheManager?getInstance()?{return?SingletonHolder.instance;}public??void?saveCache(final?String?key?,?final?String?value)?{cacheComponent.lExecutor().runTask(new?Runnable()?{@Overridepublic?void?run()?{cacheComponent.lCache().saveCache(key,value);}});}public??void?readCache(final?String?key){cacheComponent.lExecutor().runTask(new?Runnable()?{@Overridepublic?void?run()?{cacheComponent.lCache().readCache(key);}});} }


5.使用場(chǎng)景調(diào)用及簡(jiǎn)單解說

LCacheManager.getInstance().saveCache("key","who?is?lcj??");

看下打印結(jié)果:

通過Dagger2的方式剛開始可能會(huì)覺得突然間一個(gè)簡(jiǎn)單的事情,變得復(fù)雜了,其實(shí)沒有,通過Dagger2很好的處理好了依賴關(guān)系,具體說明,比如我們緩存LCache需要添加一個(gè)最大緩存?zhèn)€數(shù)變化,如果按照之前的方式,我們首先需要對(duì)LCache進(jìn)行修改,比如修改構(gòu)造函數(shù)增加maxCacheSize,然后必須對(duì)LCacheManager進(jìn)行修改,現(xiàn)在通過Dagger2的方式的話,我們只需修改LCacheModule就可以了,LCache實(shí)例化和相關(guān)參數(shù)和LCacheManager之間并沒有太大的依賴關(guān)系。

6.關(guān)于@Module提供多個(gè)同類型@Provides

?基于上面的緩存處理需求,我們需要實(shí)現(xiàn)讀寫分別使用不同的多任務(wù)LExecutor,并且LExecutor的最小線程數(shù)為5,我們會(huì)在LCacheComponent添加提供writeLExecutor函數(shù),如下:


@Component(modules?=?{LCacheModule.class,LExecutorModule.class}) @Singletonpublic?interface?LCacheComponent?{LCache?lCache();???//?app緩存LExecutor?lExecutor();??//?app多任務(wù)線程池LExecutor?writeLExecutor();??//?app?寫緩存多任務(wù)線程池void?inject(LCacheManager?lCacheManager); }


在LExecutorModule中添加提供依賴初始化的provideWriteLExecutor函數(shù)。如下:


@Modulepublic?class?LExecutorModule?{????/***?提供app?多任務(wù)最少維護(hù)線程個(gè)數(shù)*?@return?返回多任務(wù)最少維護(hù)線程個(gè)數(shù)?????*/@Provides@SingletonLExecutor?provideLExecutor()?{????????return?new?LExecutor(10);}????/***?提供app?多任務(wù)最少維護(hù)線程個(gè)數(shù)*?@return?返回多任務(wù)最少維護(hù)線程個(gè)數(shù)?????*/@Provides@SingletonLExecutor?provideWriteLExecutor()?{????????return?new?LExecutor(5);} }


然后寫完之后Rebuild一下項(xiàng)目,以為萬事大吉了,結(jié)果報(bào)了如下錯(cuò)誤,

怎么辦呢,難道Dagger2就這么不堪一擊嗎,當(dāng)然不是解決這個(gè)問題很容易,使用@Named注解解決這個(gè)問題,我們只需要在LCacheComponent的writeLExecutor()和

LExecutorModule的provideWriteLExecutor()函數(shù)上添加相同的@Named("WriteLExecutor")即可。

對(duì)于Module的provide函數(shù)也是可以傳遞參數(shù)的,不過需要在當(dāng)前Module中需要提供相關(guān)的參數(shù)的函數(shù)。例如:LCacheModule可以修改如下:


@Modulepublic?class?LCacheModule?{????/***?提供緩存對(duì)象*?@return?返回緩存對(duì)象?????*/@Provides@SingletonLCache?provideLCache(?@Named("LCache")String?name?,?@Named("LCache")int?maxCacheSize)?{????????return?new?LCache(name,maxCacheSize);}????/***?提供緩存對(duì)象*?@return?返回緩存對(duì)象?????*/@Provides@Singleton@Named("LCache")String?provideLCacheName()?{????????return?"lcjCache";}????/***?提供緩存對(duì)象*?@return?返回緩存對(duì)象?????*/@Provides@Singleton@Named("LCache")????int?provideLCacheMaxSize()?{????????return?600;}}


這里又使用了別名@Name也是因?yàn)闉榱吮苊鈈ound multiple times錯(cuò)誤導(dǎo)致編譯失敗,在編譯的過程中Dagger2會(huì)自動(dòng)去尋找相關(guān)參數(shù)進(jìn)行綁定依賴關(guān)系。


轉(zhuǎn)載于:https://blog.51cto.com/kiujyhgt/1915457

總結(jié)

以上是生活随笔為你收集整理的Android注解使用之Dagger2实现项目依赖关系解耦的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。