加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

“一盘沙拉”带你入门Dagger2(六)之Component依赖

发布时间:2020-12-14 02:10:00 所属栏目:百科 来源:网络整理
导读:如果我们有一套做好的煎饼果子(一套齐全的依赖体系,Module、Component),另外一个类需要这套依赖体系的一个对象作为依赖,怎么办,还需要再为这个对象,建立一套新的Module和Component吗 显然是不用的,Component之间是可以依赖的 开始举例子: 1. 我们先

如果我们有一套做好的煎饼果子(一套齐全的依赖体系,Module、Component),另外一个类需要这套依赖体系的一个对象作为依赖,怎么办,还需要再为这个对象,建立一套新的Module和Component吗

显然是不用的,Component之间是可以依赖的

开始举例子:

1. 我们先做一套的依赖体系,这个体系里,依赖的Tomato西红柿

Tomato.class

public class Tomato {
    public Tomato() {
        Log.e("TAG","我是一个西红柿");
    }
}

TomatoModule.class

@Module
public class TomatoModule {
    @Provides
    public Tomato provideTomato(){
        return new Tomato();
    }

}

TomatoComponent.class

@Component(modules = {TomatoModule.class})
public interface TomatoComponent {
    // ★前面说过这里的这个方法是可以不写的,
    // 但是,如果你想让别的Component依赖这个Component,
    // 就必须写,不写这个方法,就意味着没有向外界,暴露这个依赖
    Tomato provideTomato();
// void inject(Object o);//这里的西红柿并没有想注入到那个类中,可以不写inject方法
}

2. ok,煎饼果子已经做好了,我们想在Salad里直接注入tomato对象,怎么做呢

  • 只需要在SaladComponent里引入TomatoComponent即可

    dependencies = {TomatoComponent.class}

    ```
    @Component(modules = {SaladModule.class},dependencies = {TomatoComponent.class})//引入TomatoComponent
    
    public interface SaladComponent {
        .....
        //这里代码不用动
    }
    ```
    • 在Salad里面注入tomato,别忘了“tomatoComponent(tomatoComponent)”
    public class Salad {
    
        @Inject
        Tomato tomato;
    
           ......
    
        public Salad() {
           // 这里必须先得到TomatoComponent
            TomatoComponent tomatoComponent = DaggerTomatoComponent.builder().tomatoModule(new TomatoModule()).build();
            // 在这里通过传入“tomatoComponent(tomatoComponent)”构建SaladComponent,
            SaladComponent saladComponent = DaggerSaladComponent.builder().saladModule(new SaladModule()).tomatoComponent(tomatoComponent).build();
            saladComponent.inject(this);
    
            ......
    
    
        }
            ......
    }

3. 测试,tomato注入成功了

E/TAG: 我是一个西红柿

以下内容摘自Android常用开源工具(2)-Dagger2进阶

除了dependencies还可以使用SubComponent,相当于子父类继承关系

如果一个Component的功能不能满足你的需求,你需要对它进行拓展,一种办法是使用Component(dependencies=××.classs)。另外一种是使用@Subcomponent,Subcomponent用于拓展原有component。同时,这将产生一种副作用——子component同时具备两种不同生命周期的scope。子Component具备了父Component拥有的Scope,也具备了自己的Scope。

Subcomponent其功能效果优点类似component的dependencies。但是使用@Subcomponent不需要在父component中显式添加子component需要用到的对象,只需要添加返回子Component的方法即可,子Component能自动在父Component中查找缺失的依赖。

//父Component:
@PerApp
@Component(modules=××××)
public AppComponent{
    SubComponent subcomponent();  //1.只需要在父Component添加返回子Component的方法即可
}

//子Component:
@PerAcitivity   //2.注意子Component的Scope范围小于父Component
@Subcomponent(modules=××××)   //3.使用@Subcomponent
public SubComponent{
    void inject(SomeActivity activity); 
}

//使用
public class SomeActivity extends Activity{
    public void onCreate(Bundle savedInstanceState){
        ...
        App.getComponent().subCpmponent().inject(this);//4.调用subComponent方法创建出子Component
    }    
}

通过Subcomponent,子Component就好像同时拥有两种Scope,当注入的元素来自父Component的Module,则这些元素会缓存在父Component,当注入的元素来自子Component的Module,则这些元素会缓存在子Component中。

还有一个Lazy,懒加载,用于延迟加载

Lazy和Provider都是用于包装Container中需要被注入的类型,Lazy用于延迟加载,Provide用于强制重新加载,具体如下:

public class Container{
    @Inject Lazy<Fruit> lazyFruit; //注入Lazy元素
    @Inject Provider<Fruit> providerFruit; //注入Provider元素
    public void init(){
        DaggerComponent.create().inject(this);
        Fruit f1=lazyFruit.get();  //在这时才创建f1,以后每次调用get会得到同一个f1对象
        Fruit f2=providerFruit.get(); //在这时创建f2,以后每次调用get会再强制调用Module的Provides方法一次,根据Provides方法具体实现的不同,可能返回跟f2是同一个对象,也可能不是。
    }
}

值得注意的是,Provider保证每次重新加载,但是并不意味着每次返回的对象都是不同的。只有Module的Provide方法每次都创建新实例时,Provider每次get()的对象才不相同。

基础知识告一段落了

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读