Dagger 2学习笔记

最近看github的时候,看到很多项目都已经用到Dagger 2了。现在Dagger 2已经有Google开始维护了,相信Dagger 2在Android中的应用将会越来越广泛。觉得有必要好好学习一下Dagger 2。

什么是Dagger

Dagger是android的一个依赖注入框架,有别于其他的依赖注入框架使用的反射机制,Dagger是利用编译时生成辅助类的方式来完成调用,所以效率有了很大的提升,非常适合用于Android开发。Google从square那儿接手了Dagger之后,号称将Dagger的效率又提升了13%。

Dagger 注释

从注释开始学习最直观。一般Dagger中 常用的注释有:

@Inject:

Dagger使用的是 javax.inject.Inject。主要作用有:
1.修饰变量,表示这个变量为需要注入的依赖。
@Inject
    EmployeePresenter employeePresenter;


2.修饰构造函数,表示如果这个类有需要被注入依赖时,Dagger会调用这个构造函数来进行实例化。
 @Inject
    public EmployeePresenter() {
        Log.d(TAG, "EmployeePresenter() called!");
    }



那么问题来了,什么时候通知Dagger开始注入呢?这个就保留到@Component中讲。

@Module:

用来修饰类,表示此类的方法是用来提供依赖的。
@Module
public class UserModule {
    @Provides
    @Type("coder")
    Employee createCoder() {
        return new Employee("coder");
    }

    @Provides
    @Type("boss")
    Employee createBoss() {
        return new Employee("boss");
    }
}

此处的@Type注释,请看@Qualifier


@Provides

只能用来修饰Module类中的方法,用来提供依赖的实例。在这个方法中,我们可以自定义这个依赖的实例化的方式。这也是@Inject的一种补充,因为很多时候我们没办法使用@Inject,如:interface没有构造函数,自然不能使用@Inject,又或者比如 Activity的构造函数是封装好的,我们不能改变,所以也不能用@inject

@Component

修饰接口,起到注入器的作用,是@Inject和@Module之间的桥梁。提供所有你定义类型的实例。
@Component(modules = {UserModule.class})
public interface UserComponent {
    void inject(UserListActivity activity);
    @Type("coder")
    Employee createCoder();

    @Type("boss")
    Employee createBoss();
}
此处的@Type注释,请看@Qualifier


这是MainActivity中的部分代码
 private UserComponent userComponent;
    @Inject
    EmployeePresenter employeePresenter;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        initializeInjectors();
    }

    private void initializeInjectors() {
        userComponent = DaggerUserComponent.builder().userModule(new UserModule()).build();//DaggerUserComponent就是Dagger在编译时自动生成的一个UserComponent的实现。
       // userComponent = DaggerUserComponent.create(); //在Component中的Module都是默认的构造函数是,也可以使用create()来简化实例化的代码。
        userComponent.inject(this); //就是在这里通知Dagger去实例化需要注入的依赖的
    }


@Scope

在Dagger中,依赖只有singleton和非singleton之分。@Singleton标记是用于Application-Lever的单例。自定义的scope用于生命周期更短的依赖,如:@PerActivity表示生命周期跟Activity一样,但这只是语义上的标记而已,实际的生命周期管理还需要代码控制。

@Qualifier

当类的类型不足以区分依赖时,就要使用这个标记了。比如,你需要注入两个String类型的实例:userName(), userTitle()。这个时候 Dagger就没有办法区分了,所以就要用到@Qualifier来进一步区分。
@Module
public class UserModule {
    @Provides
//    @Type("coder")
    Employee createCoder() {
        return new Employee("coder");
    }

    @Provides
//    @Type("boss")
    Employee createBoss() {
        return new Employee("boss");
    }
}

@Component(modules = {UserModule.class})
public interface UserComponent {
    void inject(MainActivity activity);
//    @Type("coder")
    Employee createCoder();

//    @Type("boss")
    Employee createBoss();

}

在Module和Component中,分别有createBoss()和createCoder(),他们的参数,和返回值都一样,所以Dagger没办法区分他们,来进行Component和Module中方法的匹配。以上代码我注释掉了@type,编译时Dagger就报错了


要解决这个错误就要使用@Qualifier。
@Qualifier
@Documented
@Retention(RetentionPolicy.RUNTIME)
public @interface Type {
    String value() default "";
}

这样就自定义了一个注释Type,用来区分以上Coder,Boss的问题。
分别在Component和Module中,对应加上@Typ("coder"),@Type("Boss"),Dagger就可以识别匹配了。


  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值