看了许多Dagger2的文章,主要包括:
但感觉有的文章光有原理没有例子,有的光讲例子,原理又讲的比较少。因此我也来写一篇Dagger2的文章,尽量结合2者,供大家交流学习。
@Inject、@Qualifier
如果我们项目中自己定义的类,比如User类,需要注入到MainActivity中,用来代替new User(),那么在User类中使用@Inject注解User的构造函数表示提供注入,@Inject注解MainActivity中User类的实例属性来表示注入处。
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 
 | public class MainActivity extends AppCompatActivity {
 @Inject
 User user;
 }
 
 
 
 public class User {
 String name;
 String pwd;
 
 @Inject
 public User() {
 
 }
 }
 
 | 
如果User类有多个构造函数,则需要@Qualifier定义的注解来区分,比如官方的@Named注解
@Qualifier主要是为解决实例提供方有提供多个相同类型的实例时,加以区分,在这里多种构造函数算其中一种情况
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 
 | @Qualifier
 @Documented
 @Retention(RUNTIME)
 public @interface Named {
 
 
 
 
 String value() default "";
 }
 
 
 public class User {
 String name;
 String pwd;
 
 @Inject
 @Named("user")
 public User() {
 
 }
 
 @Named("user_with_value")
 public User(String name, String pwd) {
 this.name = name;
 this.pwd = pwd;
 }
 }
 
 
 public class MainActivity extends AppCompatActivity {
 @Inject
 @Named("user")
 User user;
 
 @Inject
 @Named("user_with_value")
 User userWithValue;
 }
 
 | 
@Module、@Component和@Provides
Module的引入是为了解决第三库提供的实例注入问题,比如User类是某个第三方库的文件,那么我们没办法在其构造函数上增加@Inject注解。这时候可以通过@Module注解的类中以@Provides注解相应返回类型为User的方法来提供实例
如果你原先的代码现在需要引入Dagger2,也可以通过@Module方式来提供注入,这样基本不用修改原有代码,另外可以把某个页面需要注入的实例全部在Module类中提供,也方便维护。而这里的某个页面具体要怎么划分,是单个activity或者单个功能,就看情况而定了,目前大多数推荐是以页面来划分Module
我们选择以页面切分Module,以下Module中提供的依赖供MainActivity页面使用
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 
 | @Module
 public class MainActivityModule {
 
 
 @Provides
 @Named("user")
 public User providerUser() {
 return new User();
 }
 
 
 
 @Provides
 @Named("user_with_value")
 public User providerValueableUser(String name, String pwd) {
 return new User(name, pwd);
 }
 }
 
 | 
如果通过@Inject和@Module都有提供User类的注入依赖,按照Dagger2的处理,优先使用@Module类中提供的注入。
如果User类仅在MainActivityModule类中有定义提供注入的方法,那么在MainActivity.java类中@Inject的属性如何初始化呢?这时候Dagger2提供@Component类来关联:
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 
 | 
 @Component(module = MainActivityModule.class)
 public interface MainActivityComponent {
 
 
 
 
 void inject(MainActivity mainActivity);
 }
 
 | 
这时,需要把MainComponent与MainActivity关联,这部分代码用到了Dagger2自动生成的代码。所以需要先编译工程,然后在MainActivity.java中加上以下代码:
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 
 | public class MainActivity extends AppCompatActivity {
 @Inject
 @Named("user")
 User user;
 
 MainActivityComponent mainComponent;
 
 @Override
 protected void onCreate(@Nullable Bundle savedInstanceState) {
 super.onCreate(savedInstanceState);
 
 
 mainComponent = DaggerMainActivityComponent.builder()
 .build();
 
 mainComponent.inject(this);
 }
 }
 
 | 
以上讲解了:
- @Inject注解在- 需要注入和- 提供注入处;
 
- @Inject注解在- 需要注入处;
 - @Module通过@Provides- 提供注入;
 - @Component在- 需要注入页面处初始化,来连接@Inject和@Module
 
二种情况,也是Dagger2最基本的情况。
下一篇会再讲Dagger2复杂一点的用法。包括
| 12
 
 | @Component(dependencies = MainApplicationComponent.class,modules ={MainActivityModule.class,ModuleB.class,ModuleA.class,MyModule.class})
 
 | 
- 子Component@SubComponent
- 作用域@Scope
| 12
 3
 4
 
 | @Scope@Documented
 @Retention(RUNTIME)
 public @interface Singleton {}
 
 | 
- Map值- @IntoMap
 
- Set值- @ElementsIntoSet
 
- … 
也不知道啥时候会有下一篇!期待吧!
以上内容均为个人学习理解,如果有错误之处,可以评论告诉我。共同学习,共同进步。