Pembaca,

Baru-baru ini saya melakukan pembaruan aplikasi INOCHI Kalender Indonesia (iKalenesia), sehingga saat ini sudah menginjak versi 3.2.2.0. Mendapatkan informasi dari pengguna bahwa iKalenesia tidak dapat dijalankan pada Android 6.0 Marshmallow segera saya mengeceknya dan akhirnya mendapat kesimpulan bahwa penyebabnya adalah bug pada SDK Android 6.0 Marshmallow untuk activity yang menggunakan theme transparent. Saya memang menggunakan theme transparent untuk keperluan wisaya (wizard) pemasangan dan pada kotak pesan notifikasi dengan tujuan agar GUI tampak seperti mengapung pada Home Screen.

 Dialog Mengapung

Dialog Mengapung

Bagi Anda yang mengalami hal yang sama, begini cara penyelesaiannya. Yaitu dengan menambahkah kode berikut ini pada kelas obyek activity Anda.

@Override
protected void onStart() {
  super.onStart();
  setVisible(true);
}
Ya, masalahpun terpecahkan. Namun ada satu bug lagi pada iKalenesia, yaitu pada fitur Peralatan. Aplikasi akan tertutup saat memilih opsi pada Spinner (combo), misalnya saat memilih tahun. Apa penyebabnya? Saya akan bercerita sedikit panjang. :D

Saat proses pengembangan (developing) versi 3.2.1.0, lagi-lagi terdapat bug pada SDK Android. Kali ini bug pada paket library android-support-v4. Bug apakah? Bug terdapat pada view yang bernama PagerTabStrip, dimana saat menjalankan aplikasi pertama kali pada tab tidak akan tercantum judul tab alias blank.

 Tab Tidak Berjudul

Tab Tidak Berjudul

Ya, benar-benar blank kecuali jika pengguna telah berpindah tab (dengan mengusap layar ke kiri atau kanan) barulah judul pada tab akan terlihat. Sempat saya kira ini akibat saya melakukan perubahan-perubahan yang tidak sengaja mengakibatkan hal ini terjadi. Namun setelah melakukan beberapa pengujian akhirnya saya yakin masalah terdapat pada SDK yang saat itu baru saja saya perbarui. Setelah googling akhirnya saya temukan jawabannya, dan memang benar, ada bug pada SDK terbaru (saat itu) yaitu pada pustaka android-support-v4.

Sayapun mempelajari cara memperbaikinya, dan berhasil. Yaitu dengan cara mem-by-pass pustaka tersebut dengan menambahkan sebuah kelas baru yang bernama PagerTabStripV22. Karena kelas ini dipergunakan sebagai view, maka saya harus mengubah layout-layout yang sebelumnya berupa view PagerTabStrip menjadi PagerTabStripV22. Saat itu saya tidak mungkin menunggu sampai Google merilisi versi perbaikan untuk masalah ini, karena pada aplikasi iKalenesia versi sebelum 3.2.1.0 didapati bug saat pengguna ingin menampilkan kalender tahun 1970 ke bawah, dan ini harus segera diatasi.

Dengan was-was akhirnya saya memublikasikan versi terbaru iKalenesia ini (versi 3.2.1.0), saya tidak memeriksa keseluruhan fitur pada aplikasi karena saya yakin bug (baik bug dari aplikasi maupun bug dari pustaka Android) tidak menyebar kemana-mana. Satu bulan berlalu hingga akhirnya saya mendapat kabar dari salah satu pengguna bahwa aplikasi tidak berjalan pada Android 6.0 Marshmallow. Setelah dilakukan pengecekan ternyata benar, sayapun memeriksa keseluruhan fitur, lumayan pembaca, ada 15 activity yang harus diperiksa dan tiap activity tersebut terdapat beberapa obyek lain yang juga harus diperiksa. Makanya saya sedikit malas untuk memeriksa ulang. :D

Sebelum memperbaiki saya memeriksa status pembaruan SDK Android dan ternyata sudah ada pembaruan. Segera saya memperbarui, dan tepat. Perbaruan salah satunya adalah untuk memperbaiki bug pada PagerTabStrip. Setelah menggunakan SDK terbaru masalah pada PagerTabStrip teratasi. Tentu saja saya sudah tidak membutuhkan lagi view "jadi-jadian" PagerTabStripV22 dan harus dihapus. Selain itu saya juga harus mengubah kembali layout-layout yang sebelumnya menggunakan view PagerTabStripV22 kembali ke PagerTabStrip.

Saya tes aplikasi pada perangkat saya, Lenovo K900 dengan Sistem Operasi yang sampai sekarang tidak ada pembaruan dari Lenovo, yaitu Android Jellybean 4.2.1. Entahlah setelah bertahun-tahun sama sekali Lenovo tidak ada niat untuk memperbarui Sistem Operasi dari K900 ini. Aplikasi tidak ada masalah saat diuji. Oya, saat pengujian, saya harus menghapus aplikasi iKalenesia versi lawas lebih dulu dari perangkat? Kenapa? Karena perbedaan sertifikat SHA1 fingerprint pada mode debug dan mode release.

Masalah tinggal satu lagi nih, aplikasi tidak jalan di Android 6.0 Marshmallow. Terpaksa saya harus mengunduh berkas image untuk emulator, lumayan, ukuran berkasnya "hanya" 500MB saja. :D Setelah emulator siap dan dilakukan pengujian ternyata betul pembaca, aplikasi tertutup saat dijalankan. Saya lakukan bug tracing, tidak ada masalah dengan kode sumber maupun layout pada proyek. Sampai akhirnya saya temukan kata kunci "transparent" pada Log Cat (catatan proses debugging). Dengan bekal kata kunci tersebut saya lakukan googling hingga didapat cara penyelesaiannya seperti saya tulis di awal-awal artikel ini.

