Pengantar Kotlin: Pemrograman Android Untuk Manusia

Diterbitkan: 2022-03-11

Dalam dunia Android yang sempurna, bahasa utama Java benar-benar modern, jelas, dan elegan. Anda dapat menulis lebih sedikit dengan melakukan lebih banyak, dan setiap kali fitur baru muncul, pengembang dapat menggunakannya hanya dengan meningkatkan versi di Gradle. Kemudian saat membuat aplikasi yang sangat bagus, aplikasi tersebut tampak sepenuhnya dapat diuji, dapat diperluas, dan dapat dipelihara. Aktivitas kami tidak terlalu besar dan rumit, kami dapat mengubah sumber data dari database ke web tanpa banyak perbedaan, dan sebagainya. Kedengarannya bagus, bukan? Sayangnya, dunia Android tidak seideal ini. Google masih berjuang untuk kesempurnaan, tetapi kita semua tahu bahwa dunia yang ideal tidak ada. Jadi, kita harus membantu diri kita sendiri dalam perjalanan hebat di dunia Android.

Apa Itu Kotlin, dan Mengapa Anda Harus Menggunakannya?

Jadi, bahasa pertama. Saya pikir Java bukanlah penguasa keanggunan atau kejelasan, dan itu tidak modern atau ekspresif (dan saya kira Anda setuju). Kekurangannya adalah di bawah Android N, kami masih terbatas pada Java 6 (termasuk beberapa bagian kecil dari Java 7). Pengembang juga dapat melampirkan RetroLambda untuk menggunakan ekspresi lambda dalam kode mereka, yang sangat berguna saat menggunakan RxJava. Di atas Android N, kita dapat menggunakan beberapa fungsi baru Java 8, tetapi itu masih Java yang lama dan berat. Sangat sering saya mendengar pengembang Android mengatakan "Saya berharap Android mendukung bahasa yang lebih baik, seperti yang dilakukan iOS dengan Swift". Dan bagaimana jika saya memberi tahu Anda bahwa Anda dapat menggunakan bahasa yang sangat bagus dan sederhana, dengan keamanan nol, lambda, dan banyak fitur baru yang bagus lainnya? Selamat datang di Kotlin.

Apa itu Kotlin?

Kotlin adalah bahasa baru (terkadang disebut sebagai Swift untuk Android), yang dikembangkan oleh tim JetBrains, dan sekarang dalam versi 1.0.2. Apa yang membuatnya berguna dalam pengembangan Android adalah ia dikompilasi ke bytecode JVM, dan juga dapat dikompilasi ke JavaScript. Ini sepenuhnya kompatibel dengan Java, dan kode Kotlin dapat dengan mudah dikonversi ke kode Java dan sebaliknya (ada plugin dari JetBrains). Itu berarti Kotlin dapat menggunakan kerangka kerja, pustaka, dll. yang ditulis dalam Java. Di Android, ini terintegrasi oleh Gradle. Jika Anda sudah memiliki aplikasi Android dan ingin menerapkan fitur baru di Kotlin tanpa menulis ulang seluruh aplikasi, cukup mulai menulis di Kotlin, dan itu akan berhasil.

Tapi apa 'fitur baru yang hebat'? Biarkan saya daftar beberapa:

Parameter Fungsi Opsional dan Bernama

 fun createDate(day: Int, month: Int, year: Int, hour: Int = 0, minute: Int = 0, second: Int = 0) { print("TEST", "$day-$month-$year $hour:$minute:$second") }

Kami Dapat Memanggil Metode createDate dengan Cara Berbeda

 createDate(1,2,2016) prints: '1-2-2016 0:0:0' createDate(1,2,2016, 12) prints: '1-2-2016 12:0:0' createDate(1,2,2016, minute = 30) prints: '1-2-2016 0:30:0'

Keamanan Nol

Jika sebuah variabel bisa nol, kode tidak akan dikompilasi kecuali kita memaksanya untuk membuatnya. Kode berikut akan memiliki kesalahan - nullableVar mungkin nol:

 var nullableVar: String? = “”; nullableVar.length;

