android系统框架之Dagger2

    xiaoxiao2021-03-25  132

    前:最近Darrger2+MVP+Retrofit+Rx系列构建的系统框架模式好像还挺热,这些框架在之前做的开发中都选用过。准备花一些时间系统的从各个的使用Demo到联合搭建成一个应用的框架,本篇是这一系列的第一篇view层的Dagger2的使用。

    目录

    目录一句话总结Dagger2基本使用简介 Dagger2注解简介 示例 injectComponent 无参构造有参构造或不能修改多个Module单例注解 小结


    一句话总结

    Dagger2是google开发和维护的采用依赖注入模式进行view层解耦的框架。

    gitHub:https://github.com/google/dagger

    android在bulid.gradle里加上(需要使用APT插件)

    dependencies { … compile ‘com.google.dagger:dagger:2.4’ apt ‘com.google.dagger:dagger-compiler:2.4’ //java注解 compile ‘org.glassfish:javax.annotation:10.0-b28’

    }

    APT插件需要 bulid.gradle(Modle:app)内

    apply plugin: ‘com.neenbedankt.android-apt’

    bulid.gradle(Project:xxx)内

    dependencies { * classpath ‘com.neenbedankt.gradle.plugins:android-apt:1.8’ }

    Dagger2基本使用简介

    Dagger2注解简介

    Dagger2是基于Java注解来实现依赖注入的,那么在正式使用之前我们需要先了解下Dagger2中的注解。Dagger2使用过程中我们通常接触到的注解主要包括:@Inject, @Module, @Provides, @Component, @Qulifier, @Scope, @Singleten。

    -@Inject 顾名思义 就是注入的意思 ,有两个作用1:标记需要被注入的变量;2:标记构造函数,即为需要被注入的变量提供相关事例(有点拗口。。。)

    -@Module 模版用于标记提供注入的类,用于补充@Inject所不能使用的地方。

    -@Provides 用于标记已经标记过@Module类中的方法,类似只提供相应的方法接口出去给别的类调用的这种方式

    -@Component 用于标注接口 是标注的依赖类和标注的注入类的桥接类(类似MVP中的P层),被此接口标注的接口会在编译的时候生成实现类,注入类通过调用此实现类来注入

    -@Qulifier 用于自定义注解。用于解决当多个被@Module注解的类中有若干个(>1)个标注@Provides的方法时,用于分他们

    -@Scope 用于自定义注解,限注解的作用域,局部单例

    -@Singleten用于自定义注解,单例(准确是说在Component 作用域内的单例,一般是全局单例)

    示例

    @inject+@Component (无参构造)

    简单的写一个人吃饭的示例 首先有个Hand类代表手

    public class Hand { @Inject Hand(){} public void eat(){ System.out.println("人吃东西"); } }

    在Hand类的无参构造函数上加@Inject注解表明这个为提供依赖类,之后创建People类通过@Inject将Hand类作为参数注解进来(此时DaggerPeopleComponent还没有被创建 所以还不能用)

    public class People { @Inject Public Hand mHand; public People() { //(此时还不能用,需要编译一下) DaggerPeopleComponent.builder().build().inject(this); } }

    之后需要一个接口类来管理依赖类与注入类(可提供多个)

    @Component public interface PeopleComponent { void inject(People people); }

    此时,重新编译一个项目 这样DaggerPeopleComponent就会被创建出来

    @Generated( value = "dagger.internal.codegen.ComponentProcessor", comments = "https://google.github.io/dagger" ) public final class DaggerPeopleComponent implements PeopleComponent { private MembersInjector<People> peopleMembersInjector; private DaggerPeopleComponent(Builder builder) { assert builder != null; initialize(builder); } public static Builder builder() { return new Builder(); } public static PeopleComponent create() { return builder().build(); } @SuppressWarnings("unchecked") private void initialize(final Builder builder) { this.peopleMembersInjector = People_MembersInjector.create(Hand_Factory.create()); } @Override public void inject(People people) { peopleMembersInjector.injectMembers(people); } public static final class Builder { private Builder() {} public PeopleComponent build() { return new DaggerPeopleComponent(this); } } }

    看以下Dagger2帮我们创建的实现类,就是建造者模式+java中的注入。并不是很难看懂。此时People类中的DaggerPeopleComponent.builder().build().inject(this);就可以使用了。 之后在people类中就可以直接调用mHand的eat方法了people.mHand.eat(); 输出结果System.out: 人吃东西

    有参构造或不能修改

    首先Hand类是有参的构造函数或者不能修改Hand类

    public class Hand { String type; Hand(String type) { this.type = type; } public void eat() { System.out.println(type+"人吃东西"); } } 情况类似。只为说明不能将注解添加到此class上)

    接着需要一个Module类用来对Hand类进行扩展(@Module+@Provides)

    @Module public class HandModule { public HandModule(String type) { this.type = type; } String type; public HandModule(){} @Provides Hand ProvidesGetHand(){ return new Hand(type); } }

    对Component的这个接口进行限制

    @Component(modules = HandModule.class) public interface PeopleComponent { void inject(People people); }

    还差一个people类

    public class People { @Inject public Hand mHand; public People() { // DaggerPeopleComponent.builder().build().inject(this); DaggerPeopleComponent.builder().HandParams(new HandModule("中国")).build().inject(this); } }

    重新编译以下后就可以使用了。 输出结果System.out: 中国人吃东西

    多个Module

    当有多个Module时需要使用@Qulifier进行区分 首先要有两个注解类

    @Qualifier @Retention(RetentionPolicy.RUNTIME) public @interface QulifierChinese { } 和 @Qualifier @Retention(RetentionPolicy.RUNTIME) public @interface QulifierForeigner { }

    Module 需要在你调用的方法上面加入相应的注解 这样就保证了调用的唯一性,也去掉了不同module下相同方法名不能识别的问题。因为返回结果根据你添加的注解头确定。

    @Module public class HandModule { public HandModule(String type,String code) { this.type = type; this.code = code; } String code; String type; public HandModule(){} @QulifierChinese @Provides Hand ProvidesGetHandChinese(){ return new Hand(type); } @QulifierForeigner @Provides Hand ProvidesGetHandForeigner(){ return new Hand(code); } }

    @Component那边不需要修改.Peolpe类中需要根据你使用的方法添加特定的注解头

    public class People { @QulifierChinese @Inject public Hand mHandChinese; @QulifierForeigner @Inject public Hand mHandForeigner; public People() { // DaggerPeopleComponent.builder().build().inject(this); DaggerPeopleComponent.builder().handModule(new HandModule("中国","外国")).build().inject(this); } }

    输出结果System.out: 中国人吃东西/System.out: 外国人吃东西 输入根据你调用的方法

    单例注解

    首先需要一个注解类

    @Scope @Retention(RetentionPolicy.RUNTIME) public @interface HandScope { }

    接着需要使用@Scope注解分别标注 Module和@Compentent注解类。代码就不贴了就加了两个标注头 @HandScope

    小结

    以上就是Dagger2的基本用法,不过dagger2常用与跟MVP结合在一起,下一篇将与mvp结合在一起展示实际用法。

    转载请注明原文地址: https://ju.6miu.com/read-13451.html

    最新回复(0)