zoukankan      html  css  js  c++  java
  • Dagger2系列之使用方法

      本系列只讲使用方法和使用中遇到的问题,如果还对dagger2还不了解的童鞋儿可以参考文章:

                          http://www.jianshu.com/p/cd2c1c9f68d4

                          http://www.jianshu.com/p/94d47da32656

      使用Dagger2的前提需要添加一些依赖:

        1  在Project的 build.gradle文件添加以下内容

    buildscript {
        repositories {
            jcenter()
        }
        dependencies {
             classpath 'com.android.tools.build:gradle:2.1.0'
    classpath 'com.neenbedankt.gradle.plugins:android-apt:1.4' } }

       2  在Module下的build.gradle添加以下内容 

    apply plugin: 'com.android.application'
    apply plugin: 'com.neenbedankt.android-apt'
    
    dependencies {
        apt 'com.google.dagger:dagger-compiler:2.4'
        compile 'com.google.dagger:dagger:2.4'
        provided 'org.glassfish:javax.annotation:10.0-b28'
    } 

      下面我们学习一下Dagger2的使用。

    <一>目标类和被依赖的类,都是我们直接可修改的。

      1  在被依赖类的构造函数上使用@inject注解

    public class NeedProvide {
        @Inject
        public NeedProvide(){
        }
    
        public void printMethod(){
            Log.d("Dagger.class","NeedProvide----printMethod()");
        }
    }

       2  创建Component,作为目标类和被依赖类的桥梁,并被@Component注解

    @Component
    public interface NeedComponent {
        void inject(TargetActivity activity);
    }

      3  运行一下,让项目生产XXXComponent

      4  在目标类中利用XXXComponent进行依赖注入

    DaggerNeedComponent.builder().build().inject(this);

      5  依赖注入完毕后,通过@inject使用被依赖类

    public class TargetActivity extends AppCompatActivity {
    
        @Inject
        NeedProvide mNeedProvide;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
    
            DaggerNeedComponent.builder().build().inject(this);
            mNeedProvide.printMethod();
        }
    }

      这里有三种角色。目标类TargetActivity,被依赖类NeedProvide,桥梁NeedComponent。

      这种方法适用于目标类和被依赖类都是我们自己创建的时候。在使用第三方库的时候,无法直接在类构造函数中添加@Inject注解。或者被依赖类有多个构造函数的时候,不能注解多个构造函数,这样会产生歧义,因为Dagger2无法确认调用哪一个构造函数,来生成类的实例对象。此时这种方法就失效了,下面请看第二种方法。

    <二>创建Module提供我们被依赖类,使用@Provides注解修饰

      这种方法步骤和上面一样,只不过修改我们添加一些注解,直接看代码。

    被依赖类:  

    public class NeedProvideS {
    
        public NeedProvideS(){
        }
    
        public void printMethod(){
            Log.d("Dagger.class","NeedProvideS----printMethod()");
        }
    
    }  

      这里将NeedProvideS类构造器上的@inject注解去掉了(不去掉也行,此处为了防止第一种方法对本次影响)。

    被依赖类的封装类即Module:           

    @Module
    public class ProvideModuleS {
    
        @Provides
       public NeedProvideS provideNeedProvide(){
            return  new NeedProvideS();
       }
    
    }

      使用Module封装被依赖类的目的在之前说过。此处我们看看这个类,类上用@Module注解修饰,方法是提供被依赖类的,所以用@Provides修饰,目的是为了让dagger能够查找到。

    @Module
    public class ProvideModuleS {
    
        @Provides
       public NeedProvideS provideNeedProvide(Bean bean){
            return  new NeedProvideS(bean);
       }
    
        @Provides
        public Bean provideBean(){
            return new Bean();
        }
    
    }

      当我们某一个方法需要参数的时候,它会自动去查找本类其他被@Module注解修改的方法。

    桥梁:

    @Component(modules = ProvideModuleS.class)
    public interface NeedComponentS {
        void inject(TargetActivityS activity);
    }

      此处使用了modules属性,指定提供封装了被依赖类的封装类。Component还可以依赖多个Module。下篇会讲。

    目标类:

    public class TargetActivityS extends AppCompatActivity {
    
        @Inject
        NeedProvideS mNeedProvideS;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
    
            DaggerNeedComponentS.builder().build().inject(this);
            mNeedProvideS.printMethod();
        }
    }

      上面我们介绍了dagger2使用的两种方法,那如果实际情况中,两种方法都用,那么默认会先使用哪种方法创建实列那?其实在构建类实例的时候,会按照以下顺序执行:

    从Module中查找类实例创建方法

    1. Module中存在创建方法,则看此创建方法有没有参数
      1. 如果有参数,这些参数也是由Component提供的,返回步骤1逐一生成参数类实例,最后再生成最终类实例
      2. 如果无参数,则直接由这个方法生成最终类实例
    2. Module中没有创建方法,则从构造函数里面找那个用@Inject注解的构造函数
      1. 如果该构造函数有参数,则也是返回到步骤1逐一生成参数类实例,最后调用该构造函数生成类实例
      2. 如果该构造函数无参数,则直接调用该构造函数生成类实例

      以上就是一次注入生成类实例的生成步骤。(copy others,原文链接:http://www.jianshu.com/p/94d47da32656)

      Dagger2最基本的使用方法已经介绍完毕了,下一遍我会讲解我在实际使用的时候遇到的问题。

  • 相关阅读:
    洛谷 P3384 【模板】树链剖分
    codevs 4633 [Mz]树链剖分练习
    看一个人的回答有感(怎么判断数组中有没有未定义的值,如:[,,1,,3])
    bzoj2754: [SCOI2012]喵星球上的点名
    bzoj4456: [Zjoi2016]旅行者
    bzoj4574:Zjoi2016线段树 dp
    bzoj4455: [Zjoi2016]小星星
    bzoj4516: [Sdoi2016]生成魔咒
    uoj#207. 共价大爷游长沙
    bzoj4530:[Bjoi2014]大融合
  • 原文地址:https://www.cnblogs.com/lang-yu/p/6238062.html
Copyright © 2011-2022 走看看