Untuk mengkompilasi, kita harus memeriksa apakah itu bukan null:

 if(nullableVar){ nullableVar.length }

Atau, lebih pendek:

 nullableVar?.length

Dengan cara ini, jika nullableVar adalah null, tidak ada yang terjadi. Jika tidak, kita dapat menandai variabel sebagai tidak dapat dibatalkan, tanpa tanda tanya setelah mengetik:

 var nonNullableVar: String = “”; nonNullableVar.length;

Kode ini dikompilasi, dan jika kita ingin menetapkan null ke nonNullableVar, compiler akan menampilkan kesalahan.

Ada juga operator Elvis yang sangat berguna:

 var stringLength = nullableVar?.length ?: 0

Kemudian, ketika nullableVar adalah null (jadi nullableVar?.length mengembalikan null), stringLength akan memiliki nilai 0.

Variabel yang Dapat Diubah dan Tidak Dapat Diubah

Pada contoh di atas, saya menggunakan var ketika mendefinisikan sebuah variabel. Ini bisa berubah, kita dapat menetapkannya kembali kapan pun kita mau. Jika kita ingin variabel itu tidak berubah (dalam banyak kasus kita harus melakukannya), kita menggunakan val (sebagai nilai, bukan variabel):

 val immutable: Int = 1

Setelah itu, kompiler tidak akan mengizinkan kami untuk menetapkan kembali ke yang tidak dapat diubah.

lambda

Kita semua tahu apa itu lambda, jadi di sini saya hanya akan menunjukkan bagaimana kita bisa menggunakannya di Kotlin:

 button.setOnClickListener({ view -> Log.d("Kotlin","Click")})

Atau jika fungsinya adalah satu-satunya atau argumen terakhir:

 button.setOnClickListener { Log.d("Kotlin","Click")}

Ekstensi

Ekstensi adalah fitur bahasa yang sangat membantu, berkat itu kami dapat "memperluas" kelas yang ada, bahkan ketika kelas tersebut final atau kami tidak memiliki akses ke kode sumbernya.

Misalnya, untuk mendapatkan nilai string dari teks edit, alih-alih menulis setiap kali editText.text.toString() kita dapat menulis fungsi:

 fun EditText.textValue(): String{ return text.toString() }

Atau lebih pendek:

 fun EditText.textValue() = text.toString()

Dan sekarang, dengan setiap instance EditText:

 editText.textValue()

Atau, kita dapat menambahkan properti yang mengembalikan hal yang sama:

 var EditText.textValue: String get() = text.toString() set(v) {setText(v)}

Kelebihan Beban Operator

Terkadang berguna jika kita ingin menambah, mengalikan, atau membandingkan objek. Kotlin memungkinkan overloading operator biner (plus, minus, plusAssign, range, dll), operator array ( get, set, get range, set range), dan operasi equals dan unary (+a, -a, dll.)

Kelas Data

Berapa banyak baris kode yang Anda perlukan untuk mengimplementasikan kelas User di Java dengan tiga properti: copy, equals, hashCode, dan toString? Di Kaotlin Anda hanya perlu satu baris:

 data class User(val name: String, val surname: String, val age: Int)

Kelas data ini menyediakan metode equals(), hashCode() dan copy(), dan juga toString(), yang mencetak User sebagai:

 User(name=John, surname=Doe, age=23)

Kelas data juga menyediakan beberapa fungsi dan properti berguna lainnya, yang dapat Anda lihat di dokumentasi Kotlin.

Ekstensi Anko

