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
@Inject
Lazy
End.
Dagger2的所有基础知识就在这里了,怎么样,是不是非常简单呢?
最后是宇宙惯例~
喜欢我教程风格的朋友请不要客气的关注一下嘛~