android dagger2使用笔记
Dependency Injecte(依赖注入)
首先写个不使用依赖注入的示例
- interface
// House.java
public interface House {
    void prepareForWar();
    void reportForWar();
}
- 新建两个实现 House 接口的类
// Starks.java
public class Starks implements House {
    @Override
    public void prepareForWar() {
        //do something
        System.out.println(this.getClass().getSimpleName()+" prepared for war");
    }
    @Override
    public void reportForWar() {
        //do something
        System.out.println(this.getClass().getSimpleName()+" reporting..");
    }
}
// Boltons.java
public class Boltons implements House {
    @Override
    public void prepareForWar() {
        //do something
        System.out.println(this.getClass().getSimpleName()+" prepared for war");
    }
    @Override
    public void reportForWar() {
        //do something
        System.out.println(this.getClass().getSimpleName()+" reporting..");
    }
}
- 接着需要一个依赖于这两个的类的类
public class War {
    private Starks starks;
    private Boltons boltons;
    public War(){
        starks = new Starks();
        boltons = new Boltons();
        starks.prepareForWar();
        starks.reportForWar();
        boltons.prepareForWar();
        starks.reportForWar();
    }
}
- 下次改用依赖注入的方式实现这个类
public class War {
    private Starks starks;
    private Boltons boltons;
    //DI - getting dependencies from else where via constructor
    public War(Starks starks, Boltons bolton){
        this.starks = starks;
        this.boltons = bolton;
    }
    public void prepare(){
        starks.prepareForWar();
        boltons.prepareForWar();
    }
    public void report(){
        starks.reportForWar();
        boltons.reportForWar();
    }
}
- 从外部注入依赖的对象
public class BattleOfBastards {
    public static void main(String[] args){
        Starks starks = new Starks();
        Boltons boltons = new Boltons();
        War war = new War(starks,boltons);
        war.prepare();
        war.report();
    }
}
利用dagger2进行依赖注入
- Dagger 2 works on Annotation processor. 需要了解一定的java注解知识
- 首先了解dagger2最常用的2个注解 @Inject和@Component
@Inject Annotation
可以作用于
- 构造器
- 字段
- 方法
@Inject注解告诉dagger哪些方法,构造器或者字段是需要依赖注入
But @Inject doesn’t work everywhere:
- Interfaces can’t be constructed.
- Third-party classes can’t be annotated.
- Configurable objects must be configured!
@Component Annotation
作用于接口
@Componentdagger会生成一个实现该接口的class,该class会实现其中的方法,提供需要依赖的对象,相当于是一个代理
修改的代码
添加默认构造器,并添加注解@Inject
public class Boltons implements House {
    // 添加默认构造器,并添加注解@Inject
   @Inject
   public Boltons(){
    }
    @Override
    public void prepareForWar() {
        //do something
        System.out.println(this.getClass().getSimpleName()+" prepared for war");
    }
    @Override
    public void reportForWar() {
        //do something
        System.out.println(this.getClass().getSimpleName()+" reporting..");
    }
}
public class Starks implements House {
    @Inject //Dagger 2
    public Starks(){
    }
    @Override
    public void prepareForWar() {
        //do something
        System.out.println(this.getClass().getSimpleName()+" prepared for war");
    }
    @Override
    public void reportForWar() {
        //do something
        System.out.println(this.getClass().getSimpleName()+" reporting..");
    }
}
public class War {
    private Starks starks;
    private Boltons boltons;
    @Inject
    public War(Starks starks, Boltons bolton){
        this.starks = starks;
        this.boltons = bolton;
    }
    public void prepare(){
        starks.prepareForWar();
        boltons.prepareForWar();
    }
    public void report(){
        starks.reportForWar();
        boltons.reportForWar();
    }
}
- 修改依赖加载方式
public class BattleOfBastards {
    public static void main(String[] args){
//        Mannual DI
//        Starks starks = new Starks();
//        Boltons boltons = new Boltons();
//        War war = new War(starks,boltons);
//        war.prepare();
//        war.report();
//      Using Dagger 2
        BattleComponent component = DaggerBattleComponent.create();
        War war = component.getWar();
        war.prepare();
        war.report();
    }
}
在build之后查看annotation processor 自动生成的代码
- 如图

- DaggerBattleComponent.java 为dagger自动生成的代码,已类名加上Dagger前缀命名, 该类实现了BattleComponent接口
package com.explore.lin.didemo.javaDIdemo;
import javax.inject.Provider;
public final class DaggerBattleComponent implements BattleComponent {
  private Provider<War> warProvider;
  private DaggerBattleComponent(Builder builder) {
    assert builder != null;
    initialize(builder);
  }
  public static Builder builder() {
    return new Builder();
  }
  public static BattleComponent create() {
    return new Builder().build();
  }
  @SuppressWarnings("unchecked")
  private void initialize(final Builder builder) {
    this.warProvider = War_Factory.create(Starks_Factory.create(), Boltons_Factory.create());
  }
  @Override
  public War getWar() {
    return new War(new Starks(), new Boltons());
  }
  public static final class Builder {
    private Builder() {}
    public BattleComponent build() {
      return new DaggerBattleComponent(this);
    }
  }
}
- 继续在component中添加方法
@Component
interface BattleComponent {
    War getWar();
    //adding more methods
    Starks getStarks();
    Boltons getBoltons();
}
- 观察dagger2生成的DaggerBattleComponent中
  // DaggerBattleComponent.java
  @Override
  public War getWar() {
    return new War(new Starks(), new Boltons());
  }
  @Override
  public Starks getStarks() {
    return new Starks();
  }
