Dagger2高级使用(自定义Scope、SubComponent、Lazy与Provider)

16 篇文章 0 订阅

###自定义Scope
我们知道component的dependencies与component自身的scope不能相同,即组件之间的scope不同
意思就是当我们写了一个componentA,同时通过dependencies引用了另一个componentB
如下面代码所示

@Component(modules = AModule.class,dependencies = ComponentB.class)
public interface ComponentA {
    ...
}

在我们componentB中,使用了**@Singleton** (单例)Scope,

/**
 * description:
 * author: dujun
 * created at: 2018/1/23 16:37
 * update: 2018/1/23
 * version: 1.0
 */
@Singleton
@Component(modules = {BModule.class})
public interface BComponent {
    ...
}

所以,因为componentA通过dependencies引用了componentB,所以中componentA也要使用一个同样的Scope,回到开始的那句话:
component的dependencies与component自身的scope不能相同,即组件之间的scope不同
此时,我们就需要自定义一个Scope
首先,创建一个接口在interface前加@

public @interface CustomScope {
}

我们照猫画虎,打开Singleton的源码:

/**
 * Identifies a type that the injector only instantiates once. Not inherited.
 *
 * @see javax.inject.Scope @Scope
 */
@Scope
@Documented
@Retention(RUNTIME)
public @interface Singleton {}

则,我们的自定义CustomScope完整代码为:

/**
 * description:
 * author: dujun
 * created at: 2018/1/23 17:48
 * update: 2018/1/23
 * version: 1.0
 */
@Scope
@Documented
@Retention(RUNTIME)
public @interface CustomScope{
}

我们看看上面@Scope、@Documented、@Retention(RUNTIME)分别代表什么
**@Scope :**注明是Scope
**@Documented :**标记在文档
**@Retention(RUNTIME) :**运行时级别

此时,componentA的代码为:

@CustomScope 
@Component(modules = AModule.class,dependencies = ComponentB.class)
public interface ComponentA {
    ...
}

###SubComponent的使用
通常,component之间的相互引用,用dependencies,我们还可以通过SubComponent来完成
下面定义了父component和module

/**
 * description:父Component
 * author: dujun
 * created at: 2018/1/24 15:47
 * update: 2018/1/24
 * version: 1.0
 */
@Singleton
@Component(modules = FMudule.class)
public interface FComponent {
}
/**
 * description:父Mudule
 * author: dujun
 * created at: 2018/1/24 15:55
 * update: 2018/1/24
 * version: 1.0
 */
@Module
public class FMudule {
    @Singleton
    @Provides
    public Gson provideGson(){
        return new Gson();
    }
}

首先,我们看到上面FMudule使用了 @Singleton,所以,这里需要说一个注意问题:
SubComponent的Scope范围小于父Component
所以,子类中如果要使用Scope,则需要自定义。假设Subcomponent 中,也需要使用 @Singleton。由于父Component使用了**@Singleton**,所以这里需要自定义,所以使用了我们自定义的**@CustomScope**

子Component类代码如下:

/**
 * description:子Component
 * author: dujun
 * created at: 2018/1/24 15:49
 * update: 2018/1/24
 * version: 1.0
 */
@CustomScope
@Subcomponent(modules = ZModule.class)
public interface ZComponent {
    ...
}
/**
 * description:子Module
 * author: dujun
 * created at: 2018/1/24 15:54
 * update: 2018/1/24
 * version: 1.0
 */
@Module
public class ZModule {
    
    @CustomScope
    @Provides
   public User provideUser(){
       return new User();
   }
}

那么FComponent与ZComponent怎么关联呢 ?,我们只需要在FComponent接口中添加如下抽象方法:

/**
 * description:父Component
 * author: dujun
 * created at: 2018/1/24 15:47
 * update: 2018/1/24
 * version: 1.0
 */
@Singleton
@Component(modules = FMudule.class)
public interface FComponent {
    // 关联@Subcomponent
   ZComponent getChildComponent();
}

最后,还有一点注意的是:
**Subcomponent同时具备两种不同生命周期的scope, SubComponent具备了父Component拥有的Scope,也具备了自己的Scope。 **

Lazy和Provider的使用

假设我们需要注入User对象,我们会根据使用情况不同,又是会用到Lazy元素Provider元素
下面是一个实例:

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

    }
}

通过上面的实例,我们可以知道俩个元素分别代表的含义:

**Lazy : **调用其get()方法的时候才会创建注入对象的实例,也就是我们通常所说的懒加载。

**Provider: **同样,也是调用其get方法的时候才会创建注入对象的实例,但是,内地调用get方法,都用会先调用其Module的Provides方法一次,所以获取到的实例对象跟Provides方法内部具体实现有关。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值