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

My *_*use 17 singleton android dagger-2

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

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

Epi*_*rce 14

您只需要使用@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() {
    }
}
Run Code Online (Sandbox Code Playgroud)

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

private final Context context;
private final MyOtherSingleton myOtherSingleton;

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

// and elsewhere

@Inject
MySingleton mySingleton;

// ...
    singletonComponent.inject(this);
Run Code Online (Sandbox Code Playgroud)

已验证工作:

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]
Run Code Online (Sandbox Code Playgroud)


Spi*_*dey 9

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

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

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

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

这是很多类型的东西(通常是具有奇怪名称的类)并且将这些对象从它们创建的位置传递到它们所属的位置可能是一个非常大的挑战.特别是当许多不同的类使用你的特殊对象时.

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

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

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

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

在您认为Component应该注入的层中实例化您的Component (Dagger2为您的Components生成构建器类).例如,您在Application类中创建ApplicationComponent实例.ApplicationComponent注入的对象只创建一次,并且当ApplicationComponent实例存在时它们存在(在注入期间,它们将被提取,而不是重新创建).ApplicationComponent实例在Application实例存在时存在(因此在Android环境中基本上始终/在应用程序生存期内).

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

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

看完之后(我祝贺你好先生)我建议看一下这个链接并查看Jake Wharton关于Dagger2的演讲.