Memastikan Kode Android Kualitas Atas Dengan Static Analysis Tools
() translation by (you can also view the original English article)
Dalam tutorial hari ini, kita akan belajar tentang cara memastikan kode Android berkualitas tinggi dalam proyek kami menggunakan beberapa fasilitas analisis kode statis untuk Java. Kita akan melihat Checkstyle, FindBugs, PMD, dan Android Studio Lint — semuanya gratis dan open source!
Apa itu Fasilitas Analisis Kode Statis?
Ini adalah fasilitas yang mengurai dan menganalisis source code Anda tanpa benar-benar mengeksekusinya. Tujuannya adalah untuk menemukan potensi kerentanan terhadap kesalahan akibat bug dan keamanan. Fasilitas analisis kode statis gratis yang populer seperti FindBugs memeriksa kode Anda terhadap serangkaian aturan yang harus dipatuhi kode Anda — jika kode tidak mengikuti aturan ini, itu adalah tanda bahwa ada sesuatu yang salah. Pikirkanlah bahwa fasilitas analisis kode statis sebagai kompiler tambahan yang dijalankan sebelum kompilasi akhir ke dalam bahasa sistem.
Banyak perusahaan perangkat lunak yang mewajibkan proyek untuk lulus uji analisis kode statis, selain melakukan tinjauan kode dan pengujian unit dalam proses pembuatan. Bahkan pengelola proyek open-source sering kali menyertakan satu atau beberapa langkah analisis kode statis dalam proses pembuatan. Jadi belajar tentang analisis statis merupakan langkah penting dalam menulis kode yang kualitas. Ketahuilah bahwa analisis kode statis — juga dikenal sebagai pengujian "kotak putih" atau lebih dikenal sebagai "white-box" testing — tidak boleh dilihat sebagai pengganti unit-testing terhadap source-code Anda.
Dalam tutorial ini, kita akan belajar tentang beberapa fasilitas analisis statis populer yang tersedia untuk Android dan Java. Tapi pertama-tama, mari kita lihat beberapa manfaat menggunakan analisis statis.
Manfaat
- Membantu mendeteksi potensi bug yang bahkan unit atau pengujian manual mungkin terlewatkan.
- Menentukan aturan spesifik proyek. Misalnya, analisis statis sebagai bagian dari rangkaian proses pembuatan yang dapat membantu pendatang baru mendapatkan percepatan terhadap standar kode dari tim baru mereka.
- Membantu Anda meningkatkan pengetahuan tentang bahasa baru.
- Memindai seluruh proyek Anda, termasuk file yang mungkin belum pernah Anda baca.
Pengaturan
Semua fasilitas analisis kode yang akan kita pelajari dalam tutorial ini tersedia sebagai plugin Gradle, sehingga kita dapat membuat gradle secara individu untuk masing-masing tugas. Mari gunakan satu file Gradle yang akan menyertakan semuanya. Tapi sebelum itu, mari kita buat folder yang akan berisi semua file untuk analisis kode statis.
Buka Android Studio dan di dalam modul aplikasi (dalam tampilan Project), buat folder baru dan beri nama code_quality_tools. Folder ini akan berisi file XML untuk fasilitas analisis kode, dan itu juga akan memiliki file Gradle, yaiutu quality.gradle, yang akan menjalankan tugas analisis statis kami.



