史上最通俗易懂的Android Dagger入門教程

任蘋蜻發表於2016-07-31

簡介

Dagger2是Dagger1的分支,早期有square開發,現在由谷歌公司接手。
他要解決問題和核心是:利用生成和寫的程式碼混合達到看似所有的產生和提供依賴的程式碼都是手寫的樣子。

官方Github地址:https://github.com/google/dagger

官方主頁:http://google.github.io/dagger/

好處

  1. 依賴注入的配置獨立於初始化地方,更改配置方便。比如:在MVP架構中,我們寫了一個TaskPresenter,但是他在TaskActivity和TaskDetailActivity中都使用了,正常情況是不是我們要在這兩個地方都做例項化,後期可能還有更多的介面,但是我們如果使用了依賴注入,我們只需要在這兩個地方定義一個TaskPresenter的變數,然後加一個註解,這樣初始化在統一的地方,以後更改是不是很方便。
  2. 我們可以注入一些依賴的模擬實驗。比如:我們的app顯示的資料來自網路,但是後臺介面還沒有寫好,但是我們對資料層進行了抽象化,那我們就可以寫一個本地json模擬是介面返回的資料,就可以測試了。
  3. app的注入元件他不知道在什麼地方,初始化完全有我們告訴他在什麼地方注入等

結構圖

首先大概解釋下Dagger中幾個角色(或者說是幾個註解):

@Inject:這個很簡單了,通常是在需要注入的地方新增這個依賴。比如:MainActivity要使用LocalManager例項,那我們就在要使用的地方定義一個成員變數

@Inject
LocationManager locationManager;

注意:不能是private修飾的

@Module:就是真正提供依賴的類了。所以我們定義一個類,用@Module註解,這樣Dagger在構造類的例項的時候,就知道從哪裡去找到需要的 依賴。modules的一個重要特徵是它們設計為分割槽並組合在一起(比如說,在我們的app中可以有多個組成在一起的modules)。所以我們這裡可以定義一個AppApplication類用來提供全域性依賴,可以是ApiService,Retrofit,OKHttp,LocalManager,Context等

@Module
public class AppApplicationModule {
    ...
}

@Provides:就是寫在Module中某些方法上,表示這個方法提供依賴

@Provides @Singleton LocationManager provideLocationManager() {
    return (LocationManager) application.getSystemService(LOCATION_SERVICE);
}

@Component: 是@Inject和@Module的橋樑,它的主要作用就是連線這兩個部分。 Components可以提供所有定義了的型別的例項。

@Singleton
@Component(modules = AppApplicationModule.class)
public interface ApplicationComponent {
    void inject(MainActivity demoActivity);
}

基本的註解我就講解到這裡,下面寫一個小例項

基本配置

首先建立一個Android專案,然後在專案的build.grade,新增android-apt依賴

buildscript {
    ...
    dependencies {
        ...
        classpath 'com.neenbedankt.gradle.plugins:android-apt:1.8'
        ...
    }
}

然後在app的build.gradle新增

apply plugin: 'com.neenbedankt.android-apt'

然後在新增依賴

dependencies {
    ...
    apt "com.google.dagger:dagger-compiler:2.2"
    provided 'org.glassfish:javax.annotation:10.0-b28'
    compile "com.google.dagger:dagger:2.2"
    ...
}

到這一步可以build下,看看配置是否正確,我們下面要做的就是上面說的,給MainActivity提供LocalManager,對,就這麼一點,不然寫多了大家又懵逼了

首先建立一個AppApplication類,他是一個Application子類,需要在清檔檔案配置,之所有要建立他是因為,我們要在這裡提供一些全域性依賴

建立Application

public class AppApplication extends Application{
    @Override
    public void onCreate() {
        super.onCreate();
    }
}

記得在清單檔案配置喲~

建立AppApplicationModule

上面說了這是一個真正提供依賴的類,其中一些方法要用@Provides修飾

@Module
public class AppApplicationModule {
    private final Context context;
    public AppApplicationModule(Context context) {
        this.context=context;
    }
    //標示這個方法可以提供LocationManager
    @Provides
    @Singleton
    LocationManager provideLocationManager() {
        return (LocationManager) context.getSystemService(LOCATION_SERVICE);
    }
}

建立ApplicationComponent

同樣也說了,他是Module和Inject之間的橋樑,我們幫他建立到了AppApplication內部

@Singleton
@Component(modules = AppApplicationModule.class)
public interface ApplicationComponent {
    void inject(MainActivity demoActivity);
}

在AppApplication中註冊依賴

public class AppApplication extends Application {
    private ApplicationComponent component;
    @Override
    public void onCreate() {
        super.onCreate();
        component = DaggerAppApplication_ApplicationComponent.builder().appApplicationModule(new AppApplicationModule(this)).build();
        component.inject(this);
    }
    @Singleton
    @Component(modules = AppApplicationModule.class)
    public interface ApplicationComponent {
        void inject(MainActivity demoActivity);
        void inject(AppApplication application);
    }
    public ApplicationComponent component() {
        return component;
    }
}

在MainActivity註冊

public class MainActivity extends AppCompatActivity {
    //可以看到我們沒有顯示的初始化LocationManager
    @Inject
    LocationManager locationManager;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        TextView tv_info = (TextView) findViewById(R.id.tv_info);
        //註解依賴
        ((AppApplication) getApplication()).component().inject(this);
        tv_info.setText(locationManager.toString());
    }
}

好這就是一個最最基本的Dagger注入例子了,下一篇我們來詳細分析下他的實現原理或者再寫一個MVP架構例子,感謝你的閱讀。原始碼下載地址:https://github.com/lifengsofts/AndroidDagger2

相關文章