Android中的Dagger2子组件混淆

Android中的Dagger2子组件混淆,android,dependencies,dagger-2,Android,Dependencies,Dagger 2,我的目标: 了解作用域是如何工作的,以及如何实现可以在多个活动中使用的UserScope,并根据需要重置/创建一个新的 我正在使用的方法: 此博客: 这显然解释了我在这里试图实现的同样的事情 公文 博客快速简报 显然,有UserModule和UserComponent。作者已将UserComponent的创建包装在UserManager下,其中包含ApplicationScope。因此,UserManager在登录时可用。登录成功后,UserComponent通过UserManager初始化

我的目标:

了解作用域是如何工作的,以及如何实现可以在多个活动中使用的
UserScope
,并根据需要重置/创建一个新的

我正在使用的方法:

  • 此博客:
    这显然解释了我在这里试图实现的同样的事情

  • 公文

  • 博客快速简报

    显然,有
    UserModule
    UserComponent
    。作者已将
    UserComponent
    的创建包装在
    UserManager
    下,其中包含
    ApplicationScope
    。因此,
    UserManager
    在登录时可用。登录成功后,
    UserComponent
    通过
    UserManager
    初始化。简单的逻辑

    现在,这个已经初始化的
    @UserScope
    被用于几个活动中,如图所示

    我正在努力理解的内容

    看看
    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
    repositorieslistativitycomponent
    是通过
    UserComponent
    创建的。像这样,

    @Override
        protected void onUserComponentSetup(UserComponent userComponent) {
            userComponent.plus(new UserDetailsActivityComponent.UserDetailsActivityModule(this)).inject(this);
        }
    
    因此,它们首先通过
    UserManager
    UserComponent
    中预先创建,然后调用
    onUserComponentSetup
    ,然后创建适当的组件并注入当前活动

    我无法理解上面提到的这种模式,正如我在文档中读到的那样,当我们需要对
    InjectionTobedonone
    的特定实例进行注入时,我们使用
    plus(InjectionTobedonone I)
    。但是为什么要通过这个组件注入这个活动呢?这能实现什么?在使用
    DaggerXYZComponent().Builder().Build().inject(activity)
    的活动的
    onCreate()
    中使用常规方法执行此操作是否有意义

    此外,我还缺少了关于如何在Android中实现
    UserScope
    的详细资料,Android的生命周期从登录到注销,但不超过
    @Singleton
    范围

    当我们需要对InjectionTobedonone的特定实例进行注入时,我们使用
    plus(InjectionTobedonone i)

    不完全是。一个组件基本上有3种方法

  • SomeDependency provideDependency()
    ,它只创建/提供一些对子组件的依赖性,或者用于手动检索(基本上是一个getter)
  • void inject(MyAndroidFrameworkClass对象)
    用于注入对象及其依赖项
  • SomeSubComponent plus(SubComponentModule模块)
    创建子组件并添加其他模块
  • 你搞混了。三,。在这里

    // 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被扩展
    。加上(somemodule)
    以创建子组件。如果您的子组件不需要额外的模块,您也可以使用
    .plus()
    ,因为一般来说,重要的是返回类型或签名

    • 如果它返回另一个组件,那么它将创建一个子组件
    • 如果它有一个参数并返回
      void
      或参数类型,则它是一个注入方法
    • 如果它没有参数并返回某种类型,则提供一个方法(1)来公开某些依赖项
    但是为什么要通过这个组件注入这个活动呢?这能实现什么

    如果您从头开始创建
    UserDetailsActivityComponent
    ,它只会看到并知道它自己能提供什么。如果您在某个地方有一些
    @Singleton
    ,它将无法访问其中任何一个,因为它不是对象图的一部分

    子组件扩展另一个组件,添加到对象图中。如果您有一个
    @Singleton a
    ,并且您的用户组件n需要
    a
    来提供
    B
    ,有了子组件,这将起作用,没有它,您将得到一个无法提供的错误

    匕首不是魔法。它实际上只是建立一个有向图并检查是否一切正常。如果某些依赖项彼此之间存在循环依赖项,或者如果图形的某个部分无法访问所需的依赖项,它将发出抱怨

    您的
    UserComponent
    保存您的用户数据。为了简单起见,假设它包含
    用户名
    。现在,
    UserDetailsActivity
    可能希望显示
    UserName
    ,但它需要某种方法来获得它

    通过使用
    @singletonappcomponent
    作为父级,您可以访问某些API,但不能访问用户范围的API。您可以将用户范围内的对象移动到
    @Singleton AppComponent
    ,但是,您必须在每次用户更改时重新创建
    AppComponent
    (这与声明它
    @Singleton
    的目的背道而驰),或者您必须找到一些其他方法来更新/更改用户

    如果你想用Dagger的方式,你可以创建一个UserComponent,将用户添加到图中,这样子组件就可以访问它并完成他们的用户任务

    当用户发生更改时,您必须确保销毁使用UserComponent的任何活动/片段,并且只需使用新用户重新创建所有内容

    使用
    DaggerXYZComponent().Builder().Build().inject(活动)

    你当然可以这样做。作者只是将调用放在
    app.getAppcomponent().getUserManager().getUserComponent()上
    或类似的内容,将其添加到
    BaseActivity
    BaseUserActivity
    中,这样您就不必每次重复相同的代码行。此方法基本上仍将在
    onCreate
    中调用,它只是启用