匕首和黄油刀与Android注释

我正在评估Android应用程序的dependency injection(DI)框架。 顶级竞争者是:匕首(与黄油刀)和Android注释。 我明白,匕首和黄油刀来自相同的来源广场,它们是相辅相成的。 这里是我正在寻找的关键matrix:

  1. 易于使用(我们的构build基于Gradle,我们使用Android Studio IDE)
  2. testing支持(我们使用Robotium进行functiontesting,使用RoboLectric进行unit testing)
  3. 性能(DI框架使用reflection,哪个更快?)

AndroidAnnotations
使用编译时注释处理。 它会生成一个带有下划线的子类,该子类被添加到原始名称(由MyActivity_生成的MyActivity )中。 所以为了使它工作,你总是必须使用生成的类来引用,而不是原来的类。

它具有非常丰富的function集,请参阅可用注释列表 。

牛油刀
也使用编译时间注释处理,但是它产生由中心类( ButterKnife )使用的查找器类。 这意味着您可以使用原始类进行引用,但必须手动调用注入。 来自ButterKnife的复制介绍:

 @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.simple_activity); ButterKnife.inject(this); // TODO Use "injected" views... } 

ButterKnife支持视图注入(AndroidAnnotations相当于@ViewById@ViewsById )和一些事件绑定(对于完整列表,请参阅这里的命名空间目录,只需计算OnXXX事件注释)。

匕首
是Android的DI实现,类似于Guice。 它还使用编译时注释处理并生成用于手动注入的对象图。 您可以区分应用程序对象图和范围对象图,以便在活动中注入。 在这里你可以看到一个Application.onCreate例子:

 @Override public void onCreate() { super.onCreate(); objectGraph = ObjectGraph.create(getModules().toArray()); objectGraph.inject(this); // use injected classes } 

我发现从匕首开始很难,但这可能只是我的经验。 不过请参阅这里的一些video以获得更好的开始: 1,2

从function设置的angular度来看,我会说Dagger实现了可以与AndroidAnnotation的@EBean@Beanfunction进行比较的function。

概要
如果您正在比较易用性,testing支持和性能,我无法find使用AndroidAnnotation和ButterKnife + Dagger的区别。 编程模型中的差异(使用_而不是使用原始模型的类并手动调用注入)和特征集中。

AndroidAnnotation为您提供了一个完整的function列表,但将您与某些库关联起来。 例如,如果你使用它的restAPI,你必须使用Spring的Android。 无论您是否使用OrmLite,您也可以使用OrmLite( @OrmLiteDao )等function的注释。

最后,至less在我看来,这是一个品味的问题。

这是Dzone博客中的好文章。

我们需要比较每个的特点,比如:

  • 最低瓶子要求
  • ActionBarSherlock兼容性
  • 注入点击听众
  • POJO注射
  • 性能

在这里输入图像说明

只有Pojo注射失败在butterknife! 所以看起来Butterknife是赢家!

资源

Google确实要求不要使用dependency injection。 但是通过阅读这些请求,他们可以更多地讨论基于guice /reflection的DI库。 诸如android注解之类的东西不使用reflection和完全编译时间生成的代码,而黄油刀和匕首则使用针对android优化的less量reflection。 但据说稍稍比android注释更强大。 这真的取决于这个项目,以及你愿意承担多less的业绩。 在我看来,使用黄油刀是很多加速自己的代码开发。 如果你需要更多的使用android注释。 最后如果你愿意采取一个轻微的performance,由于reflection最好的select,而不是绝对破坏性能与强大的基于guicereflection是匕首+黄油刀。

你应该试试牙签 。

牙签是(根据自述文件):

  • 纯java
  • 快,它不使用reflection而是注释处理
  • 简单,灵活,可扩展和function强大,强大和testing
  • 线程安全
  • logging和开源
  • 范围安全:它强制实施无泄露应用程序
  • 面向testing:它使testing更容易
  • 它适用于Android或任何其他基于上下文的框架(如Web容器)

它在大多数情况下甚至比Dagger 2更快,而且更简单。

注:是的,我是其中一位作者。

使用Android Annotations或Butterknife来简化您的编码。 但是不要去Roboguice! Roboguice强制你的活动,片段扩展到roboguice类。 一点都不好玩!

看起来像谷歌select匕首,因为他们正在与创造它的广场联合开发 。

关于Butterknife和Dagger本身,SO的问题在Dagger -and-butterknife-android之间有所区别 ,从而阐明了它们是如何相互补充的。

@ChrLipp提到的reddit-thread有一个人在同一个项目中使用了三个 ,高度评价了匕首+黄油刀,同时也给出了AndroidAnnotations的地方:

对于dependency injection来说,butterknife用于Views,Dagger用于所有对象,强烈推荐,Android Annotations创build更多的框架来开发Android,而不是注入对象到你的类中,因此每个库都是相当不同的。 匕首相当于Guice,但要快得多。 Dagger比ButterKnife和Android Annotations更强大,因为它注入所有对象,而不是ButterKnife和Android Annotations,它们只注入一组对象。

匕首可能是一个痛苦的设置和configuration,但一旦你完成它是非常值得的。 但是,再次,因为这些都是彼此不同的,这一切都取决于你的需求是什么样的项目。

另外,如果你真的想要的话,你可以在同一个项目中使用ButterKnife,Android Annotations和Dagger。 他们每个人都有相同的想法,但做一些不同的东西,所以你可以使用它们。

最终,如果你使用三者之一,你将很难转换到Android的数据绑定。 如果您需要考虑性能,这是最快的:

https://developer.android.com/tools/data-binding/guide.html

我认为(性能方面)ButterKnife和AndroidAnnotation之间的差距更大。 ButterKnife使用编译时注解(RetentionPolicy.CLASS),但它在运行时注入代码,导致更多的时间。 相反,AndroidAnnotations,在编译时处理所有注释。

为什么要打扰dependency injection?

之前还有人会问 – “但为什么我还要考虑DI? 人们说代码更干净,但是我的代码从来没有混乱过。“现在,当你回顾你前几天写的一个小型的业余爱好项目时,你可能不会做任何复杂的事情,这可能是真的,跳过unit testing,等等。 但现实是不同的。 使用dependency injection有很多东西,有些比其他的更明显。

在这里输入图像说明 查看所有Androiddependency injection库的完整比较

可测性

这个可能是我认为最重要的一个。 每当你正在编写unit testing时(你应该一直在写它们),你需要确保你正在testing你自己的代码,并且只能针对有问题的类。 你不想依赖于一些图书馆或另一个单独testing的类的逻辑。 你怎么做到这一点? 最好的方法是使用注入而不是真正的实现模拟。 毕竟,您不希望与外部第三方服务对话的课程的testing依赖于互联网连接和您正在收取的真实凭证。

代码和责任分离

基于我提到的testing,很明显,代码分离将自然发生。 这将允许您将代码拆分成一次负责一件事的较小块。 代码更小的块导致清洁,清洁导致可读性,可读性导致更less的错误。 通过这一切,我们提高了代码的可维护性。

可更换性和适应性

重构是任何开发项目的自然部分。 我们将开发将来需要修改的代码,甚至完全替代一些实现。 我们要做的越less越好。 在dependency injection的帮助下,您可以更轻松地调整代码,引入新的依赖关系,甚至完全更改它们。