StrictMode adalah alat pengembang yang terintegrasi di Android SDK yang mendeteksi dan melaporkan operasi I/O acak dan panggilan jaringan di thread utama aplikasi secara waktu nyata. Alat ini tidak memperbaiki kesalahan, tetapi bertindak sebagai detektor — melempar pengecualian atau menulis ke LogCat saat melanggar kebijakan yang ditetapkan. Menurut Google, 2024, konfigurasi StrictMode yang benar dapat mendeteksi hingga 80% masalah kinerja sebelum rilis aplikasi.
Poin Utama
StrictMode adalah API yang termasuk dalam Android SDK sejak API Level 9 (Android 2.3 Gingerbread). Tugasnya adalah mendeteksi secara waktu nyata eksekusi operasi berat yang tidak sengaja dilakukan di thread utama (UI) yang dapat memblokir rendering antarmuka. Thread utama bertanggung jawab untuk memproses input pengguna, menghitung tata letak, dan rendering — setiap pemblokiran lebih dari 16 ms menyebabkan frame terlewat.
StrictMode mengikuti prinsip “fail fast” — deteksi masalah sedini mungkin, idealnya saat pertama kali muncul. Alih-alih menunggu keluhan pengguna tentang perlambatan, pengembang menerima sinyal (log, dialog, atau crash) langsung di tahap pengembangan. Alat tidak memerlukan pustaka tambahan atau konfigurasi Gradle — beberapa baris kode di Application.onCreate sudah cukup dan berfungsi otomatis di semua perangkat.
StrictMode ditujukan untuk semua pengembang Android, terlepas dari pengalaman. Bagi pemula, alat ini membantu membentuk kebiasaan yang benar (tidak melakukan permintaan jaringan di thread UI), bagi yang berpengalaman — mengotomatiskan kontrol kualitas di pipeline CI/CD. Proyek besar (Google, Uber, Spotify) mengaktifkan StrictMode di debug builds dengan penaltyDeath, dan di release builds menonaktifkannya melalui pemeriksaan BuildConfig.DEBUG.
StrictMode mencegat panggilan sistem yang dapat memblokir thread dan membandingkannya dengan set kebijakan aktif. Jika panggilan sesuai dengan kebijakan dan dijalankan di thread utama, StrictMode menerapkan penalty yang ditetapkan. Mekanisme pencegat diimplementasikan melalui hook intra-proses — tidak menggunakan reflection dan bekerja dengan overhead minimal.
Saat kebijakan diaktifkan, StrictMode menempatkan handlernya di titik masuk panggilan sistem (FileInputStream, FileOutputStream, Socket, URLConnection). Saat aplikasi memanggil, misalnya, URLConnection.openStream di thread utama, StrictMode memeriksa thread saat ini — jika main thread, alat akan aktif. Di Android 6.0+ mekanisme diperkuat: panggilan jaringan di main thread menghasilkan NetworkOnMainThreadException bahkan tanpa StrictMode, tetapi StrictMode memungkinkan kontrol I/O disk juga.
Setiap kebijakan dapat memiliki jenis penalty sendiri atau kombinasi: penaltyLog — menulis ke LogCat dengan stacktrace, penaltyDialog — menampilkan dialog kepada pengguna (hanya di debug), penaltyDeath — melempar pengecualian dan crash aplikasi, penaltyDropBox — menyimpan data di DropBoxManager untuk analisis selanjutnya. Untuk pipeline CI/CD disarankan penaltyDeath — memastikan tidak ada merge dengan pelanggaran yang luput.
class App : Application() {
override fun onCreate() {
super.onCreate()
if (BuildConfig.DEBUG) {
StrictMode.setThreadPolicy(
StrictMode.ThreadPolicy.Builder()
.detectDiskReads()
.detectDiskWrites()
.detectNetwork()
.penaltyLog()
.penaltyDeath()
.build()
)
}
}
}
StrictMode membagi kebijakan menjadi dua tingkat: ThreadPolicy (thread — apa yang tidak boleh dilakukan di thread utama) dan VmPolicy (mesin virtual — kebocoran memori dan sumber daya). Kedua tingkat dikonfigurasi secara independen dan bekerja secara paralel.
Di tingkat thread, StrictMode mengontrol empat jenis pelanggaran: membaca dari disk (detectDiskReads), menulis ke disk (detectDiskWrites), operasi jaringan (detectNetwork), dan panggilan lambat kustom (detectCustomSlowCalls). disk_read dipicu saat membaca SharedPreferences, SQLite, file di thread utama. network — saat permintaan HTTP, WebSocket, koneksi Socket. Di Android 11+ ditambahkan detectUnbufferedIO untuk mendeteksi I/O tanpa buffer.
VmPolicy mengontrol kebocoran di tingkat mesin virtual ART: detectActivityLeaks (Activity yang tidak dihancurkan), detectLeakedClosableObjects (Cursor, Stream, Socket yang tidak ditutup), detectLeakedRegistrationObjects (BroadcastReceiver, ServiceConnection yang tidak dibatalkan). Jika VmPolicy mendeteksi bahwa Activity dibuat tetapi tidak dihancurkan setelah panggilan onDestroy, ia menampilkan stack trace lengkap — menghemat jam debugging kebocoran memori.
| Kebijakan | Tingkat | Yang Dideteksi |
|---|---|---|
| detectDiskReads | Thread | Membaca SharedPrefs, SQLite, file di thread UI |
| detectDiskWrites | Thread | Menulis ke SharedPrefs, SQLite, file di thread UI |
| detectNetwork | Thread | Semua operasi jaringan di thread UI |
| detectActivityLeaks | VM | Activity yang selamat dari onDestroy |
| detectLeakedClosableObjects | VM | Cursor, Stream, Socket tidak ditutup |
Melalui detectCustomSlowCalls Anda dapat menandai metode sendiri sebagai “mencurigakan” dan menerima peringatan saat melebihi ambang batas yang ditentukan. Misalnya, jika metode loadUserProfile() biasanya berjalan 5 ms, tetapi dalam beberapa kasus memakan waktu 200 ms — bungkus dalam StrictMode.noteSlowCall("loadUserProfile"). Jika durasi melebihi ambang (default 2000 ms), StrictMode akan menghasilkan penalty. Ambang dikonfigurasi melalui setSlowCallDurationThreshold.
Konfigurasi dasar StrictMode memakan 10 baris kode dan dilakukan di metode onCreate kelas Application kustom. Aturan utama: StrictMode hanya diaktifkan di debug builds — di release builds memperlambat aplikasi dan dapat menghasilkan positif palsu.
Buat kelas yang mewarisi Application, daftarkan di AndroidManifest.xml melalui atribut android:name, dan tambahkan konfigurasi StrictMode. ThreadPolicy.Builder mengaktifkan semua detektor dan semua jenis penalty (kecuali dialog — hanya berfungsi dengan debugger terhubung). VmPolicy.Builder menambahkan detektor kebocoran Activity dan Closable. Untuk proyek besar (100+ layar) disarankan mengonfigurasi VmPolicy dengan penaltyDeath pada detektor Activity Leaks — ini ketat tetapi efektif.
class App : Application() {
override fun onCreate() {
super.onCreate()
if (BuildConfig.DEBUG) {
StrictMode.setVmPolicy(
StrictMode.VmPolicy.Builder()
.detectActivityLeaks()
.detectLeakedClosableObjects()
.detectLeakedRegistrationObjects()
.penaltyLog()
.penaltyDeath()
.build()
)
}
}
}
Untuk kontrol otomatis di CI/CD gunakan penaltyDeath — jika ada tes yang melanggar kebijakan, aplikasi akan crash dengan pengecualian. Kombinasikan dengan Android Test Orchestrator agar setiap tes berjalan di proses bersih. Untuk tes UI (Espresso, Compose Test) buat TestRule kustom yang mencegat pelanggaran StrictMode dan mengubahnya menjadi assertion failure. Contoh: di @Before aktifkan StrictMode, di @After periksa apakah tidak ada violations.
Secara default, ambang untuk customSlowCall adalah 2000 ms, untuk disk_read dan disk_write — tanpa ambang (setiap operasi memicu). Melalui setSlowCallDurationThreshold dan setSlowIoDurationThreshold Anda dapat menetapkan nilai sendiri dalam milidetik. Jika aplikasi Anda secara sah membaca SharedPreferences di thread utama (konfigurasi kecil), naikkan ambang menjadi 10–20 ms — ini akan memotong pembacaan cepat tetapi mempertahankan yang lambat.
StrictMode adalah alat yang kuat tetapi rewel. Konfigurasi yang salah menyebabkan jutaan positif palsu, sehingga pengembang berhenti memperhatikannya. Di bawah ini adalah praktik terverifikasi yang dikumpulkan dari pengalaman tim Android besar.
Ini aturan besi: StrictMode TIDAK PERNAH aktif di release builds. Gunakan flag BuildConfig.DEBUG atau buildConfigField kustom. Di release builds, banyak pustaka pihak ketiga secara sah menjalankan operasi di thread utama (inisialisasi SDK, penulisan cache), dan StrictMode akan menghasilkan positif palsu. Selain itu, penaltyDialog di release build akan menampilkan dialog kepada pengguna akhir — yang tidak dapat diterima.
Untuk proyek kecil (1–10 layar) konfigurasi penaltyLog — log cukup untuk analisis manual. Untuk proyek menengah (10–50 layar) tambahkan penaltyDeath untuk network dan customSlowCalls. Untuk proyek besar (50+ layar) aktifkan set kebijakan lengkap dengan penaltyDeath di CI/CD, dan untuk pengembangan lokal — penaltyLog. Gradasi ini memungkinkan tidak membebani pengembang dengan crash palsu, tetapi mengontrol kualitas secara ketat di pipeline.
Beberapa pustaka (Firebase, Crashlytics, Adjust) secara sah menjalankan operasi di latar belakang yang mungkin salah dideteksi StrictMode. Solusi: tambahkan pustaka ke whitelist melalui penaltyListener, perbarui pustaka ke versi dengan perpindahan eksplisit ke background thread, atau gunakan StrictMode.vmPolicy. Di Android 11+ muncul StrictMode.OnVmViolationListener untuk pemfilteran pelanggaran secara terprogram berdasarkan stacktrace.
// Menyaring positif palsu melalui penaltyListener
StrictMode.setThreadPolicy(
StrictMode.ThreadPolicy.Builder()
.detectAll()
.penaltyListener { violation ->
val stack = violation.stackTraceToString()
if ("com.google.firebase" !in stack) {
logViolation(violation)
}
}
.build()
)
StrictMode bukan satu-satunya alat kontrol kualitas di ekosistem Android. Untuk memahami posisinya, mari kita bandingkan dengan Android Lint, Android Profiler, dan Perfetto berdasarkan kriteria utama: waktu pemeriksaan, kedalaman analisis, dan otomatisasi.
| Kriteria | StrictMode | Android Lint | Profiler / Perfetto |
|---|---|---|---|
| Waktu Periksa | Runtime (saat aplikasi berjalan) | Compile time (sebelum dijalankan) | Runtime (post-mortem) |
| Yang Diperiksa | Disk, jaringan, kebocoran | XML, kode, sumber daya | CPU, memori, jaringan, energi |
| Otomatisasi | CI/CD melalui penaltyDeath | Gradle task + lint-baseline | Memerlukan analisis manual |
| Kedalaman | Hanya thread UI dan kebocoran | Analisis kode statis | Gambaran kinerja lengkap |
| Positif Palsu | Sedang (tergantung pustaka) | Rendah (aturan dikonfigurasi) | Tidak ada (pengukuran nyata) |
Strategi terbaik adalah menggabungkan ketiga pendekatan: Android Lint menangkap kesalahan jelas di tahap kompilasi (misalnya, IdleHandler terlupakan), StrictMode mendeteksi masalah di runtime, dan Android Profiler / Perfetto digunakan untuk analisis mendalam saat dua alat pertama tidak memberikan jawaban. Di proyek nyata (Google Maps, Instagram), StrictMode diterapkan di minggu kedua pengembangan — segera setelah pengaturan arsitektur dasar.
Mari kita lihat dua skenario nyata di mana StrictMode membantu mendeteksi dan memperbaiki masalah kinerja: membaca SharedPreferences di thread utama dan kebocoran Activity melalui callback yang tidak didaftarkan.
Saat aplikasi dimulai, StrictMode dengan kebijakan detectDiskReads akan mendeteksi pembacaan SharedPreferences di thread utama. Solusi: muat konfigurasi secara asinkron melalui CoroutineScope atau cache di memori saat startup. SharedPreferences membaca file XML secara sinkron dari disk — bahkan dengan file kecil (1–2 KB), operasi memakan waktu 1–5 ms, dan di perangkat murah hingga 20 ms, yang dapat menyebabkan frame terlewat.
// ❌ Kode bermasalah — membaca SharedPrefs di thread UI
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
// StrictMode detectDiskReads → VIOLATION!
prefs = getSharedPreferences("config", MODE_PRIVATE)
}
}
// ✅ Kode diperbaiki — membaca melalui Coroutine
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
loadConfigAsync()
}
}
StrictMode dengan VmPolicy.detectActivityLeaks akan mendeteksi Activity yang telah keluar dari tumpukan (finish dipanggil), tetapi objek Activity masih menggantung di memori karena referensi statis atau callback yang tidak dibatalkan. Skenario tipikal: registrasi EventBus atau LocationListener di onResume tanpa panggilan unregister di onPause. VmPolicy akan menampilkan stack trace dengan indikasi baris tempat referensi dibuat.
// ❌ Kebocoran — callback tidak dibatalkan
private var locationCallback: LocationCallback? = null
override fun onResume() {
super.onResume()
locationCallback = LocationCallback(this::onLocationUpdated)
locationManager.register(locationCallback) // StrictMode → LEAK!
}
override fun onPause() {
super.onPause()
// Lupa: locationManager.unregister(locationCallback)
}
Pertanyaan Umum
StrictMode memang menambahkan sedikit overhead — setiap panggilan sistem diperiksa kepatuhannya terhadap kebijakan. Dampak pada kinerja adalah 1–3% di debug build dan tidak ada di release (di mana StrictMode dinonaktifkan). Saat mengaktifkan detectAll di perangkat lama (Android 6–8), overhead bisa mencapai 5%, oleh karena itu disarankan hanya mengonfigurasi kebijakan yang diperlukan.
Ya, StrictMode sepenuhnya kompatibel dengan Jetpack Compose. Kebijakan disk dan jaringan bekerja di tingkat framework, terlepas dari framework UI. Selain itu, di Compose, kekritisan pemblokiran UI lebih tinggi — Compose menggambar ulang frame pada 120 FPS di perangkat dengan kecepatan refresh tinggi, sehingga tambahan 5 ms untuk membaca file menjadi lebih terlihat.
Mulai Android 8.1 (API 27), SharedPreferences dapat menggunakan caching memori — jika file sudah dibaca, pembacaan berulang tidak memicu StrictMode. Periksa apakah Anda memanggil getSharedPreferences untuk pertama kali (pembacaan dingin) dan apakah kebijakan detectDiskReads aktif. Periksa juga apakah StrictMode tidak ditimpa di fragmen parent-free.
Di tes JUnit, gunakan StrictMode.allowThreadDiskReads() dan StrictMode.allowThreadDiskWrites() di @Before, dan di @After kembalikan pengaturan melalui StrictMode.enableDefaults(). Untuk tes Instrumentation, gunakan TestRunner kustom dengan penyimpanan sementara kebijakan asli. Di tes Espresso, mudah untuk membungkus kode yang rentan StrictMode di IdlingResource.
StrictMode hanya berfungsi di platform Android melalui Android SDK. Di Kotlin Multiplatform (KMP), kode commonMain tidak dapat menggunakan StrictMode, tetapi untuk androidMain Anda dapat menambahkannya seperti biasa. Untuk bagian iOS, gunakan analognya — DispatchQueue.main.async assertion untuk thread utama.
Kesimpulan
Kami akan mengembangkan aplikasi seluler turnkey
IT Sectr membuat aplikasi iOS dan Android untuk startup dan bisnis sejak 2017. Kami akan memberi saran dan mengusulkan solusi terbaik.
Baca juga