編輯:關於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
apply plugin:android-apt
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; } }
/** * Created by zjbpku on 12/20/14. */ @Module public class ApplicationModule { Application mApplication; ApplicationModule(Application application) { mApplication = application; } @Provides Application providesApplication() { return mApplication; } }
有什麼影響,但在實際項目中還是必須添加的,所以這裡也給加上。
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 Studio的好處我就不用說了,下面兩點就足矣讓你轉投Android Studio了: 1、Andro
二維碼其實有很多種,但是我們常見的微信使用的是一種叫做QRCode的二維碼,像下面這樣的,可以放心的掃,這只是我的博客主頁鏈接啦: 關於QR碼編碼的二維碼,我們
Android 手機無法連接mac解決辦法一般的android連接mac 很方便不用安裝驅動就可以啦,可是不知道為什麼二般情況下有的android手機(小米2,華為等)就
今天終於把老大交代的任務搞完了,感覺收獲挺多的,所以就寫一篇來記錄一下吧,首先還是來看一下,老大們的需求 需求: 希望移動端的用戶標識(IMEI)和HTML頁面的用戶