使用DispatchingAndroidInjector<&燃气轮机;还有其他dagger.android类?

使用DispatchingAndroidInjector<&燃气轮机;还有其他dagger.android类?,android,dagger-2,Android,Dagger 2,我正在将Dagger2安装到我的android项目中。这是我第一次使用这个框架,到目前为止一切都很顺利。但是我看到了不同的方法,你可以在你的项目中建立这个框架,我想知道哪一个更好,因为我比较了两者,对我来说,结果是一样的 我遵循了这个指南: 在互联网上搜索他们都使用这种方法。 它使用@Module和@Component来定义依赖项 您的应用程序的最终结果如下: public class MyApp extends Application { private NetComponent m

我正在将Dagger2安装到我的android项目中。这是我第一次使用这个框架,到目前为止一切都很顺利。但是我看到了不同的方法,你可以在你的项目中建立这个框架,我想知道哪一个更好,因为我比较了两者,对我来说,结果是一样的

我遵循了这个指南:

在互联网上搜索他们都使用这种方法。 它使用@Module和@Component来定义依赖项

您的应用程序的最终结果如下:

public class MyApp extends Application {

    private NetComponent mNetComponent;

    @Override
    public void onCreate() {
        super.onCreate();

        // Dagger%COMPONENT_NAME%
        mNetComponent = DaggerNetComponent.builder()
                // list of modules that are part of this component need to be created here too
                .appModule(new AppModule(this)) // This also corresponds to the name of your module: %component_name%Module
                .netModule(new NetModule("https://api.github.com"))
                .build();

        // If a Dagger 2 component does not have any constructor arguments for any of its modules,
        // then we can use .create() as a shortcut instead:
        //  mNetComponent = com.codepath.dagger.components.DaggerNetComponent.create();
    }

    public NetComponent getNetComponent() {
       return mNetComponent;
    }
}
@Subcomponent(modules = ...)
 public interface YourActivitySubcomponent extends AndroidInjector<YourActivity> {
   @Subcomponent.Builder
   public abstract class Builder extends AndroidInjector.Builder<YourActivity> {}
 }

@Module(subcomponents = YourActivitySubcomponent.class)
 abstract class YourActivityModule {
   @Binds
   @IntoMap
   @ActivityKey(YourActivity.class)
   abstract AndroidInjector.Factory<? extends Activity>
       bindYourActivityInjectorFactory(YourActivitySubcomponent.Builder builder);
 }

 @Component(modules = {..., YourActivityModule.class})
 interface YourApplicationComponent {}

public class YourApplication extends Application implements HasDispatchingActivityInjector {
   @Inject DispatchingAndroidInjector<Activity> dispatchingActivityInjector;

   @Override
   public void onCreate() {
     super.onCreate();
     DaggerYourApplicationComponent.create()
         .inject(this);
   }

   @Override
   public DispatchingAndroidInjector<Activity> activityInjector() {
     return dispatchingActivityInjector;
   }
 }
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    ((MyApp) getApplicationContext()).getNetComponent().inject(this);
}
但我找到了另一种方法(我还没有测试): 它看起来完全不同,使用不同的类和注释。 它使用的是这样的东西:

public class MyApp extends Application {

    private NetComponent mNetComponent;

    @Override
    public void onCreate() {
        super.onCreate();

        // Dagger%COMPONENT_NAME%
        mNetComponent = DaggerNetComponent.builder()
                // list of modules that are part of this component need to be created here too
                .appModule(new AppModule(this)) // This also corresponds to the name of your module: %component_name%Module
                .netModule(new NetModule("https://api.github.com"))
                .build();

        // If a Dagger 2 component does not have any constructor arguments for any of its modules,
        // then we can use .create() as a shortcut instead:
        //  mNetComponent = com.codepath.dagger.components.DaggerNetComponent.create();
    }

