• 前戏

本篇文章打算介绍一下Dagger框架的入门。Dagger是一个依赖注入框架(DI框架)。什么是依赖注入框架呢?------简单的说,就是创建对象不需要程序员自己new,Dagger帮忙new。关于依赖注入的概念可以在网上自己搜索,本篇不打算详细介绍依赖注入的概念。接下来,我们学习下Dagger的基本使用。



  • 没有使用Dagger框架的例子:

定义2个类:1、UserBean.java 就是一个简单的Java对象;2、MainActivity.java 就是一个普通的Activity。


要做的事情:点击MainActivity上的一个按钮,获取UserBean中的getName方法返回的值,然后使用Toast显示出来。

1、UserBean.java

1.  public class UserBean {
2.  public String getName() {
3.          return "yangjingwen";
4.      }
5.  }


复制代码



2、MainActivity.java

1.  public class MainActivity extends AppCompatActivity {
2.  
3.      private UserBean userBean = new UserBean();
4.      @Override
5.      protected void onCreate(Bundle savedInstanceState) {
6.          super.onCreate(savedInstanceState);
7.          setContentView(R.layout.activity_main);
8.      }
9.  
10.      public void click(View view) {
11.          Toast.makeText(MainActivity.this, userBean.getName(), Toast.LENGTH_SHORT).show();
12.      }
13.  }


复制代码


3、activity_main.xml

1.  <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
2.      xmlns:tools="http://schemas.android.com/tools"
3.      android:layout_width="match_parent"
4.      android:layout_height="match_parent"
5.      android:paddingBottom="@dimen/activity_vertical_margin"
6.      android:paddingLeft="@dimen/activity_horizontal_margin"
7.      android:paddingRight="@dimen/activity_horizontal_margin"
8.      android:paddingTop="@dimen/activity_vertical_margin"
9.      tools:context="com.androidxx.yangjw.androiddagger2demo.MainActivity">
10.  
11.      <Button
12.          android:layout_width="wrap_content"
13.          android:layout_height="wrap_content"
14.          android:onClick="click"
15.          android:text="点击" />
16.  </RelativeLayout>


复制代码

以上代码很简单,就是在MainActivity中调用UserBean的getName方法,并且使用Toast将其显示出来。


接下来,我们开始使用dagger来修改上面的代码。就上面的例子而言,dagger能做什么呢?----答案就是dagger可以将new UserBean()这句话省略掉。



  • Dagger的使用

步骤:


1、配置,导入dagger需要的jar包和插件。


2、开始使用


  • 配置

在module的build.gradle中添加代码:

1.  buildscript { //此处添加 
2.      repositories {
3.          jcenter()
4.      }
5.      dependencies {
6.          classpath 'com.neenbedankt.gradle.plugins:android-apt:1.8'
7.      }
8.  }
9.  
10.  apply plugin: 'com.android.application'
11.  apply plugin: 'com.neenbedankt.android-apt' //此处添加
12.  
13.  android {
14.      compileSdkVersion 23
15.      buildToolsVersion "23.0.3"
16.  
17.      defaultConfig {
18.          applicationId "com.androidxx.yangjw.androiddagger2demo"
19.          minSdkVersion 15
20.          targetSdkVersion 23
21.          versionCode 1
22.          versionName "1.0"
23.      }
24.      buildTypes {
25.          release {
26.              minifyEnabled false
27.              proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
28.          }
29.      }
30.  }
31.  
32.  dependencies {
33.      compile fileTree(dir: 'libs', include: ['*.jar'])
34.      testCompile 'junit:junit:4.12'
35.      compile 'com.android.support:appcompat-v7:23.1.1'
36.      compile 'com.google.dagger:dagger:2.4' //此处添加
37.      apt 'com.google.dagger:dagger-compiler:2.4' //此处添加
38.  }


复制代码

如上,写有“此处添加”的语句,标识是要添加到你自己项目中的,其他的配置默认为你自己项目的配置即可。


  • 开始使用
1、修改UserBean.java类

