dev*_*cca 6 android dependency-injection android-library dagger-2
我正在构建一个具有一些功能的应用程序:ContentProvider,SyncAdapter,作业服务和相关的持久性逻辑.除此之外,还有UI的活动.我试图将所有所述功能放在一个单独的库模块中,因为从理论上讲它们的逻辑是独立的,可以被任何应用程序重用.
现在来了Dagger2.我的库的依赖图的第一个节点(主要组件)确实需要提供Context,并且必须从Application注入此Context,因为库范围与应用程序具有相同的生命周期.显然,要自包含,我的库不应该直接使用我的Application类.
这些是我想到的可能性:
这样做的正确方法是什么?
适用于Android的Dagger 2来救援.它提供的概念AndroidInjector,这是一种Component可以用来以静态方式注入一个实例,而不必知道依赖供应商.此外,使用Dagger-开箱即用的前缀类,注入的依赖项看起来像是从哪儿冒出来的.真棒.
您所要做的就是在库中声明一个Module安装在Application中的顶级Component.这Module将提供SubComponent库所需的所有依赖项和s,它将自动继承@AppContext Context您在依赖关系图中播种的内容,随时可以在库中的任何位置注入,以及通过主Application提供的每个依赖项Component.
这是一个简短的例子(用Kotlin编写):
@Component(modules = [
AndroidSupportInjectionModule::class,
AppModule::class,
LibraryModule::class //plug-in the library to the dependency graph
])
@Singleton
interface AppComponent : AndroidInjector<App> {
@Component.Builder
abstract class Builder : AndroidInjector.Builder<App>() {
@BindsInstance
abstract fun appContext(@AppContext context: Context)
override fun seedInstance(instance: App) {
appContext(instance)
}
}
}
Run Code Online (Sandbox Code Playgroud)
编辑:扩展示例
Application子类的一个示例:
// DaggerApplication provides out-of-the-box support to all the AndroidInjectors.
// See the class' code to understand the magic.
public class App extends DaggerApplication {
@Override
protected AndroidInjector<? extends DaggerApplication> applicationInjector() {
// We only provide its own Injector, the Application Injector,
// that is the previous AppComponent
return DaggerAppComponent.builder().create(this);
}
Run Code Online (Sandbox Code Playgroud)
在您的Android库中:
@Module
public abstract class LibraryModule {
@ContributesAndroidInjector
public abstract LibraryActivity contributeLibraryActivityInjector();
}
Run Code Online (Sandbox Code Playgroud)
public class LibraryActivity extends DaggerAppCompatActivity {
@Inject
@AppContext
Context appContext;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceSate);
// here you automagically have your injected application context!
ExternalSingleton.getInstance(appContext)
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2383 次 |
| 最近记录: |