标签:
本文原创,转载请注明出处:http://blog.csdn.net/zjbpku
关于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 依赖注入: Dagger 2 实例讲解(一)
标签:
原文地址:http://blog.csdn.net/zjbpku/article/details/42109891