dagger2的使用

1.dagger2是what?

dagger2是一个依赖注入的框架,现在是由Google进行维护

2.什么是依赖注入

依赖注入是面向对象编程的一种设计模式,其目的是为了降低程序耦合,这个耦合就是类之间的依赖引起的.

example:

  public class ClassA{
        private ClassB b
        public ClassA(ClassB b){
        this.b = b    }
    }

 这里的classA的构造函数里传了一个参数ClassB,随着后续业务增加也许又需要传入ClassC等。如果一个工程有很多个文件使用到到了ClassA则需要修改很多个文件

所以这并不符合开闭原则,如果使用Dagger2就会解决此问题

  public class ClassA{
     @inject 
      private ClassB b 
      public ClassA(){
       }
    }

通过注解的方式将ClassB b注入到ClassA中,可以灵活设置ClassA的属性不影响其他文件对

三、如何使用Dagger2

在实际的项目中一般Dagger2和MVP模式配合使用。

example demo:

模拟登录的业务,Model ,View,Presenter

model:

//model 类

public class User implements Serializable{

    private int id;

    private String userName;

    private String pwd;

}

//Iview 类

public interface ICommonView{

   Context getContext();

}

View:

//activity

public class LoginActivity extends AppCompatActivity implements ICommonView {

  @BindView(R.id.btn_login)

  Button btn;

  @Override

  protected void onCreate(@Nullable Bundle savedInstanceState) {

    super.onCreate(savedInstanceState);

    setContentView(R.layout.activity_login);

    ButterKnife.bind(this);

  }

  @OnClick(R.id.btn_login) void login(){

  }

  @Override

  public Context getContext() {

    return this;

  }

}

presenter:

public class LoginPresenter{

  ICommonView iView;

  public LoginPresenter(ICommonView iView){

    this.iView = iView;

  }

  public void login(User user){

    Context mContext = iView.getContext();

     Toast.makeText(mContext,"login-----",Toast.LENGTH_SHORT).show();

 }

}

2.导入Dagger2

compile"com.google.dagger:dagger:2.14.1"
annotationProcessor"com.google.dagger:dagger-compiler:2.14.1"

注:后面的版本号可以到:https://github.com/google/dagger 获取最新版本

定义一个注解ActivityScope

@Scope

@Retention(RetentionPolicy.RUNTIME)

public @interface ActivityScope{

}

这个注解ActivityScope到底是干什么的呢,后面分解

3.创建一个类CommonModule,注意这里用到了刚才定义的@ActivityScope注解

@Module

public class CommonModule{

   private ICommonView iView;

   public CommonModule(ICommonView iView){

     this.iView = iView;

  }

  @Provides

  @ActivityScope

   public ICommonView provideIcommonView(){

      return this.iView;

   }

}

4.创建一个接口CommonComponent

@ActivityScope

@Component (modules = CommonModule.class)

public insterface CommonComponent{

   void inject(LoginActivity activity);

}

5.build 一下项目,然后在LoginPresenter里面使用@Inject

public class LoginPresenter{

   ICommonView iView;

   @Inject

   public LoginPresenter(ICommonView iView){

      this.iView=iView;

  }

  public void login(User user){

     Context mContext = iView.getContext();

     Toast.makeText(mContext,"login.......",Toast.LENGTH_SHORT).show();

  }

}

6.在LoginActivity中使用CommonComponent接口

public class LoginActivity extends AppCompatActivity implements ICommonView{

   

  @BindView(R.id.btn_login)

  Button btn;

  @Inject

  LoginPresenter presenter;

  @Override

  protected void onCreate(@Nullable Bundle savedInstanceState) {

  super.onCreate(savedInstanceState);

  setContentView(R.layout.activity_login);

  ButterKnife.bind(this);

  DaggerCommonCompnent.

  builder().

  commonModule(new CommonModule(this)).

  build().

  Inject(this);

 }

  @OnClick(R.id.btn_login) void login(){

  presenter.login(new User());

}

  @Override

  protected void onDestroy() {

  super.onDestroy();

}

  @Override

  public Context getContext() {

  return this;

 }

}

在这里loginPresenter并没有初始化。这里一个重点就是loginPresenter和loginActivity解耦,后续无论是怎么修改loginPresenter得构造方法都不需要改动LoinActivity的代码。而只需要修改CommonModudle

annotationProcessor"com.google.dagger:dagger-compiler:2.14.1"是什么情况?

annotationProcessor是处理注解的工具,是APT(Annotation Processing Tool)

的一种,简单来说注解提供的都是一种“标记”,真正使这些“标记”work的是APT,在build的过程中,APT(就是dagger-compiler)扫描到注解(@Component@Module)生成的.这个过程用下面这张图表示:

那么apt扫描之后会怎样呢?看一下上面demo的build-->generate-->source-->apt目录下面都有什么:

生成了很多文件。就是apt替我们写了很多类和实现方法。这些文件里面的内容墙裂推荐大家看看

ActivityScope是干啥的?怎么里面啥内容都没有?

自定义注解ActivityScope作用是限定被它标记的对象生命周期与对应的Activity相同。其实注解里我们使用了2个元注解

@Scope:标记局部单例;@Retention :指定了它是运行时注解,就是说注解不仅被保存到class文件中,jvm加载class文件之后,仍然存在.

那么,就凭这两个元注解,为啥可以限定被它标记的对象生命周期与对应的Activity相同呢?我们看一下CommonComponent生成类

 

看看LoginPresenter的构造方法就知道provideIcommonViewProvider的作用了。那为啥说提供了provideIcommonViewProvider单例就保证了生命周期和LoginActivity绑定了呢?如果还不明白就想想LoginPresenter的生命周期。

另一个例子:

https://github.com/brusewu/example-dagger.git

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值