Android 中的 Dagger2 子组件混淆
Dagger2 sub-component confusion in Android
我的目标:
了解范围的工作原理以及如何实施 UserScope
我可以在多个 Activity 上使用并根据需要 reset/create 一个新的 Activity。
我使用的方法:
此博客:http://frogermcs.github.io/building-userscope-with-dagger2/
它显然解释了我在这里试图实现的同一件事。
官方文档
http://frogermcs.github.io/building-userscope-with-dagger2/
博客快速简介
显然,有UserModule
和UserComponent
。作者已将 UserComponent
的创建包装在 UserManager
下,后者具有 ApplicationScope
。所以 UserManager
在登录时可用。当登录成功时 UserComponent
通过 UserManager
初始化。简单的逻辑。
现在,这个已经初始化的 @UserScope
被用于几个 Activity,如图所示。
我很难理解
看看UserComponent
。
public interface UserComponent {
@Subcomponent.Builder
interface Builder {
Builder sessionModule(UserModule userModule);
UserComponent build();
}
UserDetailsActivityComponent plus(UserDetailsActivityComponent.UserDetailsActivityModule module);
RepositoriesListActivityComponent plus(RepositoriesListActivityComponent.RepositoriesListActivityModule module);
LogoutManager logoutManager();
}
具体来说UserDetailsActivityComponent
和RepositoriesListActivityComponent
是通过UserComponent
创建的。像这样,
@Override
protected void onUserComponentSetup(UserComponent userComponent) {
userComponent.plus(new UserDetailsActivityComponent.UserDetailsActivityModule(this)).inject(this);
}
所以它们首先在 UserComponent
到 UserManager
中预先创建,然后它调用 onUserComponentSetup
,然后创建适当的组件并注入当前的 Activity。
我无法理解上面提到的这种模式, 正如我在文档中读到的那样,当我们需要在特定实例上注入时,我们使用 plus(InjectionToBeDoneOn i)
InjectionToBeDoneOn
。但是为什么要通过这个组件注入这个 Activity 呢?这有什么用呢?用 DaggerXYZComponent().Builder().Build().inject(activity)
和 activity 的 onCreate()
中的传统方式来做这件事难道没有意义吗?
此外,我缺少体面的 material UserScope
在 Android 中的实现方式,它具有从登录到注销的生命周期,但不大于 @Singleton
范围。
we use plus(InjectionToBeDoneOn i)
when we need the injection on particular instance of InjectionToBeDoneOn
不完全是。一个组件基本上有3种方法
SomeDependency provideDependency()
只是创建/提供对子组件的一些依赖性,或者用于手动检索(基本上是 getter)
void inject(MyAndroidFrameworkClass object)
注入对象及其依赖项
SomeSubComponent plus(SubComponentModule module)
创建一个子组件,添加额外的模块
你在这里混淆了 2. 和 3.。
// user scoped component
userComponent
// create a subcomponent (UserDetailsActivityComponent)
.plus(new UserDetailsActivityComponent.UserDetailsActivityModule(this))
// use the UserDetailsActivityComponent that was just created and inject with it
.inject(this);
UserDetailsActivityComponent
是 UserComponent
的子组件,这就是扩展 userComponent .plus(somemodule)
以创建子组件的原因。如果您的子组件不需要额外的模块,您也可以只使用 .plus()
因为对于 Dagger 来说重要的是 return 类型 或一般的签名。
- 如果它 return 是另一个组件,则它会创建一个子组件。
- 如果它有一个参数和returns
void
或者参数类型,那么它是一个注入方法
- 如果它没有参数,并且 returns 某些类型是提供方法 (1.) 来公开某些依赖项
but why inject this Activity via this Component? What does this accomplish?
如果您要从头开始创建 UserDetailsActivityComponent
,它只会看到并知道它可以提供什么 本身 。如果你在某处有一些 @Singleton
它无法访问其中的任何一个,因为它不是对象图的一部分。
一个子组件扩展另一个组件,添加到对象图中。如果你有一个 @Singleton A
并且你的 UserComponentn 需要 A
来提供 B
,有一个子组件这将起作用,没有它你将得到一个 cannot be provided错误。
匕首不是魔法。它实际上只是建立一个有向图并检查是否一切正常。如果某些依赖关系彼此之间存在循环依赖关系,或者如果图形的某些部分无法访问它需要的依赖关系,它将抱怨。
您的 UserComponent
持有您的用户数据。为简单起见,假设它持有 UserName
。现在 UserDetailsActivity
可能想显示 UserName
,但它需要一些方法才能得到它。
通过使用 @Singleton AppComponent
作为父级,您可以访问某些 API,但不能访问用户范围的 API。您可以将用户范围的对象移动到 @Singleton AppComponent
中,但是每次用户更改时您都必须重新创建 AppComponent
(这违背了声明它的目的 @Singleton
,否则您必须找到其他方法来更新/更改用户。
如果你想用 Dagger 的方式来做,你可以创建一个 UserComponent 来 adds User 到图表中。这样子组件就可以访问它并执行它们的用户操作。
当用户发生变化时,您必须确保销毁所有使用 UserComponent 的活动/片段,然后您只需重新创建所有内容 — 使用新用户。
wont it make sense to do in conventional way in OnCreate()
of the activity with DaggerXYZComponent().Builder().Build().inject(activity)
当然可以。作者只是将对 app.getAppcomponent().getUserManager().getUserComponent()
或类似内容的调用放入他们的 BaseActivity
和 BaseUserActivity
中,这样您就不必每次都重复相同的代码行。 onCreate
基本还是会调用这个方法,只是让你直接使用组件,不用每次都去取组件。
您显然可以删除那些模板方法并内联 onCreate
中的所有内容,从而导致重复代码,使长 运行.
中的维护变得更加困难
i am missing decent material of how UserScope
is implemented in android which has life span from log-in to log-out but not bigger than @SingleTon
scope.
Android 无济于事,自己清理是你的工作。如果用户更改,您将清除 UserComponent 及其 SubComponents 接触的所有内容,并使用新用户重新创建它。
您必须将 UserComponent 与当前用户一起存储在应用程序 class 中,一些 "real" 单例,或一些 "Manager" 在具有 [=21] 的应用程序组件中=] 范围。我想每种方法都有自己的好处。
Scopes 只是向 Dagger 指出一个对象应该只存在于一个 Scope 中一次。无论您将其命名为什么,或者作用域中有多少个对象,都无关紧要。 Dagger 只需要它们来确保没有依赖循环。
我的目标:
了解范围的工作原理以及如何实施 UserScope
我可以在多个 Activity 上使用并根据需要 reset/create 一个新的 Activity。
我使用的方法:
此博客:http://frogermcs.github.io/building-userscope-with-dagger2/
它显然解释了我在这里试图实现的同一件事。官方文档 http://frogermcs.github.io/building-userscope-with-dagger2/
博客快速简介
显然,有UserModule
和UserComponent
。作者已将 UserComponent
的创建包装在 UserManager
下,后者具有 ApplicationScope
。所以 UserManager
在登录时可用。当登录成功时 UserComponent
通过 UserManager
初始化。简单的逻辑。
现在,这个已经初始化的 @UserScope
被用于几个 Activity,如图所示。
我很难理解
看看UserComponent
。
public interface UserComponent {
@Subcomponent.Builder
interface Builder {
Builder sessionModule(UserModule userModule);
UserComponent build();
}
UserDetailsActivityComponent plus(UserDetailsActivityComponent.UserDetailsActivityModule module);
RepositoriesListActivityComponent plus(RepositoriesListActivityComponent.RepositoriesListActivityModule module);
LogoutManager logoutManager();
}
具体来说UserDetailsActivityComponent
和RepositoriesListActivityComponent
是通过UserComponent
创建的。像这样,
@Override
protected void onUserComponentSetup(UserComponent userComponent) {
userComponent.plus(new UserDetailsActivityComponent.UserDetailsActivityModule(this)).inject(this);
}
所以它们首先在 UserComponent
到 UserManager
中预先创建,然后它调用 onUserComponentSetup
,然后创建适当的组件并注入当前的 Activity。
我无法理解上面提到的这种模式, 正如我在文档中读到的那样,当我们需要在特定实例上注入时,我们使用 plus(InjectionToBeDoneOn i)
InjectionToBeDoneOn
。但是为什么要通过这个组件注入这个 Activity 呢?这有什么用呢?用 DaggerXYZComponent().Builder().Build().inject(activity)
和 activity 的 onCreate()
中的传统方式来做这件事难道没有意义吗?
此外,我缺少体面的 material UserScope
在 Android 中的实现方式,它具有从登录到注销的生命周期,但不大于 @Singleton
范围。
we use
plus(InjectionToBeDoneOn i)
when we need the injection on particular instance of InjectionToBeDoneOn
不完全是。一个组件基本上有3种方法
SomeDependency provideDependency()
只是创建/提供对子组件的一些依赖性,或者用于手动检索(基本上是 getter)void inject(MyAndroidFrameworkClass object)
注入对象及其依赖项SomeSubComponent plus(SubComponentModule module)
创建一个子组件,添加额外的模块
你在这里混淆了 2. 和 3.。
// user scoped component
userComponent
// create a subcomponent (UserDetailsActivityComponent)
.plus(new UserDetailsActivityComponent.UserDetailsActivityModule(this))
// use the UserDetailsActivityComponent that was just created and inject with it
.inject(this);
UserDetailsActivityComponent
是 UserComponent
的子组件,这就是扩展 userComponent .plus(somemodule)
以创建子组件的原因。如果您的子组件不需要额外的模块,您也可以只使用 .plus()
因为对于 Dagger 来说重要的是 return 类型 或一般的签名。
- 如果它 return 是另一个组件,则它会创建一个子组件。
- 如果它有一个参数和returns
void
或者参数类型,那么它是一个注入方法 - 如果它没有参数,并且 returns 某些类型是提供方法 (1.) 来公开某些依赖项
but why inject this Activity via this Component? What does this accomplish?
如果您要从头开始创建 UserDetailsActivityComponent
,它只会看到并知道它可以提供什么 本身 。如果你在某处有一些 @Singleton
它无法访问其中的任何一个,因为它不是对象图的一部分。
一个子组件扩展另一个组件,添加到对象图中。如果你有一个 @Singleton A
并且你的 UserComponentn 需要 A
来提供 B
,有一个子组件这将起作用,没有它你将得到一个 cannot be provided错误。
匕首不是魔法。它实际上只是建立一个有向图并检查是否一切正常。如果某些依赖关系彼此之间存在循环依赖关系,或者如果图形的某些部分无法访问它需要的依赖关系,它将抱怨。
您的 UserComponent
持有您的用户数据。为简单起见,假设它持有 UserName
。现在 UserDetailsActivity
可能想显示 UserName
,但它需要一些方法才能得到它。
通过使用 @Singleton AppComponent
作为父级,您可以访问某些 API,但不能访问用户范围的 API。您可以将用户范围的对象移动到 @Singleton AppComponent
中,但是每次用户更改时您都必须重新创建 AppComponent
(这违背了声明它的目的 @Singleton
,否则您必须找到其他方法来更新/更改用户。
如果你想用 Dagger 的方式来做,你可以创建一个 UserComponent 来 adds User 到图表中。这样子组件就可以访问它并执行它们的用户操作。
当用户发生变化时,您必须确保销毁所有使用 UserComponent 的活动/片段,然后您只需重新创建所有内容 — 使用新用户。
wont it make sense to do in conventional way in
OnCreate()
of the activity withDaggerXYZComponent().Builder().Build().inject(activity)
当然可以。作者只是将对 app.getAppcomponent().getUserManager().getUserComponent()
或类似内容的调用放入他们的 BaseActivity
和 BaseUserActivity
中,这样您就不必每次都重复相同的代码行。 onCreate
基本还是会调用这个方法,只是让你直接使用组件,不用每次都去取组件。
您显然可以删除那些模板方法并内联 onCreate
中的所有内容,从而导致重复代码,使长 运行.
i am missing decent material of how
UserScope
is implemented in android which has life span from log-in to log-out but not bigger than@SingleTon
scope.
Android 无济于事,自己清理是你的工作。如果用户更改,您将清除 UserComponent 及其 SubComponents 接触的所有内容,并使用新用户重新创建它。
您必须将 UserComponent 与当前用户一起存储在应用程序 class 中,一些 "real" 单例,或一些 "Manager" 在具有 [=21] 的应用程序组件中=] 范围。我想每种方法都有自己的好处。
Scopes 只是向 Dagger 指出一个对象应该只存在于一个 Scope 中一次。无论您将其命名为什么,或者作用域中有多少个对象,都无关紧要。 Dagger 只需要它们来确保没有依赖循环。