StrictMode, Android SDK'ya yerleşik bir geliştirici aracıdır ve uygulamanın ana iş parçacığındaki yanlışlıkla yapılan G/Ç işlemlerini ve ağ çağrılarını gerçek zamanlı olarak algılar ve raporlar. Hataları düzeltmez, ancak bir dedektör görevi görür — yapılandırılan politikalar ihlal edildiğinde istisnalar fırlatır veya LogCat'e yazar. Google, 2024'e göre, doğru StrictMode yapılandırması, uygulama yayınlanmadan önce performans sorunlarının %80'ine kadarını tespit edebilir.
Önemli Noktalar
StrictMode, API Seviye 9'dan (Android 2.3 Gingerbread) itibaren Android SDK'ya dahil edilen bir API'dir. Görevi, çalışma zamanında ana (UI) iş parçacığında UI oluşturmayı engelleyebilecek ağır işlemlerin yanlışlıkla yürütülmesini tespit etmektir. Ana iş parçacığı, kullanıcı girişi işleme, düzen hesaplama ve oluşturmayı yönetir — 16 ms'den uzun herhangi bir blok, kare düşüşüne neden olur.
StrictMode, “hızlı başarısız ol” ilkesini izler — sorunu mümkün olduğunca erken, ideal olarak ilk ortaya çıktığı anda tespit edin. Kullanıcıların yavaşlık şikayetlerini beklemek yerine, geliştirici geliştirme aşamasında doğrudan bir sinyal (günlükler, diyalog veya çökme) alır. Araç, ek kütüphane veya Gradle yapılandırması gerektirmez — sadece Application.onCreate'te birkaç satır kod ve tüm cihazlarda otomatik olarak çalışır.
StrictMode, deneyimden bağımsız olarak tüm Android geliştiricileri için tasarlanmıştır. Yeni başlayanlar için iyi alışkanlıklar oluşturmaya yardımcı olur (UI iş parçacığında ağ isteği yapmamak); deneyimli geliştiriciler için CI/CD hattında kalite kontrolünü otomatikleştirir. Büyük projeler (Google, Uber, Spotify), hata ayıklama yapılarında penaltyDeath ile StrictMode'u dahil eder ve BuildConfig.DEBUG kontrolü aracılığıyla sürüm yapılarında devre dışı bırakır.
StrictMode, iş parçacığını engelleyebilecek sistem çağrılarını yakalar ve bunları aktif politikalar kümesiyle karşılaştırır. Bir çağrı bir politikayla eşleşirse ve ana iş parçacığında yürütülürse, StrictMode belirtilen cezayı uygular. Yakalama mekanizması, süreç içi bir kanca aracılığıyla uygulanır — yansıma kullanmaz ve minimum ek yük ile çalışır.
StrictMode politikası etkinleştirildiğinde, işleyicisini sistem çağrılarının giriş noktalarına (FileInputStream, FileOutputStream, Socket, URLConnection) enjekte eder. Uygulama ana iş parçacığında, örneğin URLConnection.openStream çağrısı yaptığında, StrictMode geçerli iş parçacığını kontrol eder — ana iş parçacığıysa araç tetiklenir. Android 6.0+'da mekanizma güçlendirilmiştir: ana iş parçacığındaki ağ çağrıları, StrictMode olmasa bile NetworkOnMainThreadException üretir, ancak StrictMode disk G/Ç'sini de kontrol etmeye izin verir.
Her politikanın kendi ceza türü veya kombinasyonu olabilir: penaltyLog — yığın iziyle LogCat'e yazar, penaltyDialog — kullanıcıya bir diyalog gösterir (yalnızca hata ayıklama), penaltyDeath — istisna fırlatır ve uygulamayı çökertir, penaltyDropBox — daha sonra analiz için DropBoxManager'a veri kaydeder. CI/CD hatları için penaltyDeath önerilir — ihlal içeren hiçbir birleştirmenin fark edilmeden gitmemesini sağlar.
class App : Application() {
override fun onCreate() {
super.onCreate()
if (BuildConfig.DEBUG) {
StrictMode.setThreadPolicy(
StrictMode.ThreadPolicy.Builder()
.detectDiskReads()
.detectDiskWrites()
.detectNetwork()
.penaltyLog()
.penaltyDeath()
.build()
)
}
}
}
StrictMode politikaları iki seviyeye ayırır: ThreadPolicy (iş parçacığı seviyesi — ana iş parçacığında yapılamayacaklar) ve VmPolicy (sanal makine — bellek ve kaynak sızıntıları). Her iki seviye de bağımsız olarak yapılandırılır ve paralel olarak çalışır.
İş parçacığı seviyesinde, StrictMode dört tür ihlali kontrol eder: disk okumaları (detectDiskReads), disk yazmaları (detectDiskWrites), ağ işlemleri (detectNetwork) ve özel yavaş çağrılar (detectCustomSlowCalls). disk_read, ana iş parçacığında SharedPreferences, SQLite veya dosyaların herhangi bir okunmasında tetiklenir. network, HTTP istekleri, WebSocket ve Socket bağlantılarında tetiklenir. Android 11+'da, arabelleğe alınmamış G/Ç'yi tespit etmek için detectUnbufferedIO eklendi.
VmPolicy, ART sanal makine seviyesinde sızıntıları kontrol eder: detectActivityLeaks (yok edilmeyen aktiviteler), detectLeakedClosableObjects (kapatılmamış Cursor, Stream, Socket), detectLeakedRegistrationObjects (kaydı silinmemiş BroadcastReceiver, ServiceConnection). VmPolicy, bir Activity'nin oluşturulduğunu ancak onDestroy çağrısından sonra yok edilmediğini tespit ederse, tam bir yığın izi çıkarır — bu, bellek sızıntısı hata ayıklamada saatlerce zaman kazandırır.
| Politika | Seviye | Algıladığı |
|---|---|---|
| detectDiskReads | Thread | UI iş parçacığında SharedPrefs, SQLite, dosya okuma |
| detectDiskWrites | Thread | UI iş parçacığında SharedPrefs, SQLite, dosyalara yazma |
| detectNetwork | Thread | UI iş parçacığında herhangi bir ağ işlemi |
| detectActivityLeaks | VM | onDestroy'den sağ kalan aktiviteler |
| detectLeakedClosableObjects | VM | Kapatılmamış Cursor, Stream, Socket |
detectCustomSlowCalls aracılığıyla, kendi yöntemlerinizi “şüpheli” olarak işaretleyebilir ve belirtilen bir eşik aşıldığında uyarı alabilirsiniz. Örneğin, loadUserProfile() yönteminiz normalde 5 ms sürüyorsa ancak bazen 200 ms sürüyorsa — onu StrictMode.noteSlowCall(“loadUserProfile”) ile sarın. Süre eşiği (varsayılan 2000 ms) aşarsa, StrictMode bir ceza oluşturacaktır. Eşik, setSlowCallDurationThreshold aracılığıyla yapılandırılır.
Temel StrictMode yapılandırması 10 satır kod alır ve özel bir Application sınıfının onCreate yönteminde yapılır. Ana kural: StrictMode yalnızca hata ayıklama yapılarında etkinleştirilir — sürüm yapılarında uygulamayı yavaşlatır ve yanlış pozitifler oluşturabilir.
Application'ı genişleten bir sınıf oluşturun, android:name özelliği aracılığıyla AndroidManifest.xml'de kaydedin ve StrictMode yapılandırmasını ekleyin. ThreadPolicy.Builder tüm dedektörleri ve tüm ceza türlerini içerir (dialog hariç — yalnızca bir hata ayıklayıcı eklendiğinde çalışır). VmPolicy.Builder, Activity sızıntıları ve Closable nesneleri için dedektörler ekler. Büyük projeler (100+ ekran) için, Activity sızıntı dedektöründe penaltyDeath ile VmPolicy yapılandırmanız önerilir — katı ama etkilidir.
class App : Application() {
override fun onCreate() {
super.onCreate()
if (BuildConfig.DEBUG) {
StrictMode.setVmPolicy(
StrictMode.VmPolicy.Builder()
.detectActivityLeaks()
.detectLeakedClosableObjects()
.detectLeakedRegistrationObjects()
.penaltyLog()
.penaltyDeath()
.build()
)
}
}
}
CI/CD'de otomatik kontrol için penaltyDeath kullanın — herhangi bir test politikayı ihlal ederse, uygulama bir istisna ile çökecektir. Her testin temiz bir süreçte çalışması için Android Test Orchestrator ile birleştirin. UI testleri (Espresso, Compose Test) için, StrictMode ihlallerini yakalayan ve bunları assertions hatasına dönüştüren özel bir TestRule yazın. Örnek: @Before'da StrictMode'u etkinleştirin ve @After'da ihlal olmadığını kontrol edin.
Varsayılan olarak, customSlowCall için eşik 2000 ms'dir, disk_read ve disk_write için — eşik yoktur (herhangi bir işlem tetikler). setSlowCallDurationThreshold ve setSlowIoDurationThreshold aracılığıyla milisaniye cinsinden kendi değerlerinizi ayarlayabilirsiniz. Uygulamanız ana iş parçacığında SharedPreferences'ı meşru olarak okuyorsa (küçük yapılandırma), eşiği 10–20 ms'ye yükseltin — bu, hızlı okumaları filtrelerken yavaş okumaları tutacaktır.
StrictMode güçlü ama hassas bir araçtır. Yanlış yapılandırma milyonlarca yanlış pozitife yol açar ve geliştiricilerin bunlara dikkat etmeyi bırakmasına neden olur. Aşağıda, büyük Android ekiplerinin deneyimlerinden toplanan kanıtlanmış uygulamalar bulunmaktadır.
Bu kesin bir kuraldır: StrictMode sürüm yapılarında ASLA aktif olmamalıdır. BuildConfig.DEBUG bayrağını veya özel bir buildConfigField kullanın. Sürüm yapılarında, birçok üçüncü taraf kütüphane ana iş parçacığında meşru olarak işlemler gerçekleştirir (SDK başlatma, önbellek yazma) ve StrictMode yanlış pozitifler oluşturacaktır. Ayrıca, sürüm yapısında penaltyDialog son kullanıcıya bir diyalog gösterecektir — bu kabul edilemez.
Küçük projeler (1–10 ekran) için penaltyLog yapılandırın — günlükler manuel analiz için yeterlidir. Orta boy projeler (10–50 ekran) için ağ ve customSlowCalls'a penaltyDeath ekleyin. Büyük projeler (50+ ekran) için CI/CD'de penaltyDeath ile tam politika setini etkinleştirin ve yerel geliştirme için penaltyLog kullanın. Bu aşamalı yaklaşım, geliştiricileri yanlış çökmelerle aşırı yüklemekten kaçınırken hattaki kaliteyi sıkı bir şekilde kontrol eder.
Bazı kütüphaneler (Firebase, Crashlytics, Adjust) meşru olarak arka plan işlemleri gerçekleştirir ve StrictMode bunları yanlışlıkla algılayabilir. Çözümler: penaltyListener aracılığıyla kütüphaneyi bir beyaz listeye ekleyin, kütüphaneyi açıkça arka plan iş parçacığına geçiş yapan bir sürüme güncelleyin veya StrictMode.vmPolicy kullanın. Android 11+'da, yığın izine göre ihlallerin programlı olarak filtrelenmesi için StrictMode.OnVmViolationListener tanıtıldı.
// penaltyListener aracılığıyla yanlış pozitifleri filtreleme
StrictMode.setThreadPolicy(
StrictMode.ThreadPolicy.Builder()
.detectAll()
.penaltyListener { violation ->
val stack = violation.stackTraceToString()
if ("com.google.firebase" !in stack) {
logViolation(violation)
}
}
.build()
)
StrictMode, Android ekosistemindeki tek kalite kontrol aracı değildir. Yerini anlamak için, temel kriterlere göre Android Lint, Android Profiler ve Perfetto ile karşılaştıralım: kontrol süresi, analiz derinliği ve otomasyon.
| Kriter | StrictMode | Android Lint | Profiler / Perfetto |
|---|---|---|---|
| Kontrol süresi | Çalışma zamanı (uygulama çalışırken) | Derleme zamanı (başlatmadan önce) | Çalışma zamanı (ölüm sonrası) |
| Kontrol ettiği | Disk, ağ, sızıntılar | XML, kod, kaynaklar | CPU, bellek, ağ, enerji |
| Otomasyon | penaltyDeath ile CI/CD | Gradle görevi + lint-baseline | Manuel analiz gerektirir |
| Derinlik | Yalnızca UI iş parçacığı ve sızıntılar | Statik kod analizi | Tam performans resmi |
| Yanlış pozitifler | Orta (kütüphanelere bağlı) | Düşük (yapılandırılmış kurallar) | Hiçbiri (gerçek ölçümler) |
En iyi strateji, üç yaklaşımı da birleştirmektir: Android Lint derleme zamanında bariz hataları yakalar (örneğin, unutulmuş bir IdleHandler), StrictMode çalışma zamanında sorunları tespit eder ve Android Profiler / Perfetto ilk iki araç yanıt vermediğinde derinlemesine analiz için kullanılır. Gerçek projelerde (Google Maps, Instagram), StrictMode geliştirmenin ikinci haftasında — temel mimari kurulduktan hemen sonra tanıtılır.
StrictMode'un performans sorunlarını tespit etmeye ve düzeltmeye yardımcı olduğu iki gerçek senaryoya bakalım: ana iş parçacığında SharedPreferences okuma ve kaydı silinmemiş bir geri çağırma yoluyla Activity sızıntısı.
Uygulama başlangıcında, detectDiskReads politikasına sahip StrictMode, ana iş parçacığında SharedPreferences okumasını tespit edecektir. Çözüm: yapılandırmayı CoroutineScope aracılığıyla eşzamansız olarak yükleyin veya başlangıçta bellekte önbelleğe alın. SharedPreferences, diskten bir XML dosyasını eşzamanlı olarak okur — küçük bir dosyada (1–2 KB) bile işlem 1–5 ms sürer ve ucuz cihazlarda 20 ms'ye kadar çıkarak kare düşüşüne neden olabilir.
// ❌ Sorunlu kod — UI iş parçacığında SharedPrefs okuma
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
// StrictMode detectDiskReads → İHLAL!
prefs = getSharedPreferences("config", MODE_PRIVATE)
}
}
// ✅ Düzeltilmiş kod — Coroutine ile okuma
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
loadConfigAsync()
}
}
VmPolicy.detectActivityLeaks ile StrictMode, yığından çıkmış (finish çağrılmış) ancak statik bir referans veya kaydı silinmemiş bir geri çağırma nedeniyle Activity nesnesi bellekte kalmaya devam eden bir Activity'i tespit edecektir. Tipik senaryo: onPause'da unregister çağırmadan onResume'da EventBus veya LocationListener kaydetmek. VmPolicy, referansın oluşturulduğu satırı belirten bir yığın izi çıkaracaktır.
// ❌ Sızıntı — geri çağırma iptal edilmedi
private var locationCallback: LocationCallback? = null
override fun onResume() {
super.onResume()
locationCallback = LocationCallback(this::onLocationUpdated)
locationManager.register(locationCallback) // StrictMode → SIZINTI!
}
override fun onPause() {
super.onPause()
// Unuttunuz: locationManager.unregister(locationCallback)
}
Sıkça Sorulan Sorular
StrictMode gerçekten küçük bir ek yük ekler — her sistem çağrısı politikalar açısından kontrol edilir. Performans etkisi hata ayıklama yapılarında %1–3'tür ve sürüm yapılarında (StrictMode'un devre dışı olduğu) yoktur. Eski cihazlarda (Android 6–8) detectAll etkinleştirildiğinde, ek yük %5'e ulaşabilir, bu nedenle yalnızca gerekli politikaların yapılandırılması önerilir.
Evet, StrictMode Jetpack Compose ile tamamen uyumludur. Disk ve ağ politikaları, UI çerçevesinden bağımsız olarak çerçeve seviyesinde çalışır. Ayrıca, Compose'da UI bloklarının kritikliği daha yüksektir — Compose, yüksek yenileme hızına sahip cihazlarda kareleri 120 FPS'de yeniden çizer, bu nedenle dosya okumada fazladan 5 ms daha belirgin hale gelir.
Android 8.1'den (API 27) itibaren, SharedPreferences bellek önbelleğe alma kullanabilir — dosya zaten okunmuşsa, yeniden okuma StrictMode'u tetiklemez. getSharedPreferences'i ilk kez çağırdığınızdan (soğuk okuma) ve detectDiskReads politikasının aktif olduğundan emin olun. Ayrıca StrictMode'un ebeveynsiz bir fragmentte geçersiz kılınmadığını kontrol edin.
JUnit testlerinde, @Before'da StrictMode.allowThreadDiskReads() ve StrictMode.allowThreadDiskWrites() kullanın ve @After'da StrictMode.enableDefaults() aracılığıyla ayarları geri yükleyin. Enstrümantasyon testleri için, orijinal politikanın geçici olarak korunmasıyla özel bir TestRunner kullanın. Espresso testlerinde, StrictMode'a duyarlı kodu bir IdlingResource içine sarmak uygundur.
StrictMode yalnızca Android SDK aracılığıyla Android platformunda çalışır. Kotlin Multiplatform'da (KMP), commonMain kodu StrictMode'u kullanamaz, ancak androidMain için her zamanki gibi ekleyebilirsiniz. iOS kısmı için bir analog kullanın — ana iş parçacığı için DispatchQueue.main.async iddiası.
Özet
Anahtar teslim bir mobil uygulama geliştireceğiz
IT Sectr, 2017'den beri girişimler ve işletmeler için iOS ve Android uygulamaları oluşturmaktadır. Size danışmanlık yapacak ve en iyi çözümü önereceğiz.
Ayrıca okuyun