- mongodb - 在 MongoDB mapreduce 中,如何展平值对象?
- javascript - 对象传播与 Object.assign
- html - 输入类型 ="submit"Vs 按钮标签它们可以互换吗?
- sql - 使用 MongoDB 而不是 MS SQL Server 的优缺点
我正在尝试使用 Dagger2
使我的应用程序更好,代码更易于维护我在我的项目中注入(inject)了 Dagger (听起来很有趣)。我创建了 ApplicationComonent
组件,它在我的项目中完美运行。这是我的代码。
@Singleton
@Component(modules = {
ApplicationModule.class,
ThreadingModule.class,
NetworkModule.class,
DatabaseModule.class,
ServiceModule.class,
ParseModule.class,
PreferencesSessionModule.class})
public interface ApplicationComponent {
ActivityComponent activityComponent(ActivityModule activityModule);
void inject(BaseActivity baseActivity);
void inject(MainAppActivity mainAppActivity);
void inject(MyApplication application);
void inject(BaseFragment baseFragment);
void inject(MyService service);
void inject(RegistrationIntentService service);
}
我像这样在 MyApplication
类中创建我的组件实例
private void initializeAndInjectComponent() {
mApplicationComponent =
DaggerApplicationComponent
.builder()
.threadingModule(new ThreadingModule(1))
.applicationModule(new ApplicationModule(this))
.networkModule(new NetworkModule(
MyService.API_SERVER_BASE_URL,
MyService.TIMEOUT))
.build();
mApplicationComponent.inject(this);
}
我可以获取组件以便注入(inject)我的Activity
MyApplication application = MyApplication.get(this);
application.getApplicationComponent().inject(this);
一切都很完美。
添加每个方法以及模块类都用@Singleton
范围注解,所有与ApplicationComponent
相关的模块
现在我想让依赖关系变得更好,我已经看到了很多具有自定义范围的示例,例如 @PerActivity
、@PerFragment
。我有很多问题,但稍后再说。
于是我创建了ActivityComponent
@PerActivity
@Subcomponent(
modules = {
NetworkServiceModule.class,
ActivityModule.class,
PermissionModule.class
})
public interface ActivityComponent {
Activity activity();
void inject(BaseActivity baseActivity);
}
所有模块都是这样的
@PerActivity
@Module
public class ActivityModule {
private Activity mActivity;
public ActivityModule(Activity activity) {
this.mActivity = activity;
}
@Provides
@PerActivity
Activity provideActivity() {
return this.mActivity;
}
}
我的 BaseActivity
中有以下依赖项
// Dependencies from ApplicationComponent
@Inject
protected ApplicationSettingsManager mApplicationSettingsManager;
@Inject
protected ScheduledThreadPoolExecutor mPoolExecutor;
// Dependencies from ActivityComponent
@Inject
protected SpiceManager mSpiceManager;
@Inject
protected PermissionController mPermissionController;
在我的 onCreate()
方法中,我注入(inject)如下
MyApplication application = MyApplication.get(this);
application.getApplicationComponent().activityComponent(new ActivityModule(this)).inject(this);
在创建子组件 ActivityComponent
之前是
MyApplication application = MyApplication.get(this);
application.getApplicationComponent().inject(this);
现在我遇到了一个错误
Error:(34, 10) error: com.octo.android.robospice.SpiceManager cannot be provided without an @Inject constructor or from an @Provides- or @Produces-annotated method.
BaseActivity.mSpiceManager
[injected field of type: com.octo.android.robospice.SpiceManager mSpiceManager]
我无法弄清楚问题出在哪里,我错过了什么。我对 dagger2 中作用域的问题。
除了 @Singleton
之外的所有内容都被 Dagger 2 忽略,对吗?我不明白组件的生命周期是如何管理的?我只有一个想法
当你使用@Singleton
注解时, Dagger 是在某个静态池中创建对象,该对象会在整个应用程序生命周期中存在,当JVM进程(dalvik VM,ART)实例将被销毁时被摧毁。
当您使用任何其他注解时,只是为了让您作为开发人员更好地维护代码,@PerActivity
、@PerFragment
只是自定义注解而已。如果您将 @PerFragment
组件放在 Application 类中,它将与 Application 一样存在。我对吗 ?
所以我这样理解,如果 dagger 找到 @Singleton
注释,它将在第一次创建组件时添加对组件的静态引用,如果有任何其他注释,则不会持有对组件的引用。
对于上述问题的任何帮助,我将不胜感激。
更新
感谢 David Medenjak
的出色回答,我对 Dagger2
有了更深入的了解。
我也刚刚发现了问题,就我现在使用单独的 Activity
组件而言,我忘记了 ApplicationComponent
中的两行并在我的 中更改了inejction >MainActivity
到 ActivityComponent
而不是 ApplicationComponent
,所以它肯定无法解析子组件的依赖关系。
void inject(BaseActivity baseActivity);
void inject(MainAppActivity mainAppActivity);
现在一切正常,我喜欢 Dagger2
和分离的架构。
最佳答案
有点激进,但为了简化事情:所有 Scope 注释都不过是语法糖——包括 @Singleton
。
作用域大多只提供编译时检查。循环依赖,或关于您可能错过的事情的错误。 @Singleton
就像任何其他范围一样,唯一的区别是它是一个已经存在的注释,您不必自己创建它。您可以改用 @MySingleton
。
[...] dagger is creating object in some static pool that will exists during whole application lifecycle
没有。 Dagger什么都不做静态的。您有组件对象。这些组件包含由模块创建的对象。如果组件中的对象具有组件的范围,则它只会在那个确切的组件中创建一次。如果您决定创建 2 个 AppComponent
对象,您将拥有每个 @Singleton
注释对象的 2 个对象,每个对象都在其组件中。这就是为什么您应该保留对组件的引用。我见过或使用的大多数实现都将它们的 AppComponent
保留在它们的 Application
中。如果你这样做,你可以像一样使用它——它仍然只是一个 POJO。
[...]you place @PerFragment component in Application class it will live as long as Application lives.
是的。如上段所述,它只是一个对象。保留引用,您保留对象。把它扔掉或创建一个新的,你就有了新的对象(在这个组件/范围内定义)。您应该不将 Activity 或 fragment 范围的组件分别保留在 Activity 或 fragment 之外的任何地方,因为保留它们例如在您的应用程序组件中很可能会导致内存泄漏。 (如果不需要,您可能不需要 Activity 或 fragment 范围。)
if dagger finds
@Singleton
annotation it will add static reference to component when it is created first time and in case of any other annotation it won't hold reference to component.
再次,不。没有什么静态的。普通的旧 java 对象。您可以拥有多个带有自己的对象的 @Singleton
组件,但您可能不应该(尽管这是使仪器测试成为可能/容易的原因——只需交换组件。)
SpiceManager cannot be provided without an @Inject constructor or from an @Provides- or @Produces-annotated method.
这意味着您尝试注入(inject)对象的组件找不到任何方法来生成或提供 SpiceManager
。确保您从 AppComponent 或其他地方提供它,没有遗漏任何注释等。
关于java - Dagger 2 范围和子组件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36371716/
Dagger 和 Dagger 2.0 有什么区别,为什么 Google 决定 fork 现有项目? 最佳答案 来自 Dagger 2 presentation 的一些引述 Dagger 1 的问题:
我想制作一个包含一个主要 Activity 和多个 fragment 的简单项目。在这里,我在一项 Activity 中有两个 fragment ,我想将演示者注入(inject)登录 fragmen
我是 dagger 的新手,我正在寻找如何在 dagger-2.x 中实现 spring 配置文件等功能。我想为我的开发环境和生产环境使用不同的 bean,但我使用的是带有 Java 的 Dagger
假设我有两个服务 AService 和 BService,它们都需要一个 API key 。 所以在我的模块中,我不能做类似的事情: @Provides @Singleton @A @ApiKey S
我对 Dagger 很陌生——我什至不知道它是否适用于我的应用程序 我有一个搜索页面,它返回有关给定名人的最新消息。 我写了一个测试来验证当我们搜索一个受欢迎的名人时结果会出现在页面上。 page有一
我最近将 dagger 2.8 更新为 2.9 dagger。和最新版本的文档已添加如下: -添加@BindsInstance组件构建器可以轻松绑定(bind)在图之外构建的实例。 -制作人:已添加
Dagger documentation页面说: To get the most out of compile-time validation, create a module that includ
我可以知道之间的区别吗? @Singleton VS 静态 在dagger2中提供? @Provides static User currentUser(AuthManager authManager
我有一个功能,我需要为不同的用户提供不同的房间数据库。 我正在使用 Dagger 2 创建房间数据库。我的应用程序组件创建一个房间数据库。当用户切换到另一个用户时,我想为此创建新的房间数据库,我需要创
我是 Dagger 2 的新手,正在尝试 IntelliJ 中的 Dagger 2 Coffee Example,它似乎不会生成 DaggerCoffeeApp_Coffee(它应该生成它),即使我密
我正在尝试在 Android 上使用 Dagger 2。我以前让它工作,我有一个 appModule 将依赖项注入(inject)应用程序中的特定类。我的问题是我收到错误 Error:(14, 55)
我是 kotlin 和 Dagger 的新手。我有一个小问题,我不知道如何解决,也没有找到解决方案。 这就是我所拥有的: @Module class AppModule (app: Applicati
我正在尝试使用 Dagger 建立一个项目。现在,当我构建时,没有为组件生成任何 Dagger* 类,并且出现以下错误: Error:(10, 8) error: [com.redditapp.dag
在 Dagger 中,我有时会看到有些组件只扩展一个接口(interface),而其他组件则使用 dependencies。 例如我们有一个基础组件: @Singleton @Component(mo
有没有办法告诉 Dagger 2 如何提供一些东西,但不允许它被注入(inject)? 假设我要注入(inject)一个 Qux .一个 Qux需要 Foo和 Bar : @Provides @Sin
( x-post from /r/androiddev ) 我只想在序言中说这不是一篇“哪个更好”的帖子;这严格来说是一个关于如何使用 Dagger 构建某些东西的问题(以及如何在 Kodein 中构
https://developer.android.com/topic/libraries/architecture/ 在Android架构蓝图中,为什么dagger是基于mvp架构而不是MVVM架构
我第一次开始同时使用 Kotlin 和 Dagger 2。我假设一切都与 Java 中的相同,但显然不完全相同。 Dagger 不会为我生成 Dagger* 文件。这是我的代码: 组件: @PerAc
我正在尝试将 Dagger 2 与 eclipse 集成,我使用的库如下: dagger-2.0.jar dagger-compiler-2.0.jar guava-13.0.1.jar javawr
我想练习这个Dagger 2 Vehicle Motor例子。 除了我的 gradel.build 之外,我所做的一切都与该教程中的一样: compile 'com.google.dagger:dag
我是一名优秀的程序员,十分优秀!