Baru-baru ini, kami telah sepenuhnya mendesain ulang aplikasi Pyrus untuk Android. Versi pertama aplikasi berfungsi sudah di bawah Android 2.2. Menolak untuk mendukung Android di bawah 4.1, kami dapat membayar akumulasi utang teknis dan secara signifikan menyederhanakan kode sumber. Ya, kami kehilangan sebagian pengguna (kurang dari 1%), tetapi di sisi lain, kami menghemat waktu bagi pengembang untuk memperbaiki bug langka. Kami akan dapat menginvestasikannya dalam pengembangan fungsionalitas untuk semua pengguna saat ini dan yang baru. Dalam jangka panjang, ini jauh lebih penting.
Di sini kami berbagi pengalaman yang mungkin berguna bagi mereka yang sedang mempertimbangkan memulai pengembangan untuk platform Android.
Android menarik alat pengembangan yang baik, bahasa yang telah teruji waktu (Java) dengan sintaksis yang biasa, pemirsa yang sangat banyak. Namun, membuat aplikasi yang mudah di Android sulit: meskipun API dikembangkan, sering terjadi bahwa tidak ada komponen siap pakai dengan perilaku yang sesuai. Anda harus meninggalkan ide-ide desainer UX, atau setuju untuk bergantung pada perpustakaan pihak ketiga, atau menulis sendiri. Tidak semua solusi arsitektur di Android ternyata berhasil, dan ini juga meningkatkan jumlah kode tanpa manfaat yang jelas.
Sekarat dan Bangkit dari Abu
Antarmuka di Android dibangun di atas Aktivitas. Ini adalah wadah yang biasanya menempati seluruh layar perangkat, widget lain ada di dalamnya dan menerima acara tentang interaksi pengguna.
Saat pengguna mengaktifkan aplikasi, acara onResume dilemparkan ke dalam Kegiatan. Menekan tombol Beranda - Aktivitas menghilang, tetapi sebelum itu ia menerima acara onPause. Sejauh ini, semuanya logis. Apa yang terjadi ketika pengguna memutar layar perangkat 90 derajat? Anda tidak akan pernah menebak: OS membunuh Aktivitas dan menciptakan kembali! Saat Anda menghapus Aktivitas, semua komponen yang ada di dalamnya dihapus. Ini berarti bahwa Anda harus menulis kode khusus yang menyimpan status widget di dalam Aktivitas (posisi gulir, teks yang dipilih, keadaan kotak centang) dan mengembalikannya setelah induk dibuat ulang. Android melakukan beberapa hal untuk Anda, tetapi tidak semua.
Sulit untuk memahami apa yang mendorong arsitek untuk membuat keputusan seperti itu. Kemudian, seseorang memutuskan bahwa tampilannya entah bagaimana jelek, dan menambahkan parameter yang sama, yang menekan perilaku default sistem. Sekarang, alih-alih menciptakan kembali Kegiatan, OS dapat memanggil metode onConfigurationChanged khusus. "Solusi" ini terlihat seperti retasan kotor dan hanya memperburuk masalah, karena dokumentasi Android
mengatakan "teknik ini harus dianggap sebagai tindakan ekstrem dan tidak disarankan untuk sebagian besar aplikasi".
Fragmen Terfragmentasi
Awalnya, OS Android diciptakan untuk ponsel. Dengan munculnya tablet, tim Android dengan tepat memutuskan bahwa elemen antarmuka yang sebelumnya dipisahkan oleh Aktivitas yang berbeda karena ukuran kecil layar ponsel sekarang dapat hidup berdampingan di layar besar tablet. (Contoh: daftar surat dan email di ponsel ada dalam dua Aktivitas berbeda, dan di tablet mereka berbagi satu layar bersama.) Ya, masalahnya adalah: beberapa Kegiatan tidak dapat secara bersamaan berinteraksi dengan pengguna dengan desain. Oleh karena itu, mekanisme lain untuk menggunakan kembali komponen diperlukan, dan solusinya ditemukan: fragmen muncul (Fragmen).
Menurut
definisi , Fragmen mewakili perilaku atau bagian dari antarmuka pengguna dalam suatu Kegiatan. Semuanya jelas. Namun, dalam instruksi untuk menggunakan fragmen kami menemukan bagian "Menambahkan fragmen yang tidak memiliki antarmuka pengguna". APA? Ternyata sebuah fragmen mungkin tidak memiliki jendela sendiri untuk rendering!
Tapi apa yang terjadi pada fragmen saat memutar layar? Pengembang Android memikirkan hal ini - ketika Anda membuat ulang suatu Aktivitas, semua fragmennya juga dibuat ulang secara otomatis. Namun, setelah dipertimbangkan dengan cermat, fragmen tersebut memiliki metode "setRetainInstance", jika Anda menyebutnya, maka fragmen ini tidak akan dihapus dan dipulihkan selama belokan.
Konsep ini ramping dan konsisten tidak bisa disebut.
Operasi asinkron
Utas pemrosesan peristiwa tidak dapat diblokir oleh operasi lama, oleh karena itu pertukaran data dengan disk dan jaringan harus dilakukan secara asinkron di utas lainnya. Android menyediakan sebanyak empat mekanisme untuk operasi asinkron: AsyncTask, Service, IntentService, Thread. Pengembang didorong untuk mencari tahu mana yang terbaik untuk mereka gunakan. Pilihannya tidak sepele: misalnya, jika aplikasi memulai AsyncTask, dan pengguna membalikkan layar selama pelaksanaannya, maka setelah selesai bekerja AsyncTask tidak dapat menemukan aktivitas baru (dibuat setelah belokan). Dan tidak satu pun dari empat mekanisme mengimplementasikan logika sederhana: jika pengguna memulai proses asinkron kedua tanpa menunggu hasil yang pertama, dan kemudian yang pertama masih berakhir sebelumnya, maka sudah sepantasnya untuk mengabaikan dan tidak mencerminkan hasilnya di UI.
Ini menjadi jelas penampilan banyak perpustakaan - data bus untuk mengatur pekerjaan asinkron dalam aplikasi Android.
Mulai ulang aplikasi setelah OOM
Jika Android kehabisan RAM gratis, OS dapat menyelesaikan proses apa pun. Ketika pengguna mengaktifkan aplikasi di masa depan, sistem akan mencoba memulihkan kondisinya. Secara teori, ini seharusnya tidak terlihat oleh pengembang (jika ia menerapkan metode onSaveInstanceState di semua komponen): sistem itu sendiri menciptakan kembali tumpukan aktivitas seperti selama penghentian paksa. Namun, jika inisialisasi membutuhkan waktu (misalnya, memuat cache dari disk atau dari jaringan), itu akan benar untuk menunjukkan kepada pengguna indikator menunggu. Ternyata saat membuat suatu Kegiatan, Anda masih perlu memantau "mulai dingin" dan melakukan inisialisasi secara manual. Belum lagi saat memulai ulang, tidak ada Utas dan AsyncTask yang dipulihkan.
Seberapa besar kemungkinan kehabisan memori dalam praktik? Biasanya, situasi ini terjadi saat memproses gambar resolusi tinggi. Misalnya, gambar 2048x1536 menempati 12 MB di memori objek Bitmap. Jumlah memori yang tersedia untuk aplikasi tergantung pada model perangkat tertentu dan kadang-kadang sangat kecil (64Mb atau 128Mb). Karena pengumpul sampah di semua versi Android sebelum 8.0 tidak memadatkan, bahkan jika Anda memiliki memori bebas 100Mb, tetapi dibagi menjadi blok 10Mb, upaya untuk mengalokasikan memori untuk gambar seperti itu menyebabkan crash aplikasi.
Pengumpulan sampah abadi
Setelah pengguna kami memperhatikan bahwa ketika menggulir daftar panjang aplikasi "tertinggal" - setiap 2-3 detik animasi berhenti untuk jeda singkat (200-300 ms), dan kemudian dilanjutkan. Analisis menunjukkan bahwa pengumpulan sampah secara mencurigakan sering dimulai dalam aplikasi. Ternyata kelas HashMap standar (yang kami gunakan untuk mendapatkan objek Java dengan ID-nya) tidak efisien dalam kasus kami: kita perlu membuat objek wrapper untuk setiap kunci, yang merupakan integer (int). Oleh karena itu, jumlah alokasi memori meningkat tanpa manfaat apa pun. Solusinya adalah beralih ke wadah SparseArray khusus (hanya tersedia di Android, bukan di platform Java standar), yang segera mengurangi tekanan pada pengumpul sampah.
Apa hubungan lag animasi dengan itu, Anda bertanya? Faktanya adalah bahwa pengumpul sampah di Android menghentikan semua utas selama operasinya, termasuk utas utama yang terlibat dalam rendering. Dalam versi Android dimulai dengan 5.0, mesin virtual lain digunakan (ART bukan Dalvik) dan algoritma pengumpulan sampah yang berbeda, yang menjeda animasi semakin sedikit. (Anda dapat membaca tentang membandingkan waktu pengumpulan sampah di
sini .)
Lihat Dokumen
Jika Anda ingin memasukkan pratinjau dokumen dalam aplikasi Anda, Anda terpaksa mengecewakan: di Android tidak ada komponen bawaan yang dapat menampilkan file Word, Excel, Powerpoint. Belum lagi arsip ZIP atau dokumen PDF. Jalan keluar? Memaksa pengguna untuk menginstal aplikasi pihak ketiga untuk melihat setiap jenis file atau menggunakan komponen WebView (sebenarnya browser). Dalam kedua kasus, ketika pengguna merekam file, aplikasi eksternal akan diluncurkan dan beberapa skenario tidak dapat diimplementasikan, misalnya, umpan gambar: tidak ada cara mudah untuk mengintegrasikan WebView ke dalam ViewPager standar.
Apa selanjutnya
Beberapa penelitian mengklaim bahwa
kompleksitas pengembangan Android relatif tinggi . Pengalaman kami menunjukkan bahwa mudah bagi pengembang yang kompeten untuk terbiasa dengan fitur-fitur platform ini. Dan meskipun hari ini Android adalah
OS seluler paling populer di dunia , dalam 5-10 tahun situasinya dapat berubah secara radikal.
Dalam beberapa tahun terakhir, Google diam-diam telah mengembangkan
Fuchsia OC baru dengan model keamanan yang berbeda secara fundamental (dibandingkan dengan OS modern). Mungkin akan menggunakan
Dart sebagai bahasa pemrograman utama, dan kerangka kerja
Flutter sebagai cara utama untuk membuat aplikasi. Rumor mengatakan bahwa
Fuchsia dapat menggantikan Android dan ChromeOS di semua perangkat. Jika Google melakukan ini, perusahaan kemungkinan akan memberikan dukungan asli untuk aplikasi yang ditulis untuk Android (seperti yang dilakukan Microsoft ketika beralih dari DOS ke Windows). Karena itu, sejauh ini Anda tidak perlu khawatir dan terus menumpuk keahlian di Android. Dan bagi mereka yang ingin melihat masa depan, Anda dapat mengunduh Flutter dan memainkannya di
sini .