看了许多Dagger2的文章,主要包括:
但感觉有的文章光有原理没有例子,有的光讲例子,原理又讲的比较少。因此我也来写一篇Dagger2的文章,尽量结合2者,供大家交流学习。
@Inject、@Qualifier
如果我们项目中自己定义的类,比如User类,需要注入到MainActivity中,用来代替new User()
,那么在User类中使用@Inject注解User的构造函数表示提供注入,@Inject注解MainActivity中User类的实例属性来表示注入处。
1 2 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主要是为解决实例提供方有提供多个相同类型的实例时,加以区分,在这里多种构造函数算其中一种情况
1 2 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页面使用
1 2 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类来关联:
1 2 3 4 5 6 7 8 9 10
|
@Component(module = MainActivityModule.class) public interface MainActivityComponent { void inject(MainActivity mainActivity); }
|
这时,需要把MainComponent与MainActivity关联,这部分代码用到了Dagger2自动生成的代码。所以需要先编译工程,然后在MainActivity.java中加上以下代码:
1 2 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复杂一点的用法。包括
1 2
| @Component(dependencies = MainApplicationComponent.class, modules ={MainActivityModule.class,ModuleB.class,ModuleA.class,MyModule.class})
|
- 子Component
@SubComponent
- 作用域
@Scope
1 2 3 4
| @Scope @Documented @Retention(RUNTIME) public @interface Singleton {}
|
Map值@IntoMap
Set值@ElementsIntoSet
…
也不知道啥时候会有下一篇!期待吧!
以上内容均为个人学习理解,如果有错误之处,可以评论告诉我。共同学习,共同进步。