Dagger2进阶-单例

Dagger2中可以很方便的实现单例,但注意这个单例是一个Component作用域范围内的单例,而这个范围,需要上层定义@Scope注解。默认可以使用@Singleton注解,也可以使用自定义其他名称的注解,自定义时参照@Singleton即可,例如@Abc都没有问题,该注解没有特殊作用,只是起标记作用,因此命名与范围相符合更好。
例如可以取如下范围单例:
1.@ApplicationSingleton:进程级别单例
2.@ActivitySingleton:页面级别的单例

单例实现步骤

Dagger2实现单例分2步:

  1. 给对应的Component添加范围注解
    例如CoffeeShopComponent使用自定的范围注解@ActivitySingleton,代码如下:
@Subcomponent(modules = {SubModule.class})
@ActivitySingleton
public interface CoffeeShopComponent {

    @Subcomponent.Builder
    interface Builder {
        CoffeeShopComponent build();
    }

    void inject(Street street);

}
  1. 给该Component依赖的Module中提供的对象方法加上该范围注解。
    例如期望Logger是单例的,则在Logger的providers方法上,增加和Component或父Component一样的范围注解,表示在Component或父Component实例内是单例的。
@Module
public class SubModule {
    @ActivitySingleton
    @Provides
    public Logger providerLogger(Retrofit retrofit) {
        return new Logger(retrofit);
    }
}

自动注入的对象,直接在类上设置@Scope类型注解,即可设置单例范围,例如:

@ActivitySingleton
public class TestData {
    @Inject
    public TestData() {
        System.out.println("abc");
    }
}

注意

如果注入的对象的Scope范围与Component以及父Component的范围都不符合,则会报错:(unscoped) may not reference scoped bindings

如何实现Activity内单例

Activity内单例也就是同一个Activity内部的注入对象,是同一个。因此需要以下2步:

  1. 将Activity内部的Component保持只有1个实例,且与其他Activity中的Component为不同的实例
  2. 将注入对象设置的@Scope类型注解与Component一致

你可能感兴趣的:(Dagger2进阶-单例)