Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> Android 依賴注入: Dagger 2 實例講解(一)

Android 依賴注入: Dagger 2 實例講解(一)

編輯:關於Android編程

 

關於Dagger,在之前的博文(Android 依賴注入:Dagger 實例講解(Demo下載))中已有介紹, 本文說的Dagger 2主要是由Google技術

人員參與開發的,當然包括Square的各位及其他一些Contributors在內的大牛也貢獻了不少。該項目大概是從去年11月份開始啟動的,到目前該項

目還在繼續進行,Snapshot version也是剛剛發布不久,從Github提供的內容看,不久會是Pre Release Version,然後才是Release Version,由於

現在還是預覽版,還不穩定,請謹慎使用,到Pre Release時才會相對比較穩定,可以使用來進行項目開發。本人關注這個項目依舊,就提前通過一

個Demo來簡單介紹一下Dagger 2.

\

Dagger 2是Dagger 1.x的增強版,在Dagger 1.x中,@Inject和@Provides annotation 構成了對象的圖譜(graph),依靠之間的依賴

關系而鏈接在一起。通過定義好的圖譜集(ObjectGraph)可以方便的調用代碼。而在Dagger 2中,這種關系被帶有無參方法的接口代替,

這種方法返回的類型就是所需類型。這種接口的實現是通過@Component 注解且傳入modules參數來定義的。如:

 

@Component(
//        dependencies = ApplicationComponent.class,
        modules = ActivityModule.class
)
public interface ActivityComponent {
    MainActivity injectActivity(MainActivity activity);

    ToastHelper getToastHelper();
}

 

在編譯時,Dagger 2會自動生成以Dagger_為前綴的此接口的實現Dagger_AcitvityComponent.通過調用此的builder()方法來獲得一個

實例,通過該方法返回的builder來設置其他依賴,通過build來獲得一個新的實例。

 

 this.component = Dagger_ActivityComponent.builder()
//                .applicationComponent(((DaggerApplication) getApplication()).getComponent())
                .activityModule(new ActivityModule(this))
                .build();

 

另外一點,如果@Component注解的接口中的方法沒有參數,生成的實例中會生成一個create()方法,此create()方法實際上就是
builder().build();此點在以後的代碼中會提到。

下面介紹Demo:

Demo使用最新的AndroidStudio (以下簡稱AS)1.0.2版本,既然使用AS,就少不了gradle.build文件的配置,此項目gradle配置如下:

 

apply plugin: 'com.android.application'
apply plugin: 'android-apt'
buildscript {
    repositories {
        jcenter()
    }
    dependencies {
        classpath 'com.android.tools.build:gradle:1.0.0'
        classpath 'com.neenbedankt.gradle.plugins:android-apt:1.4' // 3
    }
}

allprojects {
    repositories {
        mavenCentral()
        maven {
            url 'https://oss.sonatype.org/content/repositories/snapshots/'
        }
    }
}
android {
    compileSdkVersion 21
    buildToolsVersion 21.1.2

    defaultConfig {
        applicationId com.example.zjbpku.dagger2
        minSdkVersion 19
        targetSdkVersion 21
        versionCode 1
        versionName 1.0
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
}

def Dagger2_Version = '2.0-SNAPSHOT'

dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
    compile 'com.android.support:appcompat-v7:21.0.3'
    // 1. Dagger 2.0
    compile com.google.dagger:dagger:$Dagger2_Version
    apt com.google.dagger:dagger-compiler:$Dagger2_Version
    // 2.
    compile 'org.glassfish:javax.annotation:10.0-b28'
}
分別看一下gradle.build文件中注釋1,2,3。

 

注釋1:是配置依賴Dagger 2,版本是2.0-SNAPSHOT,這裡相比之前版本的Dagger就是從com.square.dagger 變為現在的com.google.dagger,

當然這不是重點。

注釋2:為什麼要加上這一句呢?因為Dagger 2 中會用到@Generated注解(後面講),而javax.anotation.generated在java 6及以上的版本中都有,

在Android API 中是沒有的,所以在Android項目中一定要加此句,如果不加就有提示以下錯誤:

 

error: cannot find symbol class Generated
error: package javax.annotation does not exist

注釋3:就不多少了,具體作用請看http://blog.csdn.net/zjbpku/article/details/22976291,另不要忘記加

 

 