Akhirnya, kunjungi build.gradle Anda pada folder app module dan sertakan baris ini di akhir file:
1 |
apply from: '/code_quality_tools/quality.gradle' |
Di sini, script Gradle quality.gradle kami sedang diterapkan dengan referensi ke lokasi file lokalnya.
Checkstyle
Dengan aturan yang Anda tetapkan dalam file XML untuk melaksanakan standar kode untuk proyek Anda, Checkstyle memberlakukan aturan tersebut dengan menganalisis source code Anda dan membandingkannya dengan standar atau konvensi kode yang dikenal.
Checkstyle adalah fasilitas open source yang secara aktif dikelola oleh komunitas. Ini berarti Anda dapat membuat pemeriksaan kustom Anda sendiri atau memodifikasi yang sudah ada sesuai dengan kebutuhan Anda. Sebagai contoh, Checkstyle dapat menjalankan pemeriksaan pada nama konstanta (final, static, atau keduanya) pada class Anda. Jika nama-nama konstanta Anda tidak menempel pada aturan yang berada dalam huruf besar dengan kata-kata dipisahkan oleh garis bawah, masalah akan ditandai dalam laporan akhir.
1 |
// incorrect
|
2 |
private final static String myConstant = "myConstant"; |
3 |
|
4 |
// correct
|
5 |
private final static String MY_CONSTANT = "myConstant"; |
Mengintegrasikan Checkstyle
Saya akan menunjukkan cara mengintegrasikan Checkstyle ke dalam proyek Android Studio kami dan menunjukkan contoh praktis.
Pertama, kita perlu membuat aturan kode kita. Di dalam checkstyle.xml, kami membuat beberapa aturan konfigurasi Checkstyle yang akan dijalankan terhadap kode kami.
1 |
<?xml version="1.0"?><!DOCTYPE module PUBLIC
|
2 |
"-//Puppy Crawl//DTD Check Configuration 1.2//EN"
|
3 |
"http://www.puppycrawl.com/dtds/configuration_1_2.dtd">
|
4 |
<module name="Checker"> |
5 |
<module name="FileTabCharacter"/> |
6 |
<module name="TreeWalker"> |
7 |
|
8 |
<!-- Checks for Naming Conventions -->
|
9 |
<!-- See http://checkstyle.sourceforge.net/config_naming.html -->
|
10 |
<module name="MethodName"/> |
11 |
<module name="ConstantName"/> |
12 |
|
13 |
<!-- Checks for Imports -->
|
14 |
<!-- See http://checkstyle.sourceforge.net/config_imports.html-->
|
15 |
<module name="AvoidStarImport"/> |
16 |
<module name="UnusedImports"/> |
17 |
|
18 |
<!-- Checks for Size -->
|
19 |
<!-- See http://checkstyle.sourceforge.net/config_sizes -->
|
20 |
<module name="ParameterNumber"> |
21 |
<property name="max" value="6"/> |
22 |
</module>
|
23 |
|
24 |
<!-- other rules ignored for brevity -->
|
25 |
</module>
|
Pada kode di atas, kami menyertakan aturan atau pemeriksaan yang kami inginkan Checkstyle untuk memvalidasi dalam source code kami. Salah satu aturan adalah AvoidStarImport seperti namanya, memeriksa apakah source code Anda termasuk pernyataan impor seperti java.util.*
. (Sebaliknya, Anda harus secara eksplisit menentukan paket untuk diimpor, misalnya java.util.Obsable
).
Beberapa aturan memiliki properti, yang dapat kita atur seperti yang kita lakukan untuk ParameterNumber — ini membatasi jumlah parameter dari suatu method atau constructor. Secara default, properti max
adalah 7, tetapi kami mengubahnya menjadi 6 sebagai gantinya. Lihatlah beberapa cara pemeriksaan lainnya di situs website Checkstyle.
Untuk menjalankan pemeriksaan ini, kita perlu membuat tugas untuk Gradle. Jadi kunjungi file quality.gradle dan buat tugas yang disebut checkstyle:
1 |
apply plugin: 'checkstyle' |
2 |
|
3 |
task checkstyle(type: Checkstyle) { |
4 |
description 'Check code standard' |
5 |
group 'verification' |
6 |
|
7 |
configFile file('./code_quality_tools/checkstyle.xml') |
8 |
source 'src' |
9 |
include '**/*.java' |
10 |
exclude '**/gen/**' |
11 |
|
12 |
classpath = files() |
13 |
ignoreFailures = false |
14 |
}
|
Perhatikan bahwa dalam kode di atas, pertama kali kami menerapkan plugin Checkstyle Gradle. Kami memberikan deskripsi dan menambahkannya ke grup Gradle yang sudah ditentukan yang disebut verifikasi.
Properti utama tugas Checkstyle Gradle yang kami perhatikan adalah:
- configFile: file konfigurasi Checkstyle untuk digunakan.
- IgnoreFailures: mengizinkan atau tidak untuk melanjutkan proses build jika ada peringatan.
- include: termasuk kumpulan pattern.
- exclude: kumpulan pattern pengecualian. Dalam hal ini, kami tidak memindai class yang dihasilkan.
Akhirnya, Anda dapat menjalankan skrip Gradle dengan mengunjungi jendela fasilitas Gradle di Android Studio, membuka grup verification, dan kemudian klik checkstyle untuk menjalankan tugas.



