如何在Android应用程序中从Java迁移到Kotlin惨败

如何在Android应用程序中从Java迁移到Kotlin惨败


自Google宣布在Android上正式支持Kotlin以来,越来越多的开发人员希望在其新项目和现有项目中使用它。 由于我也是Kotlin的忠实拥护者,因此我迫不及待想要在我的工作项目中使用Kotlin。 最后,Kotlin与Java完全兼容,所有开发人员都对它感到满意。 那么怎么可能出问题了?


好吧,实际上很多地方都可能出错。 我只是害怕官方的Android Kotlin入门页面上说,如果要将现有应用程序移植到Kotlin,则只需要开始编写单元测试,然后,在对这种语言有一点经验之后,您应该用Kotlin编写新代码,并且现有Java代码易于转换。


在本文中,我将告诉您,如果我决定立即在产品上遵循此策略,而不是在我的小型项目中尝试该策略,将会发生什么。


满足我的小项目


我有一个一年多以前用Java创建的项目,我需要对其进行一些更改并添加一个新屏幕。 我认为这是一个很好的机会,可以检查每个人都说,将现有项目迁移到Kotlin是否真的非常简单。 根据官方文档的建议,我首先在Kotlin上编写单元测试。 我还用Kotlin编写了新的类,并转换了一些现有的类。 一切似乎都很棒,但是过了一会儿我发现了一个不愉快的问题。


Kotlin +龙目岛= :(


在我的应用程序中,我使用了Lombok库来生成getter和setter。 Lombok是Javac的注释处理器。 不幸的是,kotlin编译器使用javac而不处理注释[source] 。 这意味着用Lombok创建的方法将在Kotlin中不可用:


用Lombok创建的方法在Kotlin中不可用


但是您可以说:“嗯,这不会很酷,但是原则上,您可以为Kotlin代码中所需的那些字段手动创建吸气剂和吸气剂。 最后,您不需要立即在整个项目中都这样做。”


我也是这么想的 但是,当我想向应用程序添加新屏幕时遇到了一个真正的问题。


科特林+龙目岛+匕首2 =:(((


我的应用程序使用Dagger 2注入依赖项。 创建新屏幕时,通常会创建一个MVP结构:活动,演示者,组件,模块和合同。 演示者的所有依赖关系都使用Dagger实现。 活动调用DaggerSomeComponent.builder().(...).build().inject(this)以向演示者注入必要的依赖项。


与Kotlin一起使用Dagger 2没问题。 在此之前,您需要应用kapt插件 ,该插件为Dagger创建必要的自生成类。


在这里,一切开始崩溃


没有kapt插件,我将无法在Kotlin文件中使用生成的Dagger类。 但是添加完该插件后,Lombok创建的所有方法都消失了!


在应用kapt插件之前:


在应用kapt插件之前


应用kapt插件后


应用kapt插件后


并且,不幸的是,没有解决该问题的方法。 您只能使用kapt-plugin或仅使用Lombok 。 幸运的是,由于这只是我的小项目,所以我删除了Lombok,并亲自编写了吸气剂和吸气剂。 但是在这个项目中,只有大约50种生成的方法。 在我们工作中支持的项目中,我们有大约一千个 。 从该应用程序中删除Lombok根本不可能。


此外,很明显,放弃kapt插件并不是出路。 没有它,您将无法在使用Dagger的类中使用Kotlin。 就我而言,我将不得不用Java实现Activity,Component和Module,并且只能用Kotlin编写Contract和Presenter。 混合Java和Kotlin文件绝对不是很好。 与其从Java到Kotlin的平稳过渡,不如简单地创建一个大混乱。


如果没有kapt插件,这就是可怕的多语言MVP结构:


没有kapt插件的可怕的多语言MVP结构


但是我仍然想切换到Kotlin。 我该怎么办?


一种方法是使用不同的模块 。 Kotlin将不会在源代码中看到Lombok会生成的方法,但是会在字节码中看到它们。


就我个人而言,这似乎是最可取的方式。 如果将Kotlin的每个功能放在单独的相关模块中,则可以降低发生此类兼容性问题或在官方指南中列出的更复杂问题的风险。


不仅如此。 如果没有明确分开,混合Kotlin和Java文件还有许多其他缺点。 这使与您一起工作的所有开发人员都知道两种语言。 它还会降低代码的可读性,并可能导致构建时间增加。


简要地


  • Lombok生成的方法在Kotlin中不可见;
  • 使用kapt插件会破坏Lombok;
  • 如果没有kapt插件,则无法在Kotlin中使用Dagger的自生成类,这意味着您仍然必须编写新的Java代码;
  • 解决此问题的一种方法是将Kotlin放入单独的模块中;
  • 在没有明确区分的情况下将Kotlin和Java文件混合在大型项目中可能会导致意外的兼容性问题。

Source: https://habr.com/ru/post/zh-CN421871/


All Articles