1.  public class UserBean {
2.  
3.      @Inject
4.      public UserBean() {
5.      }
6.  
7.      public String getName() {
8.          return "yangjingwen";
9.      }
10.  }


复制代码

可以看到,添加了一个无参构造器,并且在构造器上面写了一个@Inject注解。至于@Inject注解的含义,表示通过此构造器创建UserBean对象。


2、新增UserComponent.java接口

1.  @Component
2.  public interface UserComponent {
3.  
4.      void inject(MainActivity activity);
5.  }


复制代码

注意此接口使用@Component注解,在下面我们会详细介绍@Component的作用。


3、修改MainActivity.java类

1.  public class MainActivity extends AppCompatActivity {
2.  
3.      @Inject
4.      UserBean userBean;//此处不能是private修饰符
5.      @Override
6.      protected void onCreate(Bundle savedInstanceState) {
7.          super.onCreate(savedInstanceState);
8.          setContentView(R.layout.activity_main);
9.          //DaggerUserComponent类是自动生成的。此句话的含义表示使用Dagger注入MainActivity中的userBean对象。
10.          DaggerUserComponent.create().inject(this);
11.      }
12.  
13.      public void click(View view) {
14.          Toast.makeText(MainActivity.this, userBean.getName(), Toast.LENGTH_SHORT).show();
15.      }
16.  }


复制代码

注意上面的userBean对象上加了一个@Inject注解。表示此对象需要dagger帮忙创建,即使用dagger创建好了之后,自动给其赋值(注入)。


然后多了一句DaggerUserComponent.create().inject(this);,DaggerUserComponent是自动生成的(通过前面的配置项自动生成)。create()方法就是创建了一个UserComponent对象。


至此,一个使用dagger的简单项目就可以运行起来了。大家可以对比没有使用dagger和使用dagger的区别在哪里(这个很容易发现)。


接下来,我们看看其中使用的@Inject、@Component的含义是什么。



  • 说明

上面的例子,就是在MainActivity中要使用UserBean对象,我们可以用下图形象的表达这种方式(对于一个程序员来说图画得还是不错的):


 


在MainActivity中直接创建UserBean的对象,相对于自由恋爱,女朋友需要你自己去找。


但是因为各种原因,比如生活圈子窄、比如公司女生少,僧多粥少等原因,自己找起来可能比较费劲。这个时候就可以去相亲,相亲的话需要有一个媒婆牵线搭桥,如下面这张形象的图:


 


在这个图中男方找对象,对象就是女方,2人本不相识,通过中介媒婆牵线相亲,最后在一起。但是有一个问题,媒婆怎么知道男方需要找媳妇呢?又是怎么知道女方需要嫁人呢?他们2人肯定要把需求都告诉媒婆。


在这个例子中,女方相当于userBean.java,男方相当于MainActivity.java,媒婆相当于UserComponent.java。然后MainActivity通过@Inject注解将自己想找一个什么样的对象暴露出来,UserBean通过@Inject表示要创建我(我==UserBean),需要通过我(我==UserBean)指定的构造器创建。此时,媒婆UserComponent登场,将2者的意向通过DaggerUserComponent.create().inject()关联起来;之后,郎有情、妾有意,顺理成章MainActivity成功找到一个UserBean对象。



  • 总结

1、Inject:


在构造器上使用Inject注解,表示使用此构造器创建对象。


在变量上使用Inject注解,表示此变量需要dagger来给它创建一个对象。


2、Component:


Component注解就是使用Inject标注的构造器创建一个对象,将创建好的对象赋值给Inject注解的变量中。


3、此片文章重点在于理解Dagger的作用和基本用法。关于Dagger的详细使用方式将在之后的文章中详细介绍,或者可以浏览官网:

http://google.github.io/dagger/



Dagger的官方下载地址:

https://github.com/google/dagger



4、dagger是square公司的一个开源框架,后来google对其进行了修改以至于能更好的在android上使用。所以在Github上,有2个dagger,一个是square公司维护的,一个是google自己维护的。我们这个例子中使用的是google维护的dagger,习惯上称之为dagger2。



源码在Github上,地址为:

https://github.com/yangjingwen2/androiddaggerdemo