Anda menggunakan ekstensi Butterknife atau Android, bukan? Bagaimana jika Anda bahkan tidak perlu menggunakan perpustakaan ini, dan setelah mendeklarasikan tampilan dalam XML, gunakan saja dari kode dengan ID-nya (seperti dengan XAML di C#):

 <Button android: android:layout_width="match_parent" android:layout_height="wrap_content" />
 loginBtn.setOnClickListener{}

Kotlin memiliki ekstensi Anko yang sangat berguna, dan dengan ini Anda tidak perlu memberi tahu aktivitas Anda apa itu loginBtn, ia mengetahuinya hanya dengan "mengimpor" xml:

 import kotlinx.android.synthetic.main.activity_main.*

Ada banyak hal berguna lainnya di Anko, termasuk memulai aktivitas, bersulang, dan sebagainya. Ini bukan tujuan utama Anko - ini dirancang untuk membuat tata letak dari kode dengan mudah. Jadi jika Anda perlu membuat tata letak secara terprogram, ini adalah cara terbaik.

Ini hanya pandangan singkat tentang Kotlin. Saya sarankan membaca blog Antonio Leiva dan bukunya - Kotlin untuk Pengembang Android, dan tentu saja situs resmi Kotlin.

Apa itu MVP dan Mengapa?

Bahasa yang bagus, kuat, dan jelas tidak cukup. Sangat mudah untuk menulis aplikasi yang berantakan dengan setiap bahasa tanpa arsitektur yang baik. Pengembang Android (kebanyakan yang baru memulai, tetapi juga yang lebih mahir) sering kali memberikan tanggung jawab Aktivitas untuk segala sesuatu di sekitar mereka. Aktivitas (atau Fragmen, atau tampilan lain) mengunduh data, mengirim untuk menyimpan, menyajikannya, merespons interaksi pengguna, mengedit data, mengelola semua tampilan anak . . . dan sering lebih banyak lagi. Terlalu banyak untuk objek yang tidak stabil seperti Aktivitas atau Fragmen (cukup untuk memutar layar dan Aktivitas mengatakan 'Selamat tinggal….').

Ide yang sangat bagus adalah memisahkan tanggung jawab dari pandangan dan membuatnya sebodoh mungkin. Tampilan (Aktivitas, Fragmen, tampilan kustom, atau apa pun yang menyajikan data di layar) seharusnya hanya bertanggung jawab untuk mengelola subview mereka. Tampilan harus memiliki penyaji, yang akan berkomunikasi dengan model, dan memberi tahu mereka apa yang harus mereka lakukan. Singkatnya, ini adalah pola Model-View-Presenter (bagi saya, ini harus dinamai Model-Presenter-View untuk menunjukkan koneksi antar lapisan).

MVC vs MVP

"Hei, aku tahu sesuatu seperti itu, dan itu disebut MVC!" - tidakkah menurutmu? Tidak, MVP tidak sama dengan MVC. Dalam pola MVC, tampilan Anda dapat berkomunikasi dengan model. Saat menggunakan MVP, Anda tidak mengizinkan komunikasi apa pun antara dua lapisan ini - satu-satunya cara View dapat berkomunikasi dengan Model adalah melalui Presenter. Satu-satunya hal yang View ketahui tentang Model adalah struktur datanya. Lihat tahu bagaimana, misalnya, menampilkan Pengguna, tetapi tidak tahu kapan. Berikut ini contoh sederhana:

Lihat tahu “Saya Aktivitas, saya memiliki dua EditTexts dan satu Tombol. Ketika seseorang mengklik tombol, saya harus memberitahukannya kepada presenter saya, dan memberikan nilai EditTexts kepadanya. Dan itu saja, saya bisa tidur sampai klik berikutnya atau presenter memberi tahu saya apa yang harus saya lakukan.”

Presenter tahu bahwa di suatu tempat adalah View, dan dia tahu operasi apa yang bisa dilakukan View ini. Dia juga tahu bahwa ketika dia menerima dua string, dia harus membuat Pengguna dari dua string ini dan mengirim data ke model untuk disimpan, dan jika penyimpanan berhasil, beri tahu tampilan 'Tampilkan info sukses'.

Model hanya mengetahui di mana data berada, di mana harus disimpan, dan operasi apa yang harus dilakukan pada data tersebut.

Aplikasi yang ditulis dalam MVP mudah untuk diuji, dipelihara, dan digunakan kembali. Seorang presenter murni seharusnya tidak tahu apa-apa tentang platform Android. Itu harus kelas Java (atau Kotlin, dalam kasus kami) murni. Berkat ini, kami dapat menggunakan kembali presenter kami di proyek lain. Kami juga dapat dengan mudah menulis unit test, menguji Model, View, dan Presenter secara terpisah.

Pola MVP mengarah ke basis kode yang lebih baik dan tidak terlalu rumit dengan menjaga antarmuka pengguna dan logika bisnis benar-benar terpisah.

Sedikit penyimpangan: MVP harus menjadi bagian dari Arsitektur Bersih Paman Bob untuk membuat aplikasi lebih fleksibel dan berarsitektur bagus. Saya akan mencoba menulis tentang itu lain kali.

Contoh Aplikasi dengan MVP dan Kotlin

Sudah cukup teorinya, mari kita lihat beberapa kodenya! Oke, mari kita coba membuat aplikasi sederhana. Tujuan utama aplikasi ini adalah untuk membuat pengguna. Layar pertama akan memiliki dua EditText (Nama dan Nama Keluarga) dan satu Tombol (Simpan). Setelah memasukkan nama dan nama keluarga dan mengklik 'Simpan', aplikasi akan menampilkan 'Pengguna disimpan' dan pergi ke layar berikutnya, di mana nama dan nama keluarga yang disimpan disajikan. Saat nama atau nama keluarga kosong, aplikasi tidak akan menyimpan pengguna dan menampilkan kesalahan yang menunjukkan apa yang salah.

Hal pertama setelah membuat proyek Android Studio adalah mengonfigurasi Kotlin. Anda harus menginstal plugin Kotlin, dan, setelah restart, di Tools > Kotlin Anda dapat mengklik 'Configure Kotlin in Project'. IDE akan menambahkan dependensi Kotlin ke Gradle. Jika Anda memiliki kode yang ada, Anda dapat dengan mudah mengonversinya ke Kotlin dengan (Ctrl+Shift+Alt+K atau Code > Convert Java file to Kotlin). Jika ada yang salah dan proyek tidak dapat dikompilasi, atau Gradle tidak melihat Kotlin, Anda dapat memeriksa kode aplikasi yang tersedia di GitHub.

Kotlin tidak hanya beroperasi dengan baik dengan framework dan library Java, tetapi juga memungkinkan Anda untuk terus menggunakan sebagian besar alat yang sama yang sudah Anda kenal.

Sekarang kita memiliki sebuah proyek, mari kita mulai dengan membuat tampilan pertama kita - CreateUserView. Tampilan ini harus memiliki fungsi yang disebutkan sebelumnya, sehingga kita dapat menulis antarmuka untuk itu:

 interface CreateUserView : View { fun showEmptyNameError() /* show error when name is empty */ fun showEmptySurnameError() /* show error when surname is empty */ fun showUserSaved() /* show user saved info */ fun showUserDetails(user: User) /* show user details */ }

Seperti yang Anda lihat, Kotlin mirip dengan Java dalam mendeklarasikan fungsi. Semua itu adalah fungsi yang tidak menghasilkan apa-apa, dan yang terakhir memiliki satu parameter. Inilah perbedaannya, tipe parameter muncul setelah nama. Antarmuka Tampilan bukan dari Android - ini adalah antarmuka kami yang sederhana dan kosong:

 interface View

Antarmuka Basic Presenter harus memiliki properti tipe View, dan setidaknya pada metode (onDestroy misalnya), di mana properti ini akan disetel ke nol:

 interface Presenter<T : View> { var view: T? fun onDestroy(){ view = null } }

Di sini Anda dapat melihat fitur Kotlin lainnya - Anda dapat mendeklarasikan properti di antarmuka, dan juga mengimplementasikan metode di sana.

CreateUserView kami perlu berkomunikasi dengan CreateUserPresenter. Satu-satunya fungsi tambahan yang dibutuhkan Presenter ini adalah saveUser dengan dua argumen string:

 interface CreateUserPresenter<T : View>: Presenter<T> { fun saveUser(name: String, surname: String) }

Kami juga membutuhkan definisi Model - disebutkan kelas data sebelumnya:

 data class User(val name: String, val surname: String)

Setelah mendeklarasikan semua antarmuka, kita dapat mulai mengimplementasikan.

CreateUserPresenter akan diimplementasikan di CreateUserPresenterImpl:

 class CreateUserPresenterImpl(override var view: CreateUserView?): CreateUserPresenter<CreateUserView> { override fun saveUser(name: String, surname: String) { } }

Baris pertama, dengan definisi kelas:

 CreateUserPresenterImpl(override var view: CreateUserView?)

Adalah konstruktor, kami menggunakannya untuk menetapkan properti tampilan, yang ditentukan dalam antarmuka.

MainActivity, yang merupakan implementasi CreateUserView kami, memerlukan referensi ke CreateUserPresenter:

 class MainActivity : AppCompatActivity(), CreateUserView { private val presenter: CreateUserPresenter<CreateUserView> by lazy { CreateUserPresenterImpl(this) } override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) saveUserBtn.setOnClickListener{ presenter.saveUser(userName.textValue(), userSurname.textValue()) /*use of textValue() extension, mentioned earlier */ } } override fun showEmptyNameError() { userName.error = getString(R.string.name_empty_error) /* it's equal to userName.setError() - Kotlin allows us to use property */ } override fun showEmptySurnameError() { userSurname.error = getString(R.string.surname_empty_error) } override fun showUserSaved() { toast(R.string.user_saved) /* anko extension - equal to Toast.makeText(this, R.string.user_saved, Toast.LENGTH_LONG) */ } override fun showUserDetails(user: User) { } override fun onDestroy() { presenter.onDestroy() } }

