一、简介:
- Android项目,目前一般都采用MVP模式,利用Dagger注入实例化类,利用LifeCycle进行生命周期管理,利用RxJava+Retrofit进行网络访问,用ARouter进行组件间通信。其中Dagger是其中比较难的一个知识点。
- Dagger是安卓里面最棒的依赖注入框架,第一代由Square公司共享出来的,第二代则是由Google接手后推出的。刚开始自己学,只是看了一眼,云里雾里并没有应用到项目中,最近做电商项目,为了后续添加功能和维护,然后不得不用Dagger.
- Dagger的优点:
- 依赖的注入和配置独立于组件之外
- 方便修改,构建对象,比如好多的构建需要Context,只需要有一个可以提供Context的Module就可以,或者对象构建需要的参数增加或减少时,只需要改一两个地方
- 依赖可以注入到一个组件中,使得测试更加简单
二、使用 (用实例进行分析使用)
- Dragger github地址: https://github.com/google/dagger,项目配置compile都有,此处不贴了
- 场景:注册User
需要有个UserService,然后有个实现类UserServiceImpl,这是业务逻辑层吧,然后还需要个BasePresenter和RegisterPresenter,先从p层,然后再从业务逻辑分析
- BasePresenter没什么,主要是RegisterPresenter
图中userService和context两处inject下面再解释,这里先不用纠结
在RegisterPresenter类的构造函数前加上@Inject,java一样,然后在调用的时候直接注入就OK了,我是在MVPActivity基类中定义的,
然后每个类实现这个Activity,就可以直接使用了,当然,你也可以在自己的Activity中写上
@Inject
lateinit var mPresenter:RegisterPresenter
然后在需要presenter处理业务时调用即可
从上面也可以看出UserService也可同样声明注入使用
@Inject
lateinit var userService:UserService RegisterPresenter是我们自己写的类,其中涉及的没有第三方库中的类,所以可以直接在构造函数前面标记,那么第三方库的类该如何标记,因为构造函数前标记是不可能的,因此就需要用到Module,还有一种情况就是写一个Service基类接口,你也不可能用@Inject放在构造函数上吧,因为它没有构造函数(如果你要深入底层运行机制,那它是有构造函数的,我们这里是代码应用层)。我们这里的UserService是接口
- 事先了解:
@Module和@Component配合使用
@Module通常标注一个类,该类中可以实例化各种类,Component在注入对象的时候先去Module中找,如果找不到就会检查所有被@Inject标注的构造函数
@Provides标签是放在@Module注释下的类的方法上,告诉Dragger2这个方法可以实例话对象
需要用@Module标记,这是Module,在方法内需要以providers为前缀
Module定义好了就该定义Component,同理需要@Component注释接口,这里PerCommponentScope和dependencies在下面介绍context单例时会将。Component是桥梁,需要提供一个inject()方法注入,modules中需要写上UseModule,毕竟要牵线搭桥嘛- 既然Module,Component都写完了,Rebuild一下是否可以使用了呢,不,还有个UserService的实现类没写完
-
实现类也需要加入@Inject声明,想要用注入,都要声明标记一下, - 这样service和presenter层都写完了,现在只剩下上述代码中context和dependcies和Scope了,
- dependence,顾名思义,依赖,当component依赖module重复时可以使用dependence。
- 这里另写一个Component专门提供context和Activity。
大家会发现这里又有依赖,真的是无穷尽也!但是context不应该全局只用一个么,所以就有了AppComponent,这个在Application时初始化。而且提供Activity和全局Context个人觉得就应该分开来 下面贴上AppComponent和Application的初始化
接下来还有Scope,字面意思是域,一个Module对应一个域,也可以理解为单例,例如上面@Singleton,这是系统自带的,其他的@ActivitScope都是自定义的,代码如下:
后面两个是自定义的Scope,第一个Dragger自带的,其实按道理不能理解为单例,但是这样理解也可以。- 最后是RegisterActivity中初始化一下:
override fun injectComponent() {
DaggerUserComponent.builder().activityComponent(activityComponent).userModule(UserModule()).build().inject(this)
mPresenter.mView = this
}
调用时直接使用mPresenter.register()方法就OK了, - 大功告成,Rebuild一下就可以了,然后运行
- 事先了解:
- BasePresenter没什么,主要是RegisterPresenter
三、总结:
- @Inject用在类的构造函数上,进行标注,需要用的时候用@Inject进行声明,通过Component进行注入,注入函数一般为inject()
- 当希望注入第三方库提供的类,或者是项目用某种模式写的,其中例如上述的UserServiceImpl,它是继承UserService 接口的,为了方便扩展,最好还是利用Module,然后在Component中指定Module
- 这是采用MVP模式写的注册功能的一个小例子
四、CSDN的编辑器XEditor使用还凑合,但是MarkDown效果极差,在本地MarkDown写好,复制过来格式就变样了,很郁闷