美文网首页
史上最适合新手的Dagger2教程(五)命名、限定与延时加载

史上最适合新手的Dagger2教程(五)命名、限定与延时加载

作者: Eternity岚 | 来源:发表于2018-07-27 09:28 被阅读0次

    Dagger2系列教程目录:

    史上最适合新手的Dagger2教程(一)基本注入

    史上最适合新手的Dagger2教程(二)对象注入

    史上最适合新手的Dagger2教程(三)模型与单例

    史上最适合新手的Dagger2教程(四)带参注入

    史上最适合新手的Dagger2教程(五)命名、限定与延时加载

    上节课我们讲到,有些类存在有参和无参两种构造方法,而这两种构造方法此时要用到同一个类下,怎么办?


    比如说我们现在有一个计数器Counter,有带参和不带参两种构造方法:

    public class Counter {
        private int sum;
        public Counter() {
        }
         public Counter(int sum) {
            this.sum = sum;
        }
         public int getSum() {
            return sum++;
        }
    }
    

    此时我要记录本次打开APP的计数和总计的计数:

    public class MainActivity extends AppCompatActivity {
        Counter currentCounter;
        Counter totalCounter;
         @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
    
            currentCounter = new Counter();
            totalCounter = new Counter(10);
        }
    }
    

    水啦~

    按照上节课的内容,我们先把模型、提供者和注入器写好:

    模型与提供者:

    需要注意的是:同一个模型下的提供者的方法名不能雷同,无论参数是否相同。这个和常规的Java代码有出入,请牢记!

    @Module
    public class CounterMoudule {
        private int sum;
        public CounterMoudule(int sum) {
            this.sum = sum;
        }
         @Provides
        public int sumProvider() {
            return this.sum;
        }
         @Provides
        public Counter currentCounterProvider() {
            return new Counter();
        }
         @Provides
        public Counter totalCunterProvider(int sum) {
            return new Counter(sum);
        }
    }
    

    注入器:

    @Component(modules = CounterMoudule.class)
    public interface CounterComponent {
        void inject(MainActivity mainActivity);
    }
    

    接下来,我们用两种方式实现区分注入。

    1.命名(@Named)

    Named,顾名思义——起名字,我们给这两个不同的计数器起不同的名字,问题自然迎刃而解。

    @Named注释标记的是提供者使用对象

    标记提供者:

    @Module
    public class CounterMoudule {
    
          ......
    
        @Provides
        @Named("current")
        public Counter currentCounterProvider() {
            return new Counter();
        }
        @Provides
        @Named("total")
        public Counter totalCunterProvider(int sum) {
            return new Counter(sum);
        }
    }
    

    标记使用对象:

    public class MainActivity extends AppCompatActivity {
        @Named("current")
        @Inject
        Counter currentCounter;
        @Named("total")
        @Inject
        Counter totalCounter;
         @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
    
            DaggerCounterComponent.builder().counterMoudule(new CounterMoudule(10)).build().inject(this);
    
            Log.e("current", currentCounter.getSum() + "");
            Log.e("total", totalCounter.getSum() + "");
        }
    }
    

    运行结果:

    2.限定(@Qualifier)

    Qualifier限定,由于Named是通过匹配字符串作为区分条件,在大项目中显得不够严谨,于是就有了限定这个注解。

    @Qualifier注解标记的是:自定义注解,对Java注解方面的知识要求较高,不了解的同学可以先去学习一下Java自定义注解

    自定义当前计数器注解:

    @Qualifier
    @Retention(RetentionPolicy.RUNTIME)
    public @interface CurrentCounter {
    }
    

    自定义总计数器注解:

    @Qualifier
    @Retention(RetentionPolicy.RUNTIME)
    public @interface TotalCounter {
    }
    

    注意:被限定标记的注解必须是运行时注解。

    其余地方把@Named替换成自定义注解即可:

    提供者:

    @Module
    public class CounterMoudule {
    
          ......
    
        @Provides
        @CurrentCounter
        public Counter currentCounterProvider() {
            return new Counter();
        }
         @Provides
        @TotalCounter
        public Counter totalCunterProvider(int sum) {
            return new Counter(sum);
        }
    }
    

    标记使用对象:

    public class MainActivity extends AppCompatActivity {
        @CurrentCounter
        @Inject
        Counter currentCounter;
        @TotalCounter
        @Inject
        Counter totalCounter;
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            DaggerCounterComponent.builder().counterMoudule(new CounterMoudule(10)).build().inject(this);
            Log.e("current", currentCounter.getSum() + "");
            Log.e("total", totalCounter.getSum() + "");
        }
    }
    

    3.懒加载

    最后,我们介绍一下Dagger2的大杀器!——智能懒加载。

    懒加载,就是在需要的时候才对成员变量进行初始化,这样可以大幅缩短应用初始化的时间。

    我们只要使用Lazy<T>修饰变量即可:

        @Inject
        Lazy<Object> object;
    

    End.

    Dagger2的所有基础知识就在这里了,怎么样,是不是非常简单呢?

    喜欢我教程风格的朋友请不要客气的关注一下嘛~

    相关文章

      网友评论

          本文标题:史上最适合新手的Dagger2教程(五)命名、限定与延时加载

          本文链接:https://www.haomeiwen.com/subject/wxlwmftx.html