Cara lain adalah dengan menggunakan command line:
1 |
gradle checkstyle |
Setelah tugas selesai dijalankan, laporan akan dibuat, yang tersedia di app modul > build > reports > checkstyle. Anda dapat membuka checkstyle.html untuk melihat laporan.



Sebuah plugin Checkstyle tersedia secara gratis untuk Android Studio atau IntelliJ IDEA. Ini menawarkan pemindaian real-time file Java Anda.
PMD
PMD adalah fasilitas kode analisis yang open source terbuka lain yang menganalisis source code Anda. Ia menemukan kekurangan umum seperti variabel yang tidak digunakan, empty catch block, pembuatan objek yang tidak perlu dan sebagainya. PMD memiliki banyak set aturan yang dapat Anda pilih. Contoh aturan yang merupakan bagian dari set Aturan Desain adalah:
-
SimplifyBooleanExpressions
: hindari perbandingan yang tidak perlu dalam ekspresi boolean yang memperumit kode sederhana. Sebagai contoh:
1 |
public class Bar { |
2 |
// can be simplified to
|
3 |
// bar = isFoo();
|
4 |
private boolean bar = (isFoo() == true); |
5 |
|
6 |
public isFoo() { return false;} |
7 |
}
|
PMD dikonfigurasi dengan file pmd.xml. Di dalamnya, kami akan menyertakan beberapa aturan konfigurasi seperti untuk Android, Naming, dan Desain.
1 |
<?xml version="1.0"?>
|
2 |
<ruleset xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" name="Android Application Rules" |
3 |
xmlns="http://pmd.sf.net/ruleset/1.0.0" |
4 |
xsi:noNamespaceSchemaLocation="http://pmd.sf.net/ruleset_xml_schema.xsd" |
5 |
xsi:schemaLocation="http://pmd.sf.net/ruleset/1.0.0 http://pmd.sf.net/ruleset_xml_schema.xsd"> |
6 |
|
7 |
<description>Custom ruleset for Android application</description> |
8 |
|
9 |
<exclude-pattern>.*/R.java</exclude-pattern> |
10 |
<exclude-pattern>.*/gen/.*</exclude-pattern> |
11 |
|
12 |
<!-- Android --->
|
13 |
<!-- http://pmd.sourceforge.net/pmd-4.3.0/rules/android.html -->
|
14 |
<rule ref="rulesets/java/android.xml"/> |
15 |
|
16 |
<!-- Design -->
|
17 |
<!-- http://pmd.sourceforge.net/pmd-4.3.0/rules/design.html -->
|
18 |
<rule ref="rulesets/java/design.xml"> |
19 |
<exclude name="UncommentedEmptyMethod"/> |
20 |
</rule>
|
21 |
|
22 |
<!-- Naming -->
|
23 |
<!-- http://pmd.sourceforge.net/pmd-4.3.0/rules/naming.html -->
|
24 |
<rule ref="rulesets/java/naming.xml/ShortClassName"> |
25 |
<properties>
|
26 |
<property name="minimum" value="3"/> |
27 |
</properties>
|
28 |
</rule>
|
29 |
<!-- other rules ignored for brevity -->
|
30 |
</ruleset>
|
Seperti yang kami lakukan untuk Checkstyle, kami juga perlu membuat tugas PMD Gradle untuk pemeriksaan yang akan dijalankan di dalam file quality.gradle.
1 |
apply plugin: 'pmd' |
2 |
|
3 |
task pmd(type: Pmd) { |
4 |
description 'Run PMD' |
5 |
group 'verification' |
6 |
ruleSetFiles = files("./code_quality_tools/pmd.xml") |
7 |
source 'src' |
8 |
include '**/*.java' |
9 |
exclude '**/gen/**' |
10 |
reports { |
11 |
xml.enabled = false |
12 |
html.enabled = true |
13 |
}
|
14 |
|
15 |
ignoreFailures = false |
16 |
}
|
PMD juga tersedia sebagai plugin Gradle.
Properti utama dari tugas yang kami buat adalah:
- ruleSetFiles: Aturan khusus mengatur file yang akan digunakan.
- source: source untuk tugas ini
- reports: Laporan yang dihasilkan oleh tugas ini.
Akhirnya, Anda dapat menjalankan script Gradle dengan mengunjungi fasilitas jendela Gradle, membuka folder grup verifikasi, dan kemudian klik pmd untuk menjalankan tugas. Atau Anda dapat menjalankannya melalui baris perintah:
1 |
gradle pmd |
Laporan juga akan dihasilkan setelah mengeksekusi tugas yang tersedia di app module > build > reports > pmd. Ada juga plugin PMD yang tersedia untuk IntelliJ atau Android Studio untuk Anda unduh dan integrasikan jika Anda mau.
FindBugs
FindBugs adalah fasilitas analisis statis gratis yang menganalisis class Anda yang mencari potensi masalah dengan memeriksa bytecode Anda terhadap daftar pola dari bug yang diketahui. Beberapa dari mereka adalah:
- Class mendifinisakn hashCode() but not equals(): Sebuah kelas mengimplementasikan method hashCode() but not equals() - oleh karena itu dua instance mungkin sama tetapi tidak memiliki kode hash yang sama. Ini termasuk kategori praktik yang buruk.
- Pembandingan buruk nilai int dengan konstanta long: Kode ini membandingkan nilai int dengan konstanta long yang berada di luar rentang nilai yang dapat direpresentasikan sebagai nilai int. Perbandingan ini kosong dan mungkin akan menghasilkan hasil yang tidak diharapkan. Ini termasuk dalam cara kategori yang benar.
- TestCase tidak memiliki tes: class adalah JUnit
TestCase
tetapi belum menerapkan metode uji apa pun. Pola ini juga berada di bawah kategori kebenaran.
FindBugs adalah proyek open source, sehingga Anda dapat melihat, berkontribusi, atau memantau kemajuan kode sumber di GitHub.
Di file findbugs-exclude.xml, kami ingin mencegah FindBugs dari pemindaian beberapa class (menggunakan ekspresi reguler) dalam proyek kami, seperti class resource yang dibuat secara otomatis dan class manifest yang dibuat secara otomatis. Juga, jika Anda menggunakan Dagger, kami ingin FindBugs tidak memeriksa class Dagger yang dihasilkan. Kami juga dapat memberi tahu FindBugs untuk mengabaikan beberapa aturan jika kami mau.
1 |
<FindBugsFilter>
|
2 |
<!-- Do not check auto-generated resources classes -->
|
3 |
<Match>
|
4 |
<Class name="~.*R\$.*"/> |
5 |
</Match>
|
6 |
|
7 |
<!-- Do not check auto-generated manifest classes -->
|
8 |
<Match>
|
9 |
<Class name="~.*Manifest\$.*"/> |
10 |
</Match>
|
11 |
|
12 |
<!-- Do not check auto-generated classes (Dagger puts $ into class names) -->
|
13 |
<Match>
|
14 |
<Class name="~.*Dagger*.*"/> |
15 |
</Match>
|
16 |
|
17 |
<!-- http://findbugs.sourceforge.net/bugDescriptions.html#ST_WRITE_TO_STATIC_FROM_INSTANCE_METHOD-->
|
18 |
<Match>
|
19 |
<Bug pattern="ST_WRITE_TO_STATIC_FROM_INSTANCE_METHOD" /> |
20 |
</Match>
|
21 |
</FindBugsFilter>
|
Dan akhirnya, kami akan menyertakan tugas findbugs di quality.gradle:
1 |
apply plugin: 'findbugs' |
2 |
|
3 |
task findbugs(type: FindBugs) { |
4 |
description 'Run findbugs' |
5 |
group 'verification' |
6 |
classes = files("$project.buildDir/intermediates/classes") |
7 |
source 'src' |
8 |
classpath = files() |
9 |
effort 'max' |
10 |
reportLevel = "high" |
11 |
excludeFilter file('./code_quality_tools/findbugs-exclude.xml') |
12 |
reports { |
13 |
xml.enabled = false |
14 |
html.enabled = true |
15 |
}
|
16 |
ignoreFailures = false |
17 |
}
|
Pada baris pertama di atas, kami menerapkan FindBugs sebagai Plugin Gradle dan kemudian membuat tugas yang disebut findbugs
. Properti utama dari tugas findbugs
yang benar-benar kami perhatikan adalah:
-
classes
: class yang akan dianalisis.
-
effort
: tingkat usaha analisis. Nilai yang ditentukan harus berupamin
,default
, ataumax
. Ketahuilah bahwa tingkat yang lebih tinggi meningkatkan ketepatan dan menemukan lebih banyak bug dengan mengorbankan running-time dan konsumsi memori. -
reportLevel
: ambang prioritas untuk melaporkan bug. Jika diatur ke rendah, semua bug dilaporkan. Jika ditetapkan ke sedang (default), bug prioritas menengah dan tinggi dilaporkan. Jika diatur ke tinggi, hanya bug prioritas tinggi yang dilaporkan. -
excludeFilter
: nama file dari filter yang menentukan bug untuk dikecualikan dari yang dilaporkan, yang sudah kami buat.
Anda kemudian dapat menjalankan skrip Gradle dengan mengunjungi jendela alat Gradle, membuka folder grup verifikasi, dan kemudian mengklik findbugs untuk menjalankan tugas. Atau luncurkan dari command line:
1 |
gradle findbugs |
Laporan juga akan dihasilkan ketika tugas telah selesai dijalankan. Ini akan tersedia di modul app module > build > reports > findbugs. Plugin FindBugs adalah plugin lain yang tersedia secara gratis untuk diunduh dan terintegrasi dengan IntelliJ IDEA atau Android Studio.
Android Lint
Lint adalah fasilitas analisis kode lainnya, tetapi yang ini hadir dengan Android Studio secara default. Ini memeriksa file sumber proyek Android Anda untuk bug potensial dan optimasi untuk kebenaran, keamanan, kinerja, kegunaan, aksesibilitas, dan internasionalisasi.
Untuk mengonfigurasi Lint, Anda harus menyertakan blok lintOptions {}
di file build.gradle tingkat modul Anda:
1 |
lintOptions { |
2 |
abortOnError false |
3 |
quiet true |
4 |
lintConfig file('./code_quality_tools/lint.xml') |
5 |
}
|
Pilihan Kunci Lint kita perhatikan adalah:
-
abortOnError
: apakah lint harus mengatur kode keluaran dari proses jika kesalahan ditemukan. -
quiet
: apakah akan mematikan analisa kemajuan dari laporan. -
lintConfig
: file konfigurasi default untuk digunakan.
File lint.xml Anda dapat menyertakan masalah yang Anda ingin lakukan proses Lint untuk diabaikan atau modifikasi, seperti contoh di bawah ini:
1 |
<?xml version="1.0" encoding="UTF-8"?>
|
2 |
<lint>
|
3 |
<!-- Disable the given check in this project -->
|
4 |
<issue id="IconMissingDensityFolder" severity="ignore" /> |
5 |
|
6 |
<!-- Change the severity of hardcoded strings to "error" -->
|
7 |
<issue id="HardcodedText" severity="error" /> |
8 |
</lint>
|
Anda dapat menjalankan Lint secara manual dari Android Studio dengan mengklik menu Analyze, memilih Inspect Code... (ruang lingkup pemeriksaan adalah keseluruhan proyek), dan kemudian klik tombol OK untuk melanjutkan.






