標籤:編譯 false ddl apt article als 註解 sequence detail
本文原創,轉載請註明出處:http://blog.csdn.net/zjbpku
[Duplicated] link to Dagger on Android - Dagger2具體解釋
關於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 Generatederror: 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. */@Modulepublic 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. */@Modulepublic class ApplicationModule { Application mApplication; ApplicationModule(Application application) { mApplication = application; } @Provides Application providesApplication() { return mApplication; }}
寫好之後,加入兩個@Component註解的介面,此Demo很easy。僅僅是來嘗試使用一下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自己主動產生的程式碼有所差異,這個之後會進一步介紹。
Android 依賴注入: Dagger 2 執行個體解說(一)