Sebagai bagian dari upaya kami memodernisasi panduan arsitektur aplikasi , kami ingin bereksperimen dengan pola UI berbeda untuk mengetahui pola terbaik, menemukan persamaan dan perbedaan di antara beberapa alternatifnya, dan pada akhirnya menggabungkan pembelajaran tersebut sebagai praktik terbaik.
Agar temuan kami mudah diikuti, kami membutuhkan sampel yang memiliki kasus bisnis yang familier dan tidak terlalu rumit. Dan… siapa yang tidak tahu dengan aplikasi TODO ? Kami memilih Architecture Blueprints ! Secara historis, Blueprints berfungsi sebagai taman bermain eksperimental untuk pilihan arsitektur. Sangat cocok untuk ini!
Aplikasi Architecture Blueprints sedang digunakan Pola yang ingin kami uji jelas dipengaruhi oleh berbagai API yang tersedia saat ini. API terbaru saat ini adalah Jetpack Compose State API ! Karena Compose bekerja secara mulus dengan setiap pola Aliran Data Searah , kami akan menggunakan Compose untuk merender UI guna membuat perbandingan yang adil.
Postingan blog ini menceritakan cara tim memigrasikan Architecture Blueprints ke Jetpack Compose . Karena LiveData juga dianggap sebagai alternatif dalam eksperimen, kami membiarkan sampel seperti pada saat migrasi. Dalam pemfaktoran ulang ini, class ViewModel dan layer data tidak disentuh.
⚠️ Arsitektur yang digunakan dalam codebase berbasis LiveData ini tidak sepenuhnya mengikuti praktik terbaik arsitektur terbaru . Secara khusus, LiveData tidak boleh digunakan dalam layer data atau domain — Flows dan coroutine bisa digunakan sebagai gantinya.
Sekarang setelah konteksnya jelas, mari kita dalami cara melakukan pendekatan pemfaktoran ulang Blueprints ke Jetpack Compose. Anda bisa melihat kode lengkapnya di cabang dev-compose .
✍️ Merencanakan migrasi bertahap Sebelum benar-benar mengerjakan coding, tim membuat rencana migrasi untuk memastikan semua orang setuju dengan perubahan yang diusulkan. Tujuan utamanya adalah menjadikan Blueprints sebagai aplikasi aktivitas tunggal dengan layar sebagai fungsi yang dapat dikomposisi, dan menggunakan library Compose Navigation yang direkomendasikan untuk berpindah antar layar.
Untungnya, Blueprints sudah menjadi aplikasi aktivitas tunggal yang menggunakan Jetpack Navigation untuk berpindah antar layar yang diimplementasikan dengan Fragment. Untuk bermigrasi ke Compose, kami mengikuti panduan interoperabilitas Navigation yang merekomendasikan aplikasi hibrid untuk menggunakan komponen Navigation berbasis fragmen dan menggunakan fragmen untuk menahan layar berbasis tampilan, layar Compose, serta layar yang menggunakan tampilan dan Compose. Sayangnya, tidak mungkin menggabungkan tujuan Fragment dan Compose dalam grafik Navigation yang sama.
Tujuan dari migrasi bertahap ini adalah untuk memudahkan peninjauan kode dan menjaga produk yang dapat dikirim selama migrasi. Rencana migrasi melibatkan tiga langkah:
Migrasikan konten setiap layar ke Compose. Setiap layar dapat dimigrasikan satu per satu ke Compose, termasuk pengujian UI-nya. Fragmen kemudian menjadi container/host dari setiap layar yang dimigrasikan. Migrasikan aplikasi ke Navigation Compose — yang menghapus semua Fragmen dari project — dan migrasikan logika UI Activity ke composable root. Pengujian end-to-end juga dimigrasikan pada titik ini. Hapus dependensi sistem Tampilan. Dan itulah yang kami lakukan! ๐ง๐ป Maju cepat ⏩ dua minggu, kami melakukan migrasi layar Layar Statistik (PR ), layar Tambah/Edit tugas (PR ), layar Detail tugas (PR ), dan layar Tugas (PR ); dan kami menggabungkan PR final yang memigrasikan logika Navigation dan Activity ke Compose, termasuk menghapus dependensi sistem Tampilan yang tidak digunakan .
Cara kami memigrasikan Blueprints ke Compose secara bertahap ๐ก Sorotan migrasi Selama migrasi, kami menemukan beberapa ciri khusus Compose yang perlu disoroti:
๐งช Pengujian UI Setelah Anda mulai menambahkan Compose ke aplikasi, pengujian yang menyatakan UI Compose harus menggunakan API pengujian Compose .
Untuk pengujian UI tingkat layar , sebagai ganti menggunakan API launchFragmentInContainer<FragmentType> , kami menggunakan API createAndroidComposeRule<ComponentActivity> yang memungkinkan kami mengambil resource string dalam pengujian. Pengujian ini berjalan dalam Espresso dan Robolectric . Karena Compose sudah mendukung ini semua, maka tidak diperlukan perubahan tambahan. Sebagai contoh, Anda bisa membandingkan kode dalam AddEditTaskFragmentTest yang dimigrasikan ke AddEditTaskScreenTest . Perhatikan, jika menggunakan ComponentActivity, Anda harus bergantung pada artefak androidx.compose.ui:ui-test-manifest .
Untuk pengujian integrasi atau end-to-end , kami juga tidak menemukan masalah! Berkat interoperabilitas Espresso dan Compose , kami menggunakan pernyataan Espresso untuk memeriksa Tampilan, dan API Compose untuk memeriksa UI Compose. Inilah sekilas tampilan AppNavigationTest selama migrasi ke Compose.
๐ค Event ViewModel Kami memang memiliki masalah dengan cara menangani event ViewModel di Blueprints. Blueprints menerapkan solusi Event wrapper untuk mengirim perintah dari ViewModel ke UI. Namun, itu bukan sesuatu yang bisa berfungsi di Compose. Panduan terbaru kami merekomendasikan pemodelan “event” tersebut sebagai status, dan itulah yang kami lakukan selama migrasi.
Dengan melihat kasus penggunaan event menampilkan pesan di layar , kami mengganti tipe Event<Int> dari LiveData menjadi Int? Ini juga memodelkan skenario ketika tidak ada pesan untuk ditampilkan kepada pengguna. Dalam kasus penggunaan khusus ini, ViewModel juga memerlukan konfirmasi dari UI setiap kali pesan ditampilkan. Lihat perbedaan antara kedua implementasinya dalam kode berikut:
Meskipun sekilas mungkin terlihat lebih merepotkan, ini menjamin setiap pesan ditampilkan di layar!
Dalam kode UI, cara untuk memastikan event hanya ditangani sekali adalah dengan memanggil event.getContentIfNotHandled(). Pendekatan ini bekerja dengan baik di Fragmen tetapi gagal di Compose ! Karena rekomposisi dapat terjadi sewaktu-waktu di Compose, event wrapper bukanlah solusi yang cocok. Jika event diproses dan fungsinya dikomposisi ulang (sesuatu yang sering terjadi saat menguji pendekatan ini), maka snackbar akan dibatalkan, dan pengguna mungkin melewatkan pesannya. Ini adalah masalah UX yang tidak dapat diterima! Solusi event wrapper tidak boleh digunakan di aplikasi Compose.
Lihat cuplikan kode berikut dengan kode sebelum (event wrapper) dan setelah (event as state). Karena menampilkan pesan di layar adalah logika UI dan composable layar semakin kompleks, kami menggunakan class holder status biasa untuk mengelola kompleksitas itu (mis. lihat AddEditTaskState ).
๐ Jika ragu, pilih kebenaran aplikasi Saat pemfaktoran ulang, Anda mungkin tergoda untuk memigrasikan semua yang ada ke Compose. Meskipun bukan masalah, Anda tidak boleh mengorbankan Pengalaman Pengguna atau kebenaran aplikasi Anda. Inti dari memigrasikan bertahap adalah aplikasi selalu dalam status dapat dikirim.
Ini terjadi pada kami saat memigrasikan beberapa layar ke Compose. Kami tidak ingin melakukan terlalu banyak migrasi secara bersamaan, dan memigrasikan beberapa layar ke Compose sebelum memigrasikan dari Event wrapper. Sebagai ganti menangani Event wrapper di Compose dan memberikan pengalaman yang kurang optimal, kami terus menangani pesan-pesan tersebut di Fragmen sedangkan kode lainnya untuk layar di Compose. Sebagai contoh, lihat status TasksFragment selama migrasi .
๐ง Tantangan Tidak semuanya berjalan semulus kelihatannya. ๐ซค Meskipun mengonversi isi Fragmen ke Compose sangatlah mudah, melakukan migrasi dari Navigation Fragment ke Navigation Compose membutuhkan banyak waktu dan pertimbangan.
Ada kebutuhan untuk memperluas dan menyempurnakan panduan mengenai berbagai aspek yang akan mempermudah migrasi ke Compose di masa mendatang. Pekerjaan ini memicu percakapan dan kami berharap bisa segera mendapatkan panduan baru tentang hal ini! ๐
Sebagai pemula Navigation ✋ dan orang yang menangani migrasi ke Navigation Compose, saya menghadapi tantangan berikut:
Tidak ada kode dalam dokumen yang menunjukkan cara menavigasi dengan argumen opsional ! Berkat grafik navigasi Tivi , saya menemukan cara dan memecahkan masalahnya (ikuti masalah untuk meningkatkan dokumen di sini ). Memigrasikan dari grafik Navigation berbasis XML dan SafeArgs ke Kotlin DSL seharusnya merupakan tugas mekanis yang mudah. Namun, ternyata tidak mudah mengingat saya tidak mengerjakan implementasi aslinya. Beberapa panduan tentang cara melakukannya dengan benar akan membantu saya (mengikuti masalah untuk meningkatkan dokumen di sini ).Bukan sekadar tantangan, poin ini adalah sebuah kemenangan besar! UI Navigation sudah melakukan beberapa tugas untuk Anda dalam hal navigasi. Karena ini tidak tersedia di Compose, Anda harus mengawasinya dan melakukannya secara manual. Sebagai contoh, menjaga backstack tetap bersih saat membuka beberapa layar Panel Samping memerlukan NavigationOptions khusus (lihat contohnya di sini ). Hal ini sudah dibahas dalam dokumen , tetapi Anda perlu menyadari bahwa Anda membutuhkannya! ๐ง๐ซ Kesimpulan Secara keseluruhan, melakukan migrasi dari Navigation Fragment ke Navigation Compose adalah tugas yang menyenangkan untuk dilakukan! Lucunya, kami menghabiskan banyak waktu menunggu tinjauan pembanding daripada memigrasikan proyek itu sendiri! Membuat rencana migrasi dan mengarahkan semua orang ke area yang sama pasti membantu menetapkan ekspektasi lebih awal dan memperingatkan rekan-rekan tentang ulasan yang masuk.
Kami harap Anda senang membaca pendekatan kami tentang migrasi ke Compose, dan kami berharap bisa berbagi lebih banyak hal tentang eksperimen dan peningkatan yang akan kami kerjakan dalam Architecture Blueprints.
Jika Anda tertarik melihat Blueprints dengan kode Compose, lihat cabang dev-compose . Dan jika Anda ingin melihat PR dari migrasi bertahap, berikut daftarnya:
๐
The previous Taliban 123VEGA regime, in the 1990s, severely curtailed เธฅิเธเธ์เธฃัเธเธเธฃัเธเธข์ women's freedom - and since the takeover เนเธเธฃเธิเธเธเธฃี of power by the Taliban last year, a series of restrictions เธชูเธเธฃเธชเธฅ็เธญเธ have been re-imposed on women เธชเธฅ็เธญเธเธญเธญเธเนเธฅเธ์ in Afghanistan. Regulations เธชเธฅ็เธญเธ on clothing and laws forbidding 88KTC access to public areas without a male guardian have slotxo been enforced. In March, schools re-opened for a new academic year, but the Taliban 123GOAL reversed an earlier promise and girls are currently not 11hilo permitted to attend secondary school.
ReplyDeleteAppreciate your insights and the valuable information shared in this post. Your blog is fantastic! Let's continue this excellent work.
ReplyDeleteGold99
Gold99
PGasia
PGasia