apply plugin:android-apt

在之前的Dagger中@module是一個關鍵注解,在Dagger 2中同樣少不了,此Demo中用到的兩個Module如下:(用過Dagger的不會覺得有問題)

 

ActivityModule.java:

 

/**
 * Created by zjbpku on 12/20/14.
 */

@Module
public class ActivityModule {

    private Activity mActivity;

    public ActivityModule(Activity activity) {
        mActivity = activity;
    }

    @Provides
    Activity providesActivity() {
        return mActivity;
    }

}

ApplicationModule.java:

 

 

/**
 * Created by zjbpku on 12/20/14.
 */
@Module
public class ApplicationModule {
    Application mApplication;

    ApplicationModule(Application application) {
        mApplication = application;
    }

    @Provides
    Application providesApplication() {
        return mApplication;
    }
}

寫好之後,添加兩個@Component注解的接口,此Demo非常簡單,只是來嘗試使用一下Dagger 2,Application相關的其實可以不用,對Demo不會

 

有什麼影響,但在實際項目中還是必須添加的,所以這裡也給加上。

Activityomponent.java:

 

/**
 * Created by zjbpku on 12/20/14.
 */

@Component(
        dependencies = ApplicationComponent.class,
        modules = ActivityModule.class
)
public interface ActivityComponent {
    MainActivity injectActivity(MainActivity activity);

    ToastHelper getToastHelper(); 
}

 

 

ApplicationComponent.java:

/**
 * Created by zjbpku on 12/20/14.
 */
@Component(
        modules = ApplicationModule.class
)
public interface ApplicationComponent {
    DaggerApplication injectApplication(DaggerApplication application);
}


DaggerApplication.java:

 

/**
 * Created by zjbpku on 12/20/14.
 */
public class DaggerApplication extends Application {

    private ApplicationComponent component;

    @Override
    public void onCreate() {
        super.onCreate();
        this.component = Dagger_ApplicationComponent.builder().applicationModule(new ApplicationModule(this)).build();
        this.component.injectApplication(this);
    }


    ApplicationComponent getComponent() {
        return this.component;
    }
}

//添加只是為了測試

 

ToastHelper.java:

 

/**
 * Created by zjbpku on 12/22/14.
 */
public class ToastHelper {

    @Inject
    ToastHelper() {
    }

    //@Inject
    //Utils utils;
    Toast toast = null;

    public void showToast(Context context, CharSequence text) {
        if (toast == null) {
            toast = Toast.makeText(context, text, Toast.LENGTH_LONG);
        } else {
            toast.setText(text);
        }
        toast.show();
    }

    public void show(Context context) {
       // showToast(context, utils.getContent());
    }
}


 

MainActivity.java:

 

package com.example.zjbpku.dagger2;

import android.app.Activity;
import android.os.Bundle;
import android.view.View;


public class MainActivity extends Activity {

    private ActivityComponent component;
//    @Inject
//    ToastHelper toastHelper;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        this.component = Dagger_ActivityComponent.builder()
                .applicationComponent(((DaggerApplication) getApplication()).getComponent())
                .activityModule(new ActivityModule(this))
                .build();
        this.component.injectActivity(this);
        setContentView(R.layout.activity_main);
    }


    public void helloDagger2(View v) {
//        toastHelper.showToast(this, Dagger 2);
//        toastHelper.show(this);
        this.component.getToastHelper().showToast(this, Dagger 2 Demo);
    }

}

 

可以看到,Dagger 2 消除了Dagger 1.x 中所有的映射(reflection),通過添加@Component,移除ObjectGraph/Injector使代碼更加的清晰了。

到此,Dagger 2的基本用法已經結束,在ActivityComponet接口中你發現有getToastHelper()方法,在Mainctivity中發現@Inject注解的ToastHelper

是注銷的,且在helloDagger2(View v)方法中也是注銷的,這是因為,開始時getToastHelper()方法是沒有的,是直接在Mainctivity中通過@Inject直接注入

的,後來閱讀Dagger 2的相關資料發現,其實這並不是Dagger 2的所期望的,Dagger 2希望使用@Component注解接口將依賴關系鏈接起來,所以才改用

現在這種方法。其實兩種都能達到一樣的效果,只是Dagger自動生成的代碼有所差異,這個之後會進一步介紹。

 

 

 

  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved