dagger2的Qualifier与Scope

Posted lijianming180

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了dagger2的Qualifier与Scope相关的知识,希望对你有一定的参考价值。

Qualifier即Named

当module的@Provides提供相同变量的不同属性时:用于区分把哪一个初始化

Module
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
public class {
@Blue
@Provides
public Cloth getBluecloth(){
Cloth mCloth=new Cloth();
mCloth.setColor("蓝");
return mCloth;
}
@Named("Red")
@Provides
public Cloth getRedcloth(){
Cloth mCloth=new Cloth();
mCloth.setColor("红");
return mCloth;
}
}
Component
1
2
3
4
@Component(modules=ClothModule.class)
public interface ClothCompetent {
void inject(MainActivity mainActivity);
}
Activity
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
public class MainActivity extends AppCompatActivity {
TextView mTextView;
@Named("Red")
@Inject
Cloth mClothRed;
@Blue
@Inject
Cloth mClothBlue;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mTextView= (TextView) findViewById(R.id.tv1);
ClothCompetent mClothCompetent=DaggerClothCompetent.builder().clothModule(new ClothModule()).build();
mClothCompetent.inject(this);
mTextView.setText(mClothRed+"n"+mClothBlue);
}
}
Qualifier

自定义的Qualifier与官方的Named原理一样

1
2
3
4
@Qualifier
@Retention(RetentionPolicy.RUNTIME)
public @interface Blue {
}

官方的Named

1
2
3
4
5
6
7
8
@Qualifier
@Documented
@Retention(RUNTIME)
public @interface Named {
String value() default "";
}

Scope即Singleton

以Component为依据,在指定范围内的单例

Module
  1. 在@Provides为外界提供Jacket时,参数中用到了Cloth,必须在Module中@Provides为Jacket提供Cloth
  2. 自定义的Qualifier和Named也可以在参数中使用
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
public class JacketModule {
@Provides
public Jacket getJacket(@Named("Red") Cloth cloth){
return new Jacket(cloth);
}
@Singleton
@Named("Red")
@Provides
public Cloth getRedCloth(){
Cloth mCloth=new Cloth();
mCloth.setColor("红");
return mCloth;
}
@Blue
@Provides
public Cloth getBluecloth(){
Cloth mCloth=new Cloth();
mCloth.setColor("蓝");
return mCloth;
}
}
Component

在用到的Cloth和Component上同时添加@Singleton,此时Cloth为单例

1
2
3
4
5
@Singleton
@Component(modules = JacketModule.class)
public interface JacketComponent {
void inject(MainActivity mainActivity);
}
Activity

此时的Cloth和JacketRed.getCloth()为同一个

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
public class MainActivity extends AppCompatActivity {
TextView mTextView;
@Named("Red")
@Inject
Cloth mClothRed;
@Inject
Jacket mJacketRed;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mTextView= (TextView) findViewById(R.id.tv1);
JacketComponent mJacketComponent = DaggerJacketComponent.builder().jacketModule(new JacketModule()).build();
mJacketComponent.inject(this);
mTextView.setText((mJacketRed.getCloth() == mClothRed) + "");
}
}
Scope

自定义的Scope与官方的Singleton原理一样,替换Singleton为JacketSingleton仍返回true

自定义的JacketSingleton:在JacketSingleton作用域内单例

1
2
3
4
@Scope
@Retention(RetentionPolicy.RUNTIME)
public @interface JacketSingleton {
}

官方的Singleton

1
2
3
4
@Scope
@Documented大专栏  dagger2的Qualifier与Scopepan>
@Retention(RUNTIME)
public @interface Singleton {}

dependencies

实例:分别创建两个Activity,跳转后的实例为同一个(工具类多此用法在app层单例)

分别创建两个Module

JacketModule与JacketModule2

创建Component
方法一:dependencies
1
2
3
4
5
@JacketSingleton
@Component(modules = JacketModule.class,dependencies = BaseComponent.class)
public interface JacketComponent {
void inject(MainActivity mainActivity);
}
方法二:Subcomponent
1
2
3
4
5
@JacketSingleton
@Subcomponent(modules = JacketModule2.class)
public interface JacketComponent2 {
void inject(MainActivity2 mainActivity);
}
创建BaseModule
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public class BaseModule {
@Singleton
@Provides
public Jacket getJacket(@Named("Red") Cloth cloth){
return new Jacket(cloth);
}
@Singleton
@Provides
@Named("Red")
public Cloth getRedCloth(){
Cloth mCloth=new Cloth();
mCloth.setColor("红");
return mCloth;
}
}
创建BaseComponent
1
2
3
4
5
6
@Singleton
@Component(modules = BaseModule.class)
public interface BaseComponent {
Jacket getJacket();//dependencies依赖声明的方式
JacketComponent2 getJacketComponent2(JacketModule2 jacketModule2);//@Subcomponent使用的声明方式,声明一个返回值为子组件的方法,子组件需要什么Module,就在方法参数中添加什么
}
在app中初始化BaseComponent
1
2
3
4
5
6
7
8
9
10
11
12
public class App extends Application {
private BaseComponent baseComponent;
@Override
public void onCreate() {
super.onCreate();
baseComponent = DaggerBaseComponent.builder().baseModule(new BaseModule()).build();
}
public BaseComponent getBaseComponent() {
return baseComponent;
}
}
在两个Activity中使用
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
public class MainActivity extends AppCompatActivity {
TextView mTextView;
@Named("Red")
@Inject
Cloth mClothRed;
@Inject
Jacket mJacketRed;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mTextView= (TextView) findViewById(R.id.tv1);
JacketComponent mJacketComponent = DaggerJacketComponent.builder().baseComponent(((App) getApplication()).getBaseComponent()).jacketModule(new JacketModule()).build();
mJacketComponent.inject(this);
mTextView.setText(mJacketRed.hashCode()+"");
}
public void go(View view) {
Intent intent = new Intent(this,MainActivity2.class);
intent.putExtra("xx",mJacketRed.hashCode()+"");
startActivity(intent);
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
public class MainActivity2 extends AppCompatActivity {
TextView mTextView;
@Named("Red")
@Inject
Cloth mClothRed;
@Inject
Jacket mJacketRed;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main2);
mTextView= (TextView) findViewById(R.id.tv2);
App application = (App) getApplication();
application.getBaseComponent().getJacketComponent2(new JacketModule2()).inject(this);
String mString = (String) getIntent().getExtras().get("xx");
mTextView.setText(mString+"n"+mJacketRed.hashCode()+"");
}
}
结论

分别在两个Activity中初始化的Jacket哈希值相同,为同一个变量,app层单例。

Lazy与Provider

Lazy用于延迟加载,所谓的懒加载就是当你需要用到该依赖对象时,Dagger2才帮你去获取一个;Provide用于强制重新加载,也就是每一要用到依赖对象时,Dagger2都会帮你依赖注入一次

1
2
3
4
@Inject //Lazy声明方式
Lazy<Cloth> redCloth;
@Inject //Provider声明方式
Provider<Shoe> shoe;

以上是关于dagger2的Qualifier与Scope的主要内容,如果未能解决你的问题,请参考以下文章

Dagger2 中的 Scope

Dagger2 scope

Dagger2入门详解

Android实战——Dagger2一场老板与员工的故事会

dagger2 重点笔记

Dagger2 探索记3——两大进阶组件