- 如果我们删除Boltons.java构造器中的注解@Inject,会发现无法通过编译,因为在war.java的构造器中存在对Boltons的依赖
总结
比如有个classA中存在对classB的依赖,用dagger2怎么实现呢
- 一种
class A {
    @Inject
    public A() {
    }
    @Inject
    B b;
    void act() {
        b.prepare();
    }
}
class B {
    @Inject
    public B() {
    }
    void prepare() {
        System.out.println("b.prepare()");
    }
}
@Component
interface AComponent {
    A a();
}
public class InjectDemo {
    public static void main(String[] args) {
        DaggerAComponent.create().a().act();
    }
}
- 二,什么时候使用@Provide,比如你使用第三方库,或则B中构造器没有@Inject时
class AP {
    @Inject
    public AP() {
    }
    @Inject
    BP bp;
    void act() {
        bp.prepare();
    }
}
class BP {
    void prepare() {
        System.out.println("bp.prepare()");
    }
}
@Component(modules = {APModule.class})
interface APComponent{
    AP ap();
}
@Module
class APModule {
    @Provides
    BP providerBP() {
        return new BP();
    }
}
public class ProvideDemo {
    public static void main(String[] main) {
        DaggerAPComponent.create().ap().act();
    }
}
在android中应用dagger
- 同样先新建不使用dagger的项目
参考https://github.com/DaiHangLin/dependencyInjecte
android dagger2使用笔记的更多相关文章
- Android自动化学习笔记:编写MonkeyRunner脚本的几种方式
		---------------------------------------------------------------------------------------------------- ... 
- Android自动化学习笔记之MonkeyRunner:官方介绍和简单实例
		---------------------------------------------------------------------------------------------------- ... 
- android开发学习笔记000
		使用书籍:<疯狂android讲义>——李刚著,2011年7月出版 虽然现在已2014,可我挑来跳去,还是以这本书开始我的android之旅吧. “疯狂源自梦想,技术成就辉煌.” 让我这个 ... 
- Android动画学习笔记-Android Animation
		Android动画学习笔记-Android Animation 3.0以前,android支持两种动画模式,tween animation,frame animation,在android3.0中 ... 
- Android 数字签名学习笔记
		Android 数字签名学习笔记 在Android系统中,所有安装到系统的应用程序都必有一个数字证书,此数字证书用于标识应用程序的作者和在应用程序之间建立信任关系,如果一个permission的pro ... 
- Android高级编程笔记(四)深入探讨Activity(转)
		在应用程序中至少包含一个用来处理应用程序的主UI功能的主界面屏幕.这个主界面一般由多个Fragment组成,并由一组次要Activity支持.要在屏幕之间切换,就必须要启动一个新的Activity.一 ... 
- Android群英传笔记——第十二章:Android5.X 新特性详解,Material Design UI的新体验
		Android群英传笔记--第十二章:Android5.X 新特性详解,Material Design UI的新体验 第十一章为什么不写,因为我很早之前就已经写过了,有需要的可以去看 Android高 ... 
- Android群英传笔记——第十章:Android性能优化
		Android群英传笔记--第十章:Android性能优化 随着Android应用增多,功能越来越复杂,布局也越来越丰富了,而这些也成为了阻碍一个应用流畅运行,因此,对复杂的功能进行性能优化是创造高质 ... 
- Android群英传笔记——第九章:Android系统信息和安全机制
		Android群英传笔记--第九章:Android系统信息和安全机制 本书也正式的进入尾声了,在android的世界了,不同的软件,硬件信息就像一个国家的经济水平,军事水平,不同的配置参数,代表着一个 ... 
随机推荐
- 图学java基础篇之IO
			java io体系 如图可以看出,java的io按照包来划分的话可以分为三大块:io.nio.aio,但是从使用角度来看,这三块其实揉杂在一起的,下边我们先来概述下这三块: io:主要包含字符流和字节 ... 
- 爬虫工程师常用的 Chrome 插件
			做多了爬虫都知道,写一个爬虫大部分时间不是在代码上,而是在分析网页上,所有有一套好用的工具可以极大节省劳动力,这里把平时积累的一些 Chrome 插件分享出来,均来自本人和同事推荐,并不定时更新,欢迎 ... 
- datagrid的toolbar的两种实现方式
			datagrid的toolbar的两种实现方式 1.在html文件中,可以在设置toolbar="#tb",再在div中设置id="tb" <table ... 
- cakephp 中Console / Shell 有什么优点?
			Which is the advantage of using CakePHP Console / Shell for programmed tasks ? 查看原文 最近用到了cakephp中的sh ... 
- Windows Server 2012 R2:细节信息汇总
			Windows Server 2012 R2:细节信息汇总 2013年08月09日00:10 it168网站原创 作者:核子可乐编译 编辑:王晓东 我要评论(0) 标签: 操作系统 , Windows ... 
- 【Rotate List】cpp
			题目: Given a list, rotate the list to the right by k places, where k is non-negative. For example:Giv ... 
- windows下使用grunt
			grunt官网:http://www.gruntjs.org/ 一.安装grunt 先安装node,在http://www.nodejs.org/可以下载安装包直接安装.在命令行下运行: npm in ... 
- load_file()与into outfile函数详解
			load_file()函数的使用: 1.使用条件 ①有读取文件的权限 r and (select count(*) from mysql.user)>0 如果返回正常则说明有权限,反之没有 ②文 ... 
- 第1章 HTML基础
			1.1 HTML概述 1.1.1 什么是HTML HTML(Hyper Text Markup Language,超 文本 标记 语言)是纯文本类型的语言,它是Internet上用于编写网页的主要语言 ... 
- 【LeetCode】Implement strStr()(实现strStr())
			这道题是LeetCode里的第28道题. 题目描述: 实现 strStr() 函数. 给定一个 haystack 字符串和一个 needle 字符串,在 haystack 字符串中找出 needle ... 
