中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Android注解使用之Dagger2實現項目依賴關系解耦

發布時間:2020-06-16 12:01:12 來源:網絡 閱讀:361 作者:26度出太陽 欄目:移動開發

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 {
    @Inject
    ClassB 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
    @Singleton
    LCache provideLCache() {        return new LCache("lcj",500);
    }

}


LExecutorModule類


@Modulepublic class LExecutorModule {    /**
     * 提供app 多任務最少維護線程個數
     * @return 返回多任務最少維護線程個數     */
    @Provides
    @Singleton
    LExecutor 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() {
            @Override
            public void run() {
                cacheComponent.lCache().saveCache(key,value);
            }
        });
    }

    public  void readCache(final String key){
        cacheComponent.lExecutor().runTask(new Runnable() {
            @Override
            public void run() {
                cacheComponent.lCache().readCache(key);
            }
        });
    }
}


5.使用場景調用及簡單解說
LCacheManager.getInstance().saveCache("key","who is lcj ?");

看下打印結果:

Android注解使用之Dagger2實現項目依賴關系解耦

通過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
    @Singleton
    LExecutor provideLExecutor() {        return new LExecutor(10);
    }    /**
     * 提供app 多任務最少維護線程個數
     * @return 返回多任務最少維護線程個數     */
    @Provides
    @Singleton
    LExecutor provideWriteLExecutor() {        return new LExecutor(5);
    }
}


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

Android注解使用之Dagger2實現項目依賴關系解耦

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

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

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


@Modulepublic class LCacheModule {    /**
     * 提供緩存對象
     * @return 返回緩存對象     */
    @Provides
    @Singleton
    LCache 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會自動去尋找相關參數進行綁定依賴關系。


向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

莱芜市| 汉沽区| 磐石市| 旌德县| 屯留县| 弥渡县| 临邑县| 昆山市| 中山市| 长泰县| 门源| 丰原市| 平乐县| 伊金霍洛旗| 天长市| 依兰县| 邛崃市| 新晃| 泰来县| 沂源县| 鄂州市| 贡觉县| 大化| 民丰县| 兰西县| 海门市| 太仆寺旗| 泗阳县| 松桃| 文安县| 彭水| 罗定市| 肃宁县| 亚东县| 咸丰县| 绥中县| 武鸣县| 汾阳市| 汉川市| 九龙城区| 宜阳县|