
Ketika pengembang tidak cukup berhati-hati, segalanya bisa berjalan sangat buruk. Misalnya, kelalaian pengembang klasik adalah penggunaan versi baru API yang tidak kompatibel dengan kode lama, pelaksanaan tindakan yang memerlukan izin pengguna khusus, dan kesenjangan dalam pelokalan aplikasi. Dan ini hanya beberapa di antaranya.
Selain itu, Java dan Kotlin, seperti bahasa pemrograman lainnya, memiliki konstruksi sendiri yang dapat menyebabkan kinerja yang buruk.
Halo, lint
Kami menggunakan alat yang disebut Lint (atau Linter) untuk menghindari masalah seperti itu. Lint adalah alat analisis kode statis yang membantu pengembang menangkap masalah potensial sebelum kompilasi kode. Lint melakukan beberapa pemeriksaan kode sumber, yang dapat mendeteksi masalah seperti variabel yang tidak digunakan atau argumen fungsi, penyederhanaan kondisi, cakupan yang salah, variabel atau fungsi yang tidak terdefinisi, kode yang dioptimalkan dengan buruk, dll. Ketika kita berbicara tentang pengembangan Android, ada ratusan Lint check out of the box.
Tetapi kadang-kadang kita perlu menemukan masalah khusus dalam kode kita yang tidak tercakup oleh pemeriksaan yang ada ini.
Halo kustom memeriksa Lint
Sebelum memulai pengkodean, mari tentukan tujuan kami dan lihat bagaimana mengimplementasikannya langkah demi langkah menggunakan API Lint. Tujuannya adalah membuat pemeriksaan untuk mendeteksi pemanggilan metode yang tidak benar untuk suatu objek. Gagasan tes ini adalah untuk menentukan apakah metode pemasangan pendengar pada komponen Lihat adalah salah satu yang akan mengganggu beberapa klik berturut-turut pada komponen sehingga kita dapat menghindari membuka Kegiatan yang sama atau mengakses jaringan beberapa kali.
Pemeriksaan pengguna serat ditulis sebagai bagian dari modul standar Java (atau Kotlin). Cara termudah untuk memulai adalah membuat proyek sederhana berbasis Gradle (tidak harus proyek Android).
Kemudian tambahkan dependensi Lint. Dalam file build.gradle
modul Anda, tambahkan:
compileOnly "com.android.tools.lint:lint-api:$lintVersion" compileOnly "com.android.tools.lint:lint-checks:$lintVersion"
Sekarang ada trik yang saya pelajari ketika meneliti topik ini. lintVersion
harus gradlePluginVersion + 23.0.0
. gradlePluginVersion
adalah variabel yang didefinisikan dalam file build.gradle
di tingkat proyek. Dan saat ini, versi stabil terbaru adalah 3.3.0. Ini berarti lintVersion
harus 26.3.0.
Setiap pemeriksaan serat terdiri dari 4 bagian:
- Masalahnya adalah masalah dalam kode kita yang kita coba cegah. Ketika pemeriksaan Serat gagal, ini dilaporkan ke pengembang.
- Detektor adalah alat pencarian masalah yang menyediakan API Lint.
- Implementasi adalah area di mana masalah dapat muncul (file sumber, file XML, kode yang dikompilasi, dll.).
- Registri adalah registri periksa serat kustom yang akan digunakan dengan registri yang sudah ada yang berisi pemeriksaan yang telah ditentukan.
Implementasi
Mari kita mulai dengan membuat implementasi untuk validasi khusus kami. Setiap implementasi terdiri dari kelas yang mengimplementasikan detektor dan ruang lingkup.
val correctClickListenerImplementation = Implementation(CorrectClickListenerDetector::class.java, Scope.JAVA_FILE_SCOPE)
Ingat bahwa Scope.JAVA_FILE_SCOPE
juga akan berfungsi untuk kelas Kotlin.
Masalah
Langkah selanjutnya adalah menggunakan implementasi ini untuk menentukan masalah. Setiap masalah terdiri dari beberapa bagian:
- ID adalah pengidentifikasi unik.
- Deskripsi - pernyataan singkat (5-6 kata) dari masalah.
- Penjelasan Penjelasan lengkap tentang masalah dengan saran tentang cara memperbaikinya.
- Kategori - kategori masalah (kinerja, terjemahan, keamanan, dll.)
- Prioritas - Pentingnya masalah, dalam kisaran 1 hingga 10, di mana 10 adalah yang tertinggi. Ini akan digunakan untuk mengurutkan masalah dalam laporan yang dibuat ketika Lint diluncurkan.
- Severity - keparahan masalah (fatal, kesalahan, peringatan, informasi, atau mengabaikan).
- Implementasi adalah implementasi yang akan digunakan untuk mendeteksi masalah ini.
val ISSUE_CLICK_LISTENER = Issue.create( id = "UnsafeClickListener", briefDescription = "Unsafe click listener", explanation = """" This check ensures you call click listener that is throttled instead of a normal one which does not prevent double clicks. """.trimIndent(), category = Category.CORRECTNESS, priority = 6, severity = Severity.WARNING, implementation = correctClickListenerImplementation )
Detektor
Lint API menawarkan antarmuka untuk setiap area yang dapat Anda tetapkan dalam implementasi. Masing-masing antarmuka ini menyediakan metode yang Anda dapat menimpa dan mengakses bagian dari kode yang Anda minati.
- UastScanner - File Java atau Kotlin (UAST - Unified Abstract Syntax Tree (Rusia unified abstrak syntax tree )).
- ClassScanner - file yang dikompilasi (bytecode).
- BinaryResourceScanner - sumber daya biner seperti bitmap atau
res/raw
file res/raw
. - ResourceFolderScanner - folder sumber daya (bukan file spesifik di dalamnya).
- XmlScanner - file XML.
- GradleScanner - File Gradle.
- OtherFileScanner - yang lainnya.
Selain itu, kelas Detector
adalah kelas dasar yang memiliki implementasi kosong dari semua metode yang disediakan oleh masing-masing antarmuka di atas, sehingga Anda tidak perlu mengimplementasikan antarmuka penuh jika Anda hanya perlu satu metode.
Sekarang kita siap mengimplementasikan detektor yang akan memeriksa pemanggilan metode yang benar untuk objek tersebut.
private const val REPORT_MESSAGE = "Use setThrottlingClickListener" class CorrectClickListenerDetector : Detector(), Detector.UastScanner { override fun getApplicableUastTypes(): List<Class<out UElement>>? { return listOf<Class<out UElement>>(UCallExpression::class.java) } /** * UAST, , * UAST . UElementHandler, * , , * , , , , .. * , * . — , * , , . */ override fun createUastHandler(context: JavaContext): UElementHandler? { return object: UElementHandler() { override fun visitCallExpression(node: UCallExpression) { if (node.methodName != null && node.methodName?.equals("setOnClickListener", ignoreCase = true) == true) { context.report(ISSUE_CLICK_LISTENER, node, context.getLocation(node), REPORT_MESSAGE, createFix()) } } } } private fun createFix(): LintFix { return fix().replace().text("setOnClickListener").with("setThrottlingClickListener").build() } }
Registri
Hal terakhir yang perlu kita lakukan adalah menambahkan masalah ke registri kita dan memberitahu Lint bahwa ada masalah registri khusus yang harus digunakan bersama dengan yang standar.
class MyIssueRegistry : IssueRegistry() { override val issues: List<Issue> = listOf(ISSUE_CLICK_LISTENER) }
Di tingkat modul build.gradle
:
jar { manifest { attributes("Lint-Registry-v2": "co.infinum.lint.MyIssueRegistry") } }
di mana co.infinum.lint
adalah paket kelas MyIssueRegistry
. Sekarang Anda dapat menjalankan tugas jar
menggunakan skrip gradlew
, dan pustaka akan muncul di direktori build/libs
.
Berikut ini contoh lain dari pemeriksaan pengguna Lint, tempat Anda dapat melihat cara memproses file XML.
Gunakan
Pemeriksaan Lint baru Anda siap digunakan dalam proyek. Jika pemeriksaan ini dapat diterapkan ke semua proyek, Anda dapat meletakkannya di folder ~/.android/lint
(Anda dapat membuatnya jika belum ada).
Selain itu, Anda dapat meletakkan cek Anda di modul terpisah di proyek Anda dan mengaktifkan modul ini seperti ketergantungan lainnya menggunakan metode lintChecks
.
Apakah itu sepadan?
Lint adalah alat yang sangat bagus yang harus digunakan setiap pengembang. Mampu mendeteksi potensi masalah dengan kode Anda lebih awal sangat membantu. Meskipun pemeriksaan khusus tidak mudah untuk ditulis, terutama karena kompleksitas API, mereka pasti sepadan dan dapat menghemat banyak waktu dan usaha di masa depan.