    public NetComponent getNetComponent() {
       return mNetComponent;
    }
}
@Subcomponent(modules = ...)
 public interface YourActivitySubcomponent extends AndroidInjector<YourActivity> {
   @Subcomponent.Builder
   public abstract class Builder extends AndroidInjector.Builder<YourActivity> {}
 }

@Module(subcomponents = YourActivitySubcomponent.class)
 abstract class YourActivityModule {
   @Binds
   @IntoMap
   @ActivityKey(YourActivity.class)
   abstract AndroidInjector.Factory<? extends Activity>
       bindYourActivityInjectorFactory(YourActivitySubcomponent.Builder builder);
 }

 @Component(modules = {..., YourActivityModule.class})
 interface YourApplicationComponent {}

public class YourApplication extends Application implements HasDispatchingActivityInjector {
   @Inject DispatchingAndroidInjector<Activity> dispatchingActivityInjector;

   @Override
   public void onCreate() {
     super.onCreate();
     DaggerYourApplicationComponent.create()
         .inject(this);
   }

   @Override
   public DispatchingAndroidInjector<Activity> activityInjector() {
     return dispatchingActivityInjector;
   }
 }
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    ((MyApp) getApplicationContext()).getNetComponent().inject(this);
}
@子组件(模块=…)
公共接口YourActivitySubcomponent扩展了AndroidJector{
@子组件生成器
公共抽象类生成器扩展了androidject.Builder{}
}
@模块(subcomponents=YourActivitySubcomponent.class)
抽象类YourActivityModule{
@束缚
@英托马普
@ActivityKey(YourActivity.class)

abstract AndroidJector.Factory现在官方规定的为Android设置Dagger 2的方法有许多优点,应该优先考虑。这些优点就是这里详述的,即:

  • 复制粘贴代码使以后的重构变得困难。随着越来越多的开发人员复制粘贴该块,知道它实际作用的人会越来越少

  • 更根本的是,它要求请求注入的类型(FrombulationActivity)知道它的注入器。即使这是通过接口而不是具体类型完成的,它也打破了依赖注入的核心原则:类不应该知道它是如何被注入的

  • 让我们将这些理由应用到您的第一个示例中

    原因1

    假设我们有一个活动想要使用您的
    NetComponent
    。我们称之为
    NetActivity
    。该
    NetActivity
    onCreate(Bundle savedInstanceState)
    方法如下所示:

    public class MyApp extends Application {
    
        private NetComponent mNetComponent;
    
        @Override
        public void onCreate() {
            super.onCreate();
    
            // Dagger%COMPONENT_NAME%
            mNetComponent = DaggerNetComponent.builder()
                    // list of modules that are part of this component need to be created here too
                    .appModule(new AppModule(this)) // This also corresponds to the name of your module: %component_name%Module
                    .netModule(new NetModule("https://api.github.com"))
                    .build();
    
            // If a Dagger 2 component does not have any constructor arguments for any of its modules,
            // then we can use .create() as a shortcut instead:
            //  mNetComponent = com.codepath.dagger.components.DaggerNetComponent.create();
        }
    
        public NetComponent getNetComponent() {
           return mNetComponent;
        }
    }
    
    @Subcomponent(modules = ...)
     public interface YourActivitySubcomponent extends AndroidInjector<YourActivity> {
       @Subcomponent.Builder
       public abstract class Builder extends AndroidInjector.Builder<YourActivity> {}
     }
    
    @Module(subcomponents = YourActivitySubcomponent.class)
     abstract class YourActivityModule {
       @Binds
       @IntoMap
       @ActivityKey(YourActivity.class)
       abstract AndroidInjector.Factory<? extends Activity>
           bindYourActivityInjectorFactory(YourActivitySubcomponent.Builder builder);
     }
    
     @Component(modules = {..., YourActivityModule.class})
     interface YourApplicationComponent {}
    
    public class YourApplication extends Application implements HasDispatchingActivityInjector {
       @Inject DispatchingAndroidInjector<Activity> dispatchingActivityInjector;
    
       @Override
       public void onCreate() {
         super.onCreate();
         DaggerYourApplicationComponent.create()
             .inject(this);
       }
    
       @Override
       public DispatchingAndroidInjector<Activity> activityInjector() {
         return dispatchingActivityInjector;
       }
     }
    
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        ((MyApp) getApplicationContext()).getNetComponent().inject(this);
    }
    
    此代码具有分散在燕麦片上的指甲剪的所有视觉吸引力(不是我的明喻),最终将复制粘贴到您使用
    NetComponent
    的所有注射站点活动中。如果您使用更复杂的组件,例如文档中的示例:

    @Override
    public void onCreate(Bundle savedInstanceState) {
      super.onCreate(savedInstanceState);
      // DO THIS FIRST. Otherwise frombulator might be null!
      ((SomeApplicationBaseType) getContext().getApplicationContext())
         .getApplicationComponent()
         .newActivityComponentBuilder()
         .activity(this)
         .build()
         .inject(this);
     // ... now you can write the exciting code
    
    }

    更糟。它很容易退化为一段神奇的代码,必须复制并粘贴到整个注入站点。如果它改变了,很容易忘记只更新一个站点,导致应用程序崩溃

    原因2

    依赖项注入的一个巨大优势是注入站点不需要知道或关心它们的注入器,就像依赖项不知道或关心它们的依赖项一样。要返回我们的
    网络活动
    ,我们有:

    ((MyApp) getApplicationContext()).getNetComponent().inject(this);
    
    该活动“了解”其注入器(
    NetComponent
    ),现在该活动与一个具体的
    MyApp
    和来自同一个注入器的方法
    getNetComponent()
    结合在一起。如果这些类别中的任何一个发生更改,
    NetActivity
    也必须更改

    遵循Dagger版本2.10和更高版本中提供的新的内部活动和片段注入方式的优点与这些缺点正好相反:

  • 最终得到的复制粘贴代码更少
  • 请求喷射的类型不再需要知道或关心其喷射器或喷射器的来源
  • 此外,正如中所指出的,优先使用子组件而不是依赖组件可以减少应用程序的方法数


    虽然使用子组件一开始似乎比较困难,但有一些明显的优势。然而,为了学习匕首相关组件,最初可能更容易理解。如果第二个例子一开始太复杂,当你掌握了技巧后,你可以选择首选的方法。

    你能详细说明不同之处吗?另外,总体来看,我会按照谷歌推荐的方法进行操作。他们维护Dagger2:DI附加了代码中的主要差异,以便更好地了解我在说什么@Shmuel您给出的回购协议代码示例与我编写的代码相同。但是这个链接()显示的是不同的东西。正如你所看到的,url也来自google=P。也许我遗漏了什么。你会发现Dagger有十几种不同的实现方式,它们的复杂程度各不相同。最后一个例子看起来像是泛化注入过程并使用子组件——老实说,我尝试使用KISS原则。记住,在实现相同目标的同时,这两个选项中的哪一个适合您的目标。对我来说,DI应该用这个库来解决的难题正被越来越复杂的实现所抵消。我在页面上看到了这些优点。虽然第二个优势是有意义的,但第一个优势是没有意义的:“复制粘贴代码会使以后重构变得困难。随着越来越多的开发人员复制粘贴该块,知道它实际作用的人会越来越少。“最终更改此代码”((MyApp)getApplication()).getNetComponent().inject(此);“对于此代码”AndroidInjection.inject(此);”所以你必须粘贴代码。@leandroucampo你说得对,仍然会有一些复制/粘贴。但对于第二种方法,则没有那么多。不管怎样,谢谢你的接受。我想区别在于人们可能可以推断出雄激素注射。注射(这个)
    的作用,因为它保持简单。在前一个示例中,以及在文档中的第一个示例中,它要复杂得多,需要更多地理解代码的作用。当事情变得更复杂时,这意味着复制/粘贴它的人可能甚至不会努力去理解它,而且他们