Cara gagal secara menyedihkan dari migrasi Java ke Kotlin di aplikasi Android

Cara gagal secara menyedihkan dari migrasi Java ke Kotlin di aplikasi Android


Karena Google mengumumkan dukungan resmi untuk Kotlin di Android, semakin banyak pengembang ingin menggunakannya dalam proyek baru dan yang sudah ada. Karena saya juga penggemar berat Kotlin, saya tidak sabar untuk dapat menggunakan Kotlin dalam proyek kerja saya. Pada akhirnya, Kotlin sepenuhnya kompatibel dengan Java, dan semua pengembang senang dengannya. Jadi apa yang salah?


Sebenarnya banyak yang bisa salah. Saya hanya takut bahwa laman resmi Android Memulai dengan Kotlin mengatakan bahwa jika Anda ingin port aplikasi yang ada ke Kotlin, Anda hanya harus mulai menulis tes unit, dan kemudian, setelah sedikit pengalaman dengan bahasa ini, Anda harus tulis kode baru di Kotlin, dan kode Java yang ada mudah dikonversi.


Dalam artikel ini saya akan memberi tahu Anda apa yang akan terjadi jika saya memutuskan untuk segera mengikuti strategi ini pada prod, dan tidak mencobanya pada proyek kecil saya.


Temui proyek kecilku


Saya punya proyek yang saya buat lebih dari setahun yang lalu di Jawa, dan saya perlu mengubahnya sedikit dan menambahkan satu layar baru. Saya pikir ini adalah kesempatan bagus untuk memeriksa apakah migrasi proyek yang ada ke Kotlin benar-benar sangat sederhana, seperti yang dikatakan semua orang. Berdasarkan rekomendasi dari dokumentasi resmi, saya mulai dengan menulis tes unit di Kotlin. Saya juga menulis kelas baru di Kotlin dan mengonversi beberapa yang sudah ada. Segalanya tampak indah, tetapi setelah beberapa saat saya menemukan satu masalah yang tidak menyenangkan.


Kotlin + Lombok = :(


Dalam aplikasi saya, saya menggunakan perpustakaan Lombok untuk menghasilkan getter dan setter. Lombok adalah pengolah anotasi untuk javac. Sayangnya, kompiler kotlin menggunakan javac tanpa memproses anotasi [sumber] . Ini berarti bahwa metode yang dibuat dengan Lombok tidak akan tersedia di Kotlin:


Metode yang dibuat dengan Lombok tidak akan tersedia di Kotlin


Tetapi Anda dapat mengatakan: “Yah, itu tidak akan terlalu keren, tetapi pada prinsipnya, Anda dapat secara manual membuat getter dan setter untuk bidang-bidang yang akan diperlukan dalam kode Kotlin. Pada akhirnya, Anda tidak perlu melakukan ini di seluruh proyek segera. "


Saya berpikir dengan cara yang sama. Tapi saya mengalami masalah nyata ketika saya ingin menambahkan layar baru ke aplikasi.


Kotlin + Lombok + Dagger 2 =: (((


Aplikasi saya menggunakan Belati 2 untuk menyuntikkan dependensi. Saat membuat layar baru, saya biasanya membuat struktur MVP: Aktivitas, Presenter, Komponen, Modul dan Kontrak. Semua dependensi untuk presenter diimplementasikan menggunakan Belati. Aktivitas memanggil DaggerSomeComponent.builder().(...).build().inject(this) untuk menyuntikkan presenter dengan dependensi yang diperlukan.


Menggunakan Dagger 2 dengan Kotlin tidak ada masalah. Tepat sebelum itu, Anda perlu menerapkan plugin kapt , yang menciptakan kelas yang dibuat sendiri untuk Dagger.


Dan di sini semuanya mulai berantakan


Tanpa plugin kapt, saya tidak bisa menggunakan kelas Dagger yang dihasilkan dalam file Kotlin. Tetapi setelah saya menambahkan plugin ini, semua metode yang dibuat oleh Lombok menghilang!


Sebelum menerapkan plugin kapt :


Sebelum menerapkan plugin kapt


Setelah menerapkan plugin kapt :


Setelah menerapkan plugin kapt


Dan, sayangnya, tidak ada solusi untuk masalah ini. Anda dapat menggunakan hanya plugin kapt atau hanya Lombok . Untungnya, karena itu hanya proyek kecil saya, saya hanya menghapus Lombok dan menulis getter dan setters sendiri. Tetapi dalam proyek ini hanya ada sekitar 50 metode yang dihasilkan. Dalam proyek yang kami dukung di tempat kerja, kami memiliki sekitar seribu di antaranya . Menghapus Lombok dari aplikasi ini sama sekali tidak mungkin.


Juga, jelas bahwa melepaskan plugin kapt bukanlah jalan keluarnya. Tanpanya, Anda tidak dapat menggunakan Kotlin di kelas tempat belati digunakan. Dalam kasus saya, saya harus mengimplementasikan Kegiatan, Komponen dan Modul di Jawa, dan hanya Kontrak dan Presenter yang dapat ditulis di Kotlin. Mencampurkan file Java dan Kotlin jelas tidak bagus. Alih-alih transisi yang mulus dari Jawa ke Kotlin, Anda hanya akan membuat kekacauan besar.


Inilah yang akan menjadi struktur MVgl polyglot yang mengerikan ini tanpa plugin kapt:


Struktur polyglot MVP yang mengerikan tanpa plugin kapt


Tapi saya masih ingin beralih ke Kotlin. Apa yang harus saya lakukan


Salah satu caranya adalah dengan menggunakan modul yang berbeda . Kotlin tidak akan melihat metode yang akan dihasilkan Lombok dalam kode sumber, tetapi akan melihatnya dalam bytecode.


Secara pribadi, menurut saya ini adalah cara yang paling disukai. Jika Anda menempatkan Kotlin dalam modul dependen terpisah untuk setiap fitur, Anda mengurangi risiko masalah kompatibilitas yang saya temui, atau yang lebih kompleks yang tercantum dalam panduan resmi .


Dan itu belum semuanya. Ada banyak kelemahan lain untuk mencampur file Kotlin dan Java tanpa pemisahan yang jelas. Hal ini membuat semua pengembang yang bekerja dengan Anda dalam proyek ini mengetahui kedua bahasa. Ini juga mengurangi keterbacaan kode dan dapat menyebabkan peningkatan waktu pembuatan [sumber] .


Secara singkat


  • metode yang dihasilkan oleh Lombok tidak terlihat di Kotlin;
  • menggunakan plugin kapt memecah Lombok;
  • tanpa plugin kapt, Anda tidak dapat menggunakan kelas yang dibuat sendiri untuk Dagger di Kotlin, yang berarti Anda masih harus menulis kode Java baru;
  • cara untuk mengatasi masalah ini adalah dengan membawa Kotlin ke modul terpisah;
  • mencampurkan file Kotlin dan Java dalam proyek besar tanpa pemisahan yang jelas dapat menyebabkan masalah kompatibilitas yang tidak terduga.

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


All Articles