Anda juga dapat menjalankan Lint dengan mengunjungi fasilitas dari jendela Gradle, membuka grup verification, dan kemudian mengklik lint. Akhirnya, Anda dapat menjalankannya melalui baris perintah.
Pada Windows:
1 |
gradlew lint |
Di Linux atau Mac:
1 |
./gradlew lint |
Laporan juga akan dihasilkan ketika tugas telah selesai dijalankan, yang tersedia di app module > build > outputs > lint-results.html.
Bonus: StrictMode
StrictMode adalah fasilitas pengembang yang membantu mencegah pengembang proyek Anda melakukan sembarang flash I/O atau network I/O di thread utama, karena ini dapat menyebabkan aplikasi menjadi lamban atau tidak responsif. Ini juga membantu mencegah dialog ANR (App Not Responding) muncul. Dengan diperbaikinya masalah StrictMode, aplikasi Anda akan menjadi lebih responsif dan pengguna akan menikmati pengalaman yang lebih lancar. StrictMode menggunakan dua set kebijakan untuk melaksanakan aturannya:
- VM Policies: menjaga praktik pemrograman yang buruk seperti tidak menutup objek
SQLiteCursor
atau objekCloseable
apa pun yang telah dibuat. - Thread Policies: berhati-hati untuk operasi seperti flash I/O dan network I/O yang dilakukan pada application thread utama bukan pada background thread.
1 |
if (BuildConfig.DEBUG) { |
2 |
StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder() |
3 |
.detectDiskReads() |
4 |
.detectDiskWrites() |
5 |
.detectNetwork() // or .detectAll() for all detectable problems |
6 |
.penaltyLog() // Log detected violations to the system log. |
7 |
.build()); |
8 |
StrictMode.setVmPolicy(new StrictMode.VmPolicy.Builder() |
9 |
.detectLeakedSqlLiteObjects() |
10 |
.detectLeakedClosableObjects() |
11 |
.penaltyLog() |
12 |
.penaltyDeath() // Crashes the whole process on violation. |
13 |
.build()); |
14 |
}
|
Kode di atas dapat berupa Aplikasi, Activity, atau komponen aplikasi lainnya pada method onCreate()
.
Anda dapat mempelajari lebih lanjut tentang StrictMode
di sini di Envato Tuts+.
Contoh proyek Android yang menerapkan semua hal di atas termasuk kumpulan aturan dari fasilitas untuk proyek Android yang khas dapat ditemukan di repositori GitHub postingan ini.
Kesimpulan
Dalam tutorial ini, Anda belajar tentang cara memastikan kode Android berkualitas tinggi menggunakan fasilitas analisis kode statis: apa itu, manfaat penggunaannya, dan cara menggunakan Checkstyle, FindBugs, Lint, PMD, dan StrictMode dalam aplikasi Anda. Cobalah dan coba fasilitas ini — Anda mungkin menemukan beberapa masalah dalam kode yang tidak pernah Anda duga.
Sementara itu, lihat beberapa kursus dan tutorial kami lainnya tentang pengembangan aplikasi Android!
- Android SDKRxJava 2 untuk Aplikasi Android: RxBinding dan RxLifecycleJessica Thornsby
- Android StudioPemograman Fungsional Aplikasi Android di Kotlin: MemulaiJessica Thornsby
- Android SDKAndroid dari Dasar: Menggunakan REST APIsAshraff Hathibelagal
- Android SDKCara Membuat Aplikasi Chat Android Menggunakan FirebaseAshraff Hathibelagal