创建Singleton w / Dagger 2的最简单方法是什么?

时间:2016-08-23 01:59:28

标签: android singleton dagger-2

我是否需要设置模块,提供程序和接口(组件)? 为了能够注入一个单独的东西,似乎需要相当多的开销。

有人可以使用Dagger 2提供简单的单例示例吗? (还显示了如何设置单例的属性,如上下文,因此每次使用单例时都不需要传递它)

2 个答案:

答案 0 :(得分:13)

您只需要使用@Inject构造函数进行注释的模块(因为例如,框架会为您创建 - 就像上下文一样)。如果您无法添加@Inject构造函数,则还需要在组件中指定void inject(...)方法。

但是,如果您可以使用@Inject构造函数创建它,那么@Inject也可用作字段注释

@Component(modules={ContextModule.class})
@Singleton
public interface SingletonComponent {
    void inject(MainActivity mainActivity);
}

@Module
public class ContextModule {
    Context context;

    public ContextModule(Context context) {
        this.context = context;
    }

    @Provides
    Context context() {
        return context;
    }
}

@Singleton
public class MyOtherSingleton {
    @Inject
    public MyOtherSingleton() {
    }
}


@Singleton
public class MySingleton {
    @Inject Context context;
    @Inject MyOtherSingleton myOtherSingleton;

    @Inject
    public MySingleton() {
    }
}

您也可以执行构造函数参数

private final Context context;
private final MyOtherSingleton myOtherSingleton;

@Inject
public MySingleton(Context context, MyOtherSingleton myOtherSingleton) {
    this.context = context;
    this.myOtherSingleton = myOtherSingleton;
}
SingletonComponent singletonComponent = DaggerSingletonComponent.builder()
           .contextModule(CustomApplication.this)
           .build();

// and elsewhere

@Inject
MySingleton mySingleton;

// ...
    singletonComponent.inject(this);

已确认工作:

08-23 04:39:28.418 com.zhuinden.rxrealm D/DogView: My singleton has [com.zhuinden.rxrealm.application.CustomApplication@53348a58] and [com.zhuinden.rxrealm.application.injection.test.MyOtherSingleton@5336bb74]
08-23 04:39:36.422 com.zhuinden.rxrealm D/CatView: My singleton has [com.zhuinden.rxrealm.application.CustomApplication@53348a58] and [com.zhuinden.rxrealm.application.injection.test.MyOtherSingleton@5336bb74]

答案 1 :(得分:8)

这是一个简化的(不完全精确 - 下面的检查链接)文本逐渐解释Dagger2及其背后的想法。我希望你能在本文之后阅读并理解Dagger2的其他细节。

不要专注于单身一词。存在Dagger2(忘记匕首并使用dagger2)来强制执行对象范围。不是我们通常谈论的范围(类,方法,循环),而是架构级别的范围(您定义这些层)。

Android中的一些典型图层是Application,Activity和Fragment。如您所知,您的Android应用程序只获取一个Application类实例。 Activity类的许多实例和Fragment类的许多实例。

您希望保持您的应用程序干净整洁,并希望将对象保持在他们所属的位置(强制语义)。这些对象需要在的某处创建(通常你必须输入工厂类/方法/项目 - 一个是个笑话),需要在某处调用创建实用程序,你需要传递这些对象从某个地方到他们所属的地方!

要输入(通常是具有奇怪名称的类),并将这些对象从创建它们的位置传递到它们所属的位置,可能会遇到很多挑战。特别是当许多不同的类使用你的特殊对象时。

Dagger2来救援!基本上你需要理解两个术语。组件和模块。

组件在这里注入。他们为你的类注入他们需要构建的对象。组件只能注入,它们不会创建对象。那么谁创造了对象?

模块创建组件注入需要构造的类的对象。模块充满了提供 InsertName 方法。这些方法创建需要传递给需要它们的类的对象。如果使用@Scope 注释提供方法,则提供方法将始终创建新对象,或者它将重用(singleton)已创建的对象(您需要键入新的范围注释但是那个细节)。提供方法的名称并不重要。重要的是这些方法的返回类型(只记得以后会有用的信息)

当您键入组件时,您需要说明哪些模块与该组件关联,并且在组件实例化期间,您必须将关联的模块实例传递给该组件构造函数。组件和模块一起构成了一台平均注射机。

在您认为Component应该注入的层中实例化您的Component (Dagger2为您的组件生成构建器类)。例如,您在Application类中创建ApplicationComponent实例。 ApplicationComponent注入的对象只创建一次,并且它们存在,而ApplicationComponent实例存在(在注入期间,它们将被提取,而不是重新创建)。 ApplicationComponent实例存在,而Application实例存在(所以在Android环境中基本上总是/在应用程序生命周期内)

您可以使用Activity类重复相同的故事。在Activity类中实例化ActivityComponent,该Activity存在时该Component存在。注意ActivityComponent注入的对象仅在ActivityComponent(Activity类实例)存在时才存在。这就是Dagger2的美丽。属于“活动”图层的对象的字面范围是“活动”图层。

注意:组件可以相互依赖。您的ActivityComponent可以依赖于您的ApplicationComponent,因此Activity层可以使用来自Application层的对象(但不是其他方式,这是糟糕的设计)。这样,组件形成了一个依赖树,使得对象获取和注入非常有效。

在阅读完本文之后(祝贺您好先生)我建议您查看此link并查看Jake Wharton's talk on Dagger2

相关问题