Baik, masalah teratasi, akhirnya saya memublikasikan versi terbaru (versi 3.2.2.0). Oya, saat perilisan versi terbaru, saya juga harus merilis aplikasi-aplikasi kalender sejenis lainnya, diantaranya:  iKalenesia versi Pro, Kalender Dunia, Kalender Malaysia, Kalender Brunei, Kalender Singapore, Kalender Philippines, Kalender Hijriyah, serta Kalender Indonesia versi Lite. Lumayan capek juga. :D

Selang sehari setelah rilis, alamak... Banyak keluhan masuk dari pengguna bahwa mereka tidak dapat memperbarui aplikasi secara otomatis. Pengguna harus menghapus lebih dulu versi lawas kemudian memasang versi baru. Sial, ini ribetnya jadi pengembang aplikasi Android. Apa penyebabnya? Mari saya uraikan!

Seperti sudah saya tuliskan sebelumnya, setelah memperbarui SDK, saya menghapus view "jadi-jadian" PagerTabStripV22 dan mengubah layout-layout yang menggunakan view tersebut. Yang perlu Anda ketahui, saat Anda menambahkan obyek maupun resource pada proyek Android yang sedang Anda kembangkan, IDE (dalam hal ini adalah Eclipse) akan mendaftarkan obyek-obyek tersebut pada sebuah kelas yang dinamakan kelas R.

 Penampakan kelas R

Penampakan kelas R

Kelas ini mencatat setiap obyek, resource, maupun reference yang terdapat pada proyek agar dapat dikenali oleh obyek-obyek lain. Setiap item diwakili oleh sebuah konstanta bernilai integer namun ditulis dalam bentuk heksa desimal. Kelas ini akan dibuat otomatis oleh IDE, konten pada kelas akan diperbarui otomatis saat Anda menambah, menghapus, dan/atau mengubah obyek-obyek pada proyek. Anda tidak diijinkan untuk mengubah nilai konstanta secara manual. Di sinilah akar masalahnya.

Saat Anda memberi pengenal pada sebuah view, pengenal tersebut akan otomatis dibuatkan konstantanya pada kelas R.

 Memberikan Pengenal pada View

Memberikan Pengenal pada View

Dan ketika Anda menghapus sebuah view atau obyek lainnya pada proyek, maka kelas R ini akan dibuat ulang (regenerate). Yang jadi permasalahan adalah nilai konstanta dari sebuah item besar kemungkinan akan berubah. Bingung maksudnya? Simak penjabarannya berikut ini.

Misalkan saya mempunyai sebuah layout yang terdiri dari sebuah LinearLayout, sebuah TextView, sebuah EditText, dan sebuah Button. LinearLayout saya berikan pengenal (id) linMain dan tercatat di kelas R dengan nilai 0x7f0e0001. TextView saya beri pengenal txtLabel dan tercatat di kelas R dengan nilai 0x7f0e0002. EditText saya berikan pengenal editNama dan tercatat di kelas R dengan nilai 0x7f0e0003. Button saya beri pengenal btnGo dan tercatat di kelas R dengan nilai 0x7f0e0004.

Selanjutnya, saya menambah beberapa berkas resource, menambah beberapa layout, dan sebagainya, serta menuliskan kode sumber pada kelas Activity. Sampai saat ini aplikasi berjalan dengan baik. Kemudian karena sesuatu hal, saya menghapus beberapa view pada layout, mengubah pengenal dari beberapa view, juga menghapus beberapa resource. Saat tersebut, kelas R akan memeriksa ulang isi proyek secara keseluruhan kemudain mencatat kembali item-item dan memberinya nilai. Nah, nilai-nilai ini besar kemungkinan akan berubah. Kenapa? Karena nilai ditentukan secara berurut, perhatikan lagi paragraf di atas (0x7f0e0001, 0x7f0e0002, 0x7f0e0003, 0x7f0e0004, dan seterusnya). Saat sebuah item dihapus, tentu saja item berikutnya harus menggantikan posisi item terhapus tersebut.

Lalu masalahnya dimana? Kan hanya nilai yang berubah? Begini, sebelum terjadi perubahan struktur pada proyek, view Button dengan pengenal btnGo memiliki nilai 0x7f0e0004, kemudian saat terjadi perubahan (peningkatan versi), nilai 0x7f0e0004 kini dimiliki oleh EditText dengan pengenal editNama. Tentu saja perbedaan properti (sifat-sifat) dari Button dan EditText memiliki banyak perbedaan. Sebut saja EditText punya metode/event setOnEditorActionListener sementara Button tidak. Inilah yang membuat sistem kebingungan dan akhirnya terjadi crash pada aplikasi. Kalau di kehidupan nyata, anggap saja pedagang asong yang tiba-tiba diberi jabatan gubernur seperti (mirip) terjadi di negara sebelah.

Begitulah yang terjadi para pembaca. Mudah-mudahan Anda paham. Mudah-mudahan Anda juga menjadi mengerti, betapa sulitnya menjadi pengembang Android, dengan bug yang tiada hentinya pada SDK Android itu sendiri, juga dengan keterbatasan dan aturan dari IDE nya. Tentunya sebagai seorang pengembang, kita harus selalu berusaha memberikan yang terbaik bagi para pengguna aplikasi.

 

 

 

Komentar Anda

Komentari