美文网首页
Dragger 笔记

Dragger 笔记

作者: 细雨么么 | 来源:发表于2021-08-11 16:54 被阅读0次

1.无参数 对象

class User2 @Inject constructor() {

    var age:Int?=null


    override fun toString(): String {
        return "User2(age=$age)"
    }


}

2.搞一个 注入生成类

@Component
public interface MainComponent2 {

    fun  a(activity: MainActivity)

}

3.在使用Activity 中调用

 @Inject
    lateinit var user2: User2
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        DaggerMainComponent.builder().build().inject(this)
}

自己的推断。当年你在Activity中标记了Inject 对象时,调用了 dragger inject。那么生成的DragComponent 就会把你标注的对象导入进去。

image.png

这时候会检查你的标注了Inject 的对象 与你调用的 drag inject 参数是否匹配。如果不匹配,直接编译不通过。
可以在同一个activity 中执行不同component中相同构造函数的对象的inject注入。不能执行不同component 不同构造函数对象的inject注入。

举个例子

class User2 @Inject constructor() {

    var age:Int?=null


    override fun toString(): String {
        return "User2(age=$age)"
    }


}



class User @Inject constructor(var age:Int) {

    var name:String?=null
    override fun toString(): String {
        return "name=$name age=$age"
    }

}

@Singleton
@Component(modules = [MainModule::class])
public interface MainComponent {
    fun inject(activity: MainActivity)
}


@Singleton
@Component(modules = [MainModule::class])
public interface MainComponent2 {

    fun  a(activity: MainActivity)

}


  @Inject
    lateinit var user: User
    @Inject
    lateinit var dog: Dog
    @Inject
    lateinit var hahahaha: Hahahaha;
    @Inject
    lateinit var user2: User2
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        DaggerMainComponent.builder().build().inject(this)
        DaggerMainComponent2.builder().build().a(this)
        hello_world_tv.setOnClickListener {
            user.name="hhh"

            dog.user.name="张三"
            dog.name="汪汪汪"
            Log.d("test","${user==dog.user}")
            hello_world_tv.text=dog.toString()
        }
    }

是可以正常运行的。但是如果把MainComponent2 改下。


@Component
public interface MainComponent2 {

    fun  a(activity: MainActivity)

}

就运行不了。 当然,如果你去改user2,然后必然也要改MainComponent2 中的provide。也是执行不了的。执行不了的原因就是,在component2中回去尝试构建user,但是发现没有user的provide构造函数。所以执行失败了。每个component 都会去吧所以标注了inject的对象尝试去构建出来。

标注了inject 的Bean 对象,在使用时,调用了 component 的inject 时会把对象的包导入进去,如果 构造参数不符合规则,就会编译不过。所以两个相同的,编译可以执行。如果两个不一样的,会尝试吧所以的都导入到一个component中。自然编译不过

inject 跟通过构造方法生成桥梁的区别是:

例:
@Module
class AppModule(private val context: Context) {


    @Provides
    fun provideSp(): SharedPreferences {
        return context.getSharedPreferences("sp", Context.MODE_PRIVATE)
    }

//绑定桥梁
  fun testInject(){
        DaggerAppComponent.builder()
            .appModule(AppModule(this))
            .build().inject(this)


    }
}

构造方法的方式会通过 在build的时候、
``
public Builder appModule(AppModule appModule) {
this.appModule = Preconditions.checkNotNull(appModule);
return this;
}

public AppComponent build() {
  Preconditions.checkBuilderRequirement(appModule, AppModule.class);
  return new DaggerAppComponent(appModule);
}

``
把生成的对象传入。
inject 会检查绑定对象是否存在inject对象。对比:


image.png
image.png

自定义作用域

java:

@Scope  //声明这是一个自定义@Scope注解
@Retention(RUNTIME)
public @interface ActivityScope {
}

KT:

@Documented
@Scope
@Retention(AnnotationRetention.RUNTIME)
annotation class Activit

2022年3月26日16:53:58

关于作用域的理解,作用域并不能解决什么问题。对象的绑定主要来源于 component,同一个component中,标记了相同scope 作用域的对象,只会产生同一个,inject方法其实只是对象的引用赋值

 @Override
  public void inject(BActivity activity) {
    injectBActivity(activity);
  }

  private AActivity injectAActivity(AActivity instance) {
    AActivity_MembersInjector.injectPlane1(instance, providerAnPlaneProvider.get());
    AActivity_MembersInjector.injectPlane2(instance, providerAnPlaneProvider.get());
    return instance;
  }
@InjectedFieldSignature("com.example.learndragger.testscope.AActivity.plane1")
  public static void injectPlane1(AActivity instance, AirPlane22 plane1) {
    instance.plane1 = plane1;
  }

观看生成代码,只是把页面的标记了@inject对象的引用 指向了component生成的对象。所以如果不同的页面,使用了同一个component,那么他们引用的就可以是同一个对象。(但是只标记了scope 的对象)。没有任何scope标记的对象,每次都会生成新的对象,标记了scope的对象,会做一个 双重检查,每次返回同一个对象。
component通过build 生成对应的component对象,它可以不用赋值到具体的对象(activity/fragment),可以引用到别的component中,规则是
1。不同的component不能使用相同的作用域scoope 标记
2。没有使用scope的component不能依赖使用了scope的component

相关文章

网友评论

      本文标题:Dragger 笔记

      本文链接:https://www.haomeiwen.com/subject/cnycbltx.html