Di awal kelas, kami mendefinisikan presenter kami:

 private val presenter: CreateUserPresenter<CreateUserView> by lazy { CreateUserPresenterImpl(this) }

Ini didefinisikan sebagai tidak dapat diubah (val), dan dibuat oleh delegasi malas, yang akan ditetapkan saat pertama kali dibutuhkan. Selain itu, kami yakin itu tidak akan nol (tidak ada tanda tanya setelah definisi).

Ketika Pengguna mengklik tombol Simpan, View mengirimkan informasi ke Presenter dengan nilai EditTexts. Ketika itu terjadi, Pengguna harus disimpan, jadi kita harus menerapkan metode saveUser di Presenter (dan beberapa fungsi Model):

 override fun saveUser(name: String, surname: String) { val user = User(name, surname) when(UserValidator.validateUser(user)){ UserError.EMPTY_NAME -> view?.showEmptyNameError() UserError.EMPTY_SURNAME -> view?.showEmptySurnameError() UserError.NO_ERROR -> { UserStore.saveUser(user) view?.showUserSaved() view?.showUserDetails(user) } } }

Ketika Pengguna dibuat, itu dikirim ke UserValidator untuk memeriksa validitasnya. Kemudian, sesuai dengan hasil validasi, metode yang tepat disebut. Konstruksi when() {} sama dengan switch/case di Java. Tetapi ini lebih kuat - Kotlin memungkinkan penggunaan tidak hanya enum atau int dalam 'case', tetapi juga rentang, string, atau tipe objek. Itu harus mengandung semua kemungkinan atau memiliki ekspresi lain. Di sini, ini mencakup semua nilai UserError.

Dengan menggunakan view?.showEmptyNameError() (dengan tanda tanya setelah view), kita terlindungi dari NullPointer. Tampilan dapat dibatalkan dalam metode onDestroy, dan dengan konstruksi ini, tidak akan terjadi apa-apa.

Ketika model Pengguna tidak memiliki kesalahan, ia memberitahu UserStore untuk menyimpannya, dan kemudian menginstruksikan View untuk menunjukkan keberhasilan dan menampilkan detail.

Seperti disebutkan sebelumnya, kita harus mengimplementasikan beberapa hal model:

 enum class UserError { EMPTY_NAME, EMPTY_SURNAME, NO_ERROR } object UserStore { fun saveUser(user: User){ //Save user somewhere: Database, SharedPreferences, send to web... } } object UserValidator { fun validateUser(user: User): UserError { with(user){ if(name.isNullOrEmpty()) return UserError.EMPTY_NAME if(surname.isNullOrEmpty()) return UserError.EMPTY_SURNAME } return UserError.NO_ERROR } }

Hal yang paling menarik di sini adalah UserValidator. Dengan menggunakan kata objek, kita dapat membuat kelas tunggal, tanpa khawatir tentang utas, konstruktor pribadi, dan sebagainya.

Hal berikutnya - dalam metode validationUser(user), ada ekspresi with(user) {}. Kode dalam blok tersebut dieksekusi dalam konteks objek, diteruskan dengan nama dan nama keluarga adalah properti Pengguna.

Ada juga hal kecil lainnya. Semua kode di atas, dari enum hingga UserValidator, definisi ditempatkan dalam satu file (definisi kelas Pengguna juga ada di sini). Kotlin tidak memaksa Anda untuk memiliki setiap kelas publik dalam satu file (atau memberi nama kelas persis seperti file). Jadi, jika Anda memiliki beberapa bagian pendek dari kode terkait (kelas data, ekstensi, fungsi, konstanta - Kotlin tidak memerlukan kelas untuk fungsi atau konstanta), Anda dapat menempatkannya dalam satu file tunggal alih-alih menyebar ke semua file dalam proyek.

Saat pengguna disimpan, aplikasi kita akan menampilkannya. Kami membutuhkan Tampilan lain - bisa berupa tampilan Android, Tampilan kustom, Fragmen, atau Aktivitas apa pun. Saya memilih Aktivitas.

Jadi, mari kita definisikan antarmuka UserDetailsView. Itu dapat menunjukkan pengguna, tetapi juga harus menunjukkan kesalahan saat pengguna tidak ada:

 interface UserDetailsView { fun showUserDetails(user: User) fun showNoUserError() }

Selanjutnya, UserDetailsPresenter. Itu harus memiliki properti pengguna:

 interface UserDetailsPresenter<T: View>: Presenter<T> { var user: User? }

Antarmuka ini akan diimplementasikan di UserDetailsPresenterImpl. Itu harus menimpa properti pengguna. Setiap kali properti ini ditetapkan, pengguna harus di-refresh pada tampilan. Kita dapat menggunakan properti setter untuk ini:

 class UserDetailsPresenterImpl(override var view: UserDetailsView?): UserDetailsPresenter<UserDetailsView> { override var user: User? = null set(value) { field = value if(field != null){ view?.showUserDetails(field!!) } else { view?.showNoUserError() } } }

Implementasi UserDetailsView, UserDetailsActivity, sangat sederhana. Sama seperti sebelumnya, kita memiliki objek presenter yang dibuat dengan lazy loading. Pengguna yang akan ditampilkan harus diteruskan melalui maksud. Ada satu masalah kecil dengan ini untuk saat ini, dan kami akan menyelesaikannya sebentar lagi. Saat kami memiliki pengguna dari maksud, View perlu menetapkannya ke penyaji mereka. Setelah itu, pengguna akan disegarkan di layar, atau, jika nol, kesalahan akan muncul (dan aktivitas akan selesai - tetapi penyaji tidak mengetahuinya):

 class UserDetailsActivity: AppCompatActivity(), UserDetailsView { private val presenter: UserDetailsPresenter<UserDetailsView> by lazy { UserDetailsPresenterImpl(this) } override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_user_details) val user = intent.getParcelableExtra<User>(USER_KEY) presenter.user = user } override fun showUserDetails(user: User) { userFullName.text = "${user.name} ${user.surname}" } override fun showNoUserError() { toast(R.string.no_user_error) finish() } override fun onDestroy() { presenter.onDestroy() } }

Melewati objek melalui maksud mengharuskan objek ini mengimplementasikan antarmuka Parcelable. Ini pekerjaan yang sangat 'kotor'. Secara pribadi, saya benci melakukan ini karena semua PENCIPTA, properti, menyimpan, memulihkan, dan sebagainya. Untungnya, ada plugin yang tepat, Parcelable untuk Kotlin. Setelah menginstalnya, kita dapat menghasilkan Parcelable hanya dengan satu klik.

Hal terakhir yang harus dilakukan adalah mengimplementasikan showUserDetails(user: User) di MainActivity kami:

 override fun showUserDetails(user: User) { startActivity<UserDetailsActivity>(USER_KEY to user) /* anko extension - starts UserDetailsActivity and pass user as USER_KEY in intent */ }

Dan itu saja.

Demo aplikasi Android di Kotlin

Kami memiliki aplikasi sederhana yang menyimpan Pengguna (sebenarnya, itu tidak disimpan, tetapi kami dapat menambahkan fungsi ini tanpa menyentuh penyaji atau tampilan) dan menyajikannya di layar. Di masa mendatang, jika kita ingin mengubah cara pengguna ditampilkan di layar, seperti dari dua aktivitas menjadi dua fragmen dalam satu aktivitas, atau dua tampilan kustom, perubahan hanya akan dilakukan di kelas Tampilan. Tentu saja, jika kita tidak mengubah fungsionalitas atau struktur model. Presenter, yang tidak tahu persis apa itu View, tidak memerlukan perubahan apa pun.

Mengalami masalah kinerja di aplikasi Android Anda? Lihat tips dan teknik pengoptimalan ini.

Apa berikutnya?

Di aplikasi kami, Presenter dibuat setiap kali aktivitas dibuat. Pendekatan ini, atau kebalikannya, jika Presenter harus bertahan di seluruh instance aktivitas, adalah subjek dari banyak diskusi di Internet. Bagi saya, itu tergantung pada aplikasi, kebutuhannya, dan pengembangnya. Terkadang lebih baik menghancurkan presenter, terkadang tidak. Jika Anda memutuskan untuk mempertahankannya, teknik yang sangat menarik adalah menggunakan LoaderManager untuk itu.

Seperti disebutkan sebelumnya, MVP harus menjadi bagian dari arsitektur Clean Uncle Bob. Selain itu, pengembang yang baik harus menggunakan Dagger untuk menyuntikkan dependensi presenter ke aktivitas. Ini juga membantu memelihara, menguji, dan menggunakan kembali kode di masa mendatang. Saat ini, Kotlin bekerja sangat baik dengan Dagger (sebelum rilis resmi tidak begitu mudah), dan juga dengan library Android bermanfaat lainnya.

Bungkus

Bagi saya, Kotlin adalah bahasa yang hebat. Ini modern, jelas, dan ekspresif sementara masih dikembangkan oleh orang-orang hebat. Dan kami dapat menggunakan rilis baru apa pun di perangkat dan versi Android apa pun. Apa pun yang membuat saya marah di Java, Kotlin meningkat.

Tentu saja, seperti yang saya katakan tidak ada yang ideal. Kotlin juga memiliki beberapa kelemahan. Versi plugin gradle terbaru (terutama dari alfa atau beta) tidak berfungsi dengan baik dengan bahasa ini. Banyak orang mengeluh bahwa waktu pembuatan sedikit lebih lama daripada Java murni, dan apk memiliki beberapa MB tambahan. Namun Android Studio dan Gradle masih terus berkembang, dan ponsel memiliki lebih banyak ruang untuk aplikasi. Itu sebabnya saya percaya Kotlin bisa menjadi bahasa yang sangat bagus untuk setiap pengembang Android. Coba saja, dan bagikan di bagian komentar di bawah apa yang Anda pikirkan.

Kode sumber aplikasi sampel tersedia di Github: github.com/tomaszczura/AndroidMVPKotlin