日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 >

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

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

Dagger2

? ? 一句話:一款快速的注解框架,應用于Android、Java,由 Google 開發和維護,是?Square?的?Dagger?項目的分支。

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

? ? Dagger2采用依賴注入方式,依賴注入是一種面向對象的編程模式,它的出現是為了降低耦合性,所謂耦合就是類之間依賴關系,所謂降低耦合就是降低類和類之間依賴關系。

依賴關系

? ?Java的面向對象編程特性,通常會在一個Java對象中引用另一個Java對象,舉例說明一下:


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


通過上面的例子可以看出,ClassA需要借助ClassB才能完成一些特定操作,但是我們在ClassA直接實例化了ClassB,這樣耦合就產生了,第一違背了單一職責原則,ClassB的實例化應該由自己完成,不應該由ClassA來完成,第二違背了開閉原則,一旦ClassB的構造函數產生變化,就需要修改ClassA的構造函數。

通過依賴注入降低這種耦合關系:

1.通過構造參數傳參的方式


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采用的就是注解注入的方式,然后編譯自動生成目標代碼的方式實現宿主與被依賴者之間的關系。

Dagger2在Android的使用方式及簡單說明

在Android中的使用方式很簡單:只需在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 ?修飾需要依賴的地方(可以是構造方法、field或者一般的方法)

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

Dagger2舉例說明

?以項目中實際場景緩存管理為例,來體驗一下解耦效果。設計遵循單一職責原則。

?1.首先定義緩存類和多任務類。并且在其構造函數上添加@Inject注解

LCache類


/***?Created?by?lichaojun?on?2017/3/30.*?處理緩存?*/public?class?LCache?{????private?static??final??String?DEFAULT_CACHE_NAME="LCache";//默認緩存名字private?static??final??int?DEFAULT_MAX_CACHE_SIZE=1024;//默認緩存名字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();//默認線程池維護線程的最少數量private?int?coreSize?=?DEFAULT_CPU_CORE;//線程池維護線程的最少數量@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類來提供相關依賴

LCacheModule類


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


LExecutorModule類


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


3.使用@Component 用來將@Inject和@Module關聯起來,新建LCacheComponent類


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


4.在宿主中注入想要依賴的對象


/***?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.使用場景調用及簡單解說

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

看下打印結果:

通過Dagger2的方式剛開始可能會覺得突然間一個簡單的事情,變得復雜了,其實沒有,通過Dagger2很好的處理好了依賴關系,具體說明,比如我們緩存LCache需要添加一個最大緩存個數變化,如果按照之前的方式,我們首先需要對LCache進行修改,比如修改構造函數增加maxCacheSize,然后必須對LCacheManager進行修改,現在通過Dagger2的方式的話,我們只需修改LCacheModule就可以了,LCache實例化和相關參數和LCacheManager之間并沒有太大的依賴關系。

6.關于@Module提供多個同類型@Provides

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


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


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


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


然后寫完之后Rebuild一下項目,以為萬事大吉了,結果報了如下錯誤,

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

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

對于Module的provide函數也是可以傳遞參數的,不過需要在當前Module中需要提供相關的參數的函數。例如:LCacheModule可以修改如下:


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


這里又使用了別名@Name也是因為為了避免bound multiple times錯誤導致編譯失敗,在編譯的過程中Dagger2會自動去尋找相關參數進行綁定依賴關系。


轉載于:https://blog.51cto.com/kiujyhgt/1915457

總結

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

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。