Dagger2 作用:举例解释
例1:相当于SpringBoot的@AutoWrite 自动注入,可以注入接口、类、第三方控件等
例2:相当于 自动实例化对象、接口 A a = new A()
例3:MVP模式中的P层的引用就可以通过Dagger2来注入,当然你还可以通过反射来实现
前期准备:
dagger官网 可以查看最新版 或者 是java版还是需要引入kotin版
kotlin版
//在app Build中加入kapt插件:
apply plugin: 'kotlin-kapt'
dependencies {
//Dagger2 kotlin
implementation "com.google.dagger:dagger:2.14.1"
kapt "com.google.dagger:dagger-compiler:2.14.1"
}
分解讲解:
一、简单实现自动注入类
先介绍两个注解:
@Inject
- @Inject是Dagger2内置的一个注解
- @Inject用来标注目标对象如上面的 userBean 例如:3、在Activity/Fragment中,实现注入中的属性声明
- @Inject用来标注依赖类的构造方法如上面的UserBean --例如: 1、创建基类
@Component
相当于一个桥梁的作用---例如:2、创建桥梁接口
1、创建基类:
//创建用户基类,创建一个属性,并且命名为张三,
//使用@Inject作用:UserBean 可以通过Dagger2注入到目标类
class UserBean @Inject constructor(){
var name: String = "张三"
}
2、创建桥梁接口
//使用@Component创建桥梁,把依赖类连接到目标类
@Component
interface UserComponent {
fun jnject(activity: MainActivity)//这个方法名jnject随便用什么都行,无所谓,跟自定义注解一样
}
3、在Activity/Fragment中实现注入
class MainActivity : AppCompatActivity() {
@Inject
lateinit var userBean: UserBean
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
//绑定-这里必须先Rebuild Project -因为Dagger2使用的是编译时注解,先编译一遍
DaggerUserComponent.builder().build().jnject(this)
Log.e("111",userBean.name)
//最后可以得到userBean中的name值-张三
}
}
二、简单实现注入接口、第三方库\View
如果需要注入的目标是一个接口,那么就不存在构造器,那么再像之前的方式就行不通了需要借助另外两个注解
@Module
- 注入的是一个接口,那么就没有构造器,那么久需要借助第三方类来通知Dagger2需要注入的类是哪个了
@Provides
-
该方法这就是具体的创建实例的方法。所以@Module和@Provides是配套出现的在一个类中
1、创建需要注入的原始接口
interface OrderInterface {
fun getData():String
}
2、创建原始接口的实现类,方便我们测试得到结果,看看是否成功
class OrderInterfaceImp:OrderInterface {
override fun getData(): String {
return "保存信息测试"
}
}
3、创建@Module跟@Provides 让Dagger2 知道需要注入的是哪个接口(OrderInterface )
@Module
class OrderModule {
@Provides
fun providesOrder(): OrderInterface {
return OrderInterfaceImp()
}
}
4、创建桥梁,让Activity\Fragment通过桥梁去找到原始注入接口
@Component(modules = [(OrderModule::class)]) //这个注解的值是一个数组,可以看源码
interface OrderComponent {
fun inject(activity: MainActivity2)
}
5、Activity的引入
class MainActivity2 : AppCompatActivity() {
@Inject
lateinit var orderInterface: OrderInterface
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
DaggerOrderComponent.builder().build().inject(this)
Log.e("111", orderInterface.getData())
}
}
总结,就是第一种跟第二种的区别:第一种是给类使用的,第二种是给接口使用的,因为接口没有构造器,所以需要借助第三个类去建立桥梁
三、递归注入
都是使用Dagger2来注入那么工厂方法返回时是不是也可以通过注入来实例化MainServiceImpl而不是直接实例
1、Module类中不能直接实例化,需要使用Dagger2递归注入
修改为:
@Module
class OrderModule {
@Provides
fun OrderModule(orderInterfaceImp: OrderInterfaceImp): OrderInterface {
return orderInterfaceImp //使用Dagger2递归注入
}
}
2、实现类中需要通过@Injeck构造器通知Dagger2需要注入的类
class OrderInterfaceImp @Inject constructor():OrderInterface {
override fun getData(): String {
return "保存信息测试"
}
}
四、Dagger2注入接口完整版
1、创建接口
interface OrderInterface {
fun getData():String
}
2、创建接口实现类、使用@Injeck构造器通知Dagger2需要注入的接口实现类
class OrderInterfaceImp @Inject constructor():OrderInterface {
override fun getData(): String {
return "保存信息测试"
}
}
3、实现Module,借助@Provides连接Dagger2需要注入的原始接口
@Module
class OrderModule {
@Provides
fun OrderModule(orderInterfaceImp: OrderInterfaceImp): OrderInterface {
return orderInterfaceImp
}
}
4、实现Component桥梁,连接activity跟原始接口
@Component(modules = [(OrderModule::class)]) //这个注解的值是一个数组,可以看源码
interface OrderComponent {
fun inject(activity: MainActivity2)
}
5、在Activity中实现绑定并注入,不需要先Rebuild Project,因为Dagger2是运行时注解
class MainActivity : AppCompatActivity() {
@Inject
lateinit var userBean: UserBean
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
//绑定
DaggerUserInterface.builder().build().jnject(this)
Log.e("111",userBean.name)//输入出接口的值,证明接口已经被实例化
}
}
注意:如果想要了解运行时注解,可以去学些下Android APT语法
Dagger2的高级应用 (二)******************** 借鉴别人写的,太多了,做个笔记