Como falhar miseravelmente da migração de Java para Kotlin em um aplicativo Android

Como falhar miseravelmente da migração de Java para Kotlin em um aplicativo Android


Desde que o Google anunciou o suporte oficial ao Kotlin no Android, mais e mais desenvolvedores desejam usá-lo em seus projetos novos e existentes. Como também sou um grande fã do Kotlin, eu mal podia esperar para poder usar o Kotlin no meu projeto de trabalho. No final, o Kotlin é totalmente compatível com Java, e todos os desenvolvedores estão satisfeitos com isso. Então, o que poderia dar errado?


Bem, na verdade muita coisa pode dar errado. Só estou com medo de que a página oficial da documentação do Android "Introdução ao Kotlin" diga que se você deseja transferir um aplicativo existente para o Kotlin, comece a escrever testes de unidade e, depois de um pouco de experiência com esse idioma, escreva um novo código no Kotlin, e o código Java existente é fácil de converter.


Neste artigo, vou lhe dizer o que aconteceria se eu decidisse seguir imediatamente essa estratégia no produto e não experimentá-lo no meu pequeno projeto.


Conheça meu pequeno projeto


Eu tinha um projeto que criei há mais de um ano em Java e precisava alterá-lo um pouco e adicionar uma nova tela. Eu pensei que era uma ótima oportunidade para verificar se a migração de um projeto existente para o Kotlin é realmente muito simples, como todos dizem. Com base nas recomendações da documentação oficial, comecei escrevendo testes de unidade no Kotlin. Também escrevi novas aulas no Kotlin e converti algumas já existentes. Tudo parecia maravilhoso, mas depois de um tempo descobri um problema desagradável.


Kotlin + Lombok = :(


No meu aplicativo, usei a biblioteca Lombok para gerar getters e setters. Lombok é um processador de anotação para javac. Infelizmente, o compilador kotlin usa javac sem processar anotações [fonte] . Isso significa que os métodos criados com o Lombok não estarão disponíveis no Kotlin:


Métodos criados com Lombok não estarão disponíveis no Kotlin


Mas você pode dizer: “Bem, não será muito legal, mas, em princípio, você pode criar manualmente getters e setters para os campos que serão necessários no código Kotlin. No final, você não precisa fazer isso em todo o projeto imediatamente. "


Eu pensei da mesma maneira. Mas encontrei um problema real quando quis adicionar uma nova tela ao aplicativo.


Kotlin + Lombok + Adaga 2 =: ((((


Meu aplicativo usa o Dagger 2 para injetar dependências. Ao criar uma nova tela, geralmente crio uma estrutura MVP: Atividade, Apresentador, Componente, Módulo e Contrato. Todas as dependências para o apresentador são implementadas usando o Dagger. A atividade chama DaggerSomeComponent.builder().(...).build().inject(this) para injetar no apresentador as dependências necessárias.


Usar o Dagger 2 com Kotlin não é problema. Antes disso, você precisa aplicar o plugin kapt , que cria as classes auto-geradas necessárias para o Dagger.


E aqui tudo começa a desmoronar


Sem o plugin kapt, eu não poderia usar as classes Dagger geradas nos arquivos Kotlin. Mas depois que adicionei este plugin, todos os métodos criados por Lombok desapareceram!


Antes de aplicar o plugin kapt :


Antes de aplicar o plugin kapt


Após aplicar o plugin kapt :


Depois de aplicar o plugin kapt


E, infelizmente, não há solução para esse problema. Você pode usar apenas o kapt-plugin ou apenas o Lombok . Felizmente, como era apenas meu pequeno projeto, simplesmente excluí Lombok e escrevi os getters e setters. Mas neste projeto, havia apenas cerca de 50 métodos gerados. No projeto que apoiamos no trabalho, temos cerca de mil deles . Remover Lombok deste aplicativo simplesmente não é possível.


Além disso, é óbvio que desistir do plugin kapt não é a saída. Sem ele, você não pode usar o Kotlin nas classes em que o Dagger é usado. No meu caso, eu precisaria implementar Activity, Component e Module em Java, e apenas Contract e Presenter poderiam ser escritos em Kotlin. A mistura de arquivos Java e Kotlin definitivamente não é ótima. Em vez de uma transição suave do Java para o Kotlin, você simplesmente criaria uma grande bagunça.


É assim que esta terrível estrutura poliglota do MVP seria sem o plugin kapt:


Estrutura MVP poliglota horrível sem o plugin kapt


Mas ainda quero mudar para Kotlin. O que eu faço?


Uma maneira é usar módulos diferentes . O Kotlin não verá os métodos que o Lombok irá gerar no código fonte, mas os verá no bytecode.


Pessoalmente, parece-me que esta é a maneira mais preferida. Se você colocar o Kotlin em módulos dependentes separados para cada recurso, reduzirá o risco de problemas de compatibilidade que eu encontrei, ou mais complexos listados no guia oficial .


E isso não é tudo. Existem muitas outras desvantagens em misturar arquivos Kotlin e Java sem uma separação clara. Isso faz com que todos os desenvolvedores que trabalham com você no projeto conheçam os dois idiomas. Também reduz a legibilidade do código e pode levar a um aumento no tempo de compilação [origem] .


Brevemente


  • métodos gerados por Lombok não são visíveis no Kotlin;
  • o uso do plugin kapt quebra o Lombok;
  • sem um plug-in kapt, você não pode usar classes auto-geradas para o Dagger no Kotlin, o que significa que você ainda precisa escrever um novo código Java;
  • uma maneira de resolver esse problema é trazer o Kotlin em módulos separados;
  • misturar arquivos Kotlin e Java em grandes projetos sem uma separação clara pode levar a problemas inesperados de compatibilidade.

Source: https://habr.com/ru/post/pt421871/


All Articles