StrictMode — bu Android SDK ga o‘rnatilgan ishlab chiquvchi vositasi bo‘lib, real vaqt rejimida tasodifiy kiritish/chiqarish operatsiyalari va asosiy ipdagi tarmoq chaqiruvlarini aniqlaydi va xabar beradi. U xatolarni tuzatmaydi, balki detektor vazifasini bajaradi — belgilangan siyosatlar buzilganda istisno tashlaydi yoki LogCat ga yozadi. Google, 2024 ma’lumotlariga ko‘ra, StrictMode ni to‘g‘ri sozlash dastur chiqishidan oldin ishlash muammolarining 80% gacha aniqlash imkonini beradi.
Asosiy ma’lumotlar
StrictMode — bu API Level 9 (Android 2.3 Gingerbread) dan boshlab Android SDK ga kiritilgan API. Uning vazifasi — ishlash vaqtida asosiy (UI) ipida interfeys renderini bloklashi mumkin bo‘lgan og‘ir operatsiyalarni aniqlash. Asosiy ip foydalanuvchi kiritishini qayta ishlash, maketni hisoblash va render uchun javobgardir — 16 ms dan ortiq har qanday bloklash kadr o‘tkazib yuborilishiga olib keladi.
StrictMode fail fast
tamoyiliga amal qiladi — muammoni imkon qadar erta, afzal uning birinchi paydo bo‘lish momentida aniqlash. Foydalanuvchilarning sekinlashuv haqidagi shikoyatlarini kutish o‘rniga, ishlab chiquvchi signalni (log, dialog yoki crash) to‘g‘ridan-to‘g‘ri ishlab chiqish bosqichida oladi. Vosita qo‘shimcha kutubxonalar va Gradle konfiguratsiyasini talab qilmaydi — Application.onCreate da bir necha qator kod yetarli va u barcha qurilmalarda avtomatik ishlaydi.
StrictMode barcha Android ishlab chiquvchilari uchun mo‘ljallangan, tajribadan qat’i nazar. Yangi boshlovchilarga to‘g‘ri odatlarni shakllantirishga yordam beradi (UI ipida tarmoq so‘rovlarini bajarmaslik), tajribalilarga — CI/CD quvurida sifat nazoratini avtomatlashtirishga. Katta loyihalar (Google, Uber, Spotify) StrictMode ni penaltyDeath bilan debug yig‘ilishlariga qo‘shadi va release yig‘ilishlarida BuildConfig.DEBUG tekshiruvi orqali o‘chiradi.
StrictMode ipni bloklashi mumkin bo‘lgan tizim chaqiruvlarini ushlaydi va ularni faol siyosatlar to‘plami bilan solishtiradi. Agar chaqiruv siyosatga mos kelsa va asosiy ipda bajarilsa, StrictMode belgilangan penalty (jazo) ni qo‘llaydi. Tutib olish mexanizmi ichki jarayonli hook orqali amalga oshiriladi — u reflection dan foydalanmaydi va minimal overhead bilan ishlaydi.
Siyosat faollashtirilganda, StrictMode o‘z ishlovchisini tizim chaqiruvlari kirish nuqtasiga (FileInputStream, FileOutputStream, Socket, URLConnection) kiritadi. Dastur, masalan, asosiy ipda URLConnection.openStream ni chaqirganda, StrictMode joriy ipni tekshiradi — agar main thread bo‘lsa, vosita ishga tushadi. Android 6.0+ da mexanizm kuchaytirilgan: main thread dagi tarmoq chaqiruvlari StrictMode siz ham NetworkOnMainThreadException ni hosil qiladi, ammo StrictMode disk I/O ni ham nazorat qilish imkonini beradi.
Har bir siyosat o‘ziga xos penalty turiga yoki kombinatsiyasiga ega bo‘lishi mumkin: penaltyLog — stack trace bilan LogCat ga yozish, penaltyDialog — foydalanuvchiga dialog ko‘rsatish (faqat debug da), penaltyDeath — istisno tashlash va dasturni crash qilish, penaltyDropBox — keyingi tahlil uchun DropBoxManager ga ma’lumotlarni saqlash. CI/CD quvuri uchun penaltyDeath tavsiya etiladi — bu hech qanday buzilish bilan merge sezilmasdan o‘tmasligini kafolatlaydi.
class App : Application() {
override fun onCreate() {
super.onCreate()
if (BuildConfig.DEBUG) {
StrictMode.setThreadPolicy(
StrictMode.ThreadPolicy.Builder()
.detectDiskReads()
.detectDiskWrites()
.detectNetwork()
.penaltyLog()
.penaltyDeath()
.build()
)
}
}
}
StrictMode siyosatlarni ikki darajaga ajratadi: ThreadPolicy (ip bo‘yicha — asosiy ipda nima qilish mumkin emas) va VmPolicy (virtual mashina — xotira va resurs oqishlari). Ikkala daraja mustaqil ravishda sozlanadi va parallel ishlaydi.
Ip darajasida StrictMode to‘rt turdagi buzilishlarni nazorat qiladi: diskdan o‘qish (detectDiskReads), diskka yozish (detectDiskWrites), tarmoq operatsiyalari (detectNetwork) va foydalanuvchi sekin chaqiruvlari (detectCustomSlowCalls). disk_read asosiy ipda SharedPreferences, SQLite, fayllarni o‘qishda ishga tushadi. network — HTTP so‘rovlari, WebSocket, Socket ulanishlari paytida. Android 11+ da buferlanmagan kiritish/chiqarishni aniqlash uchun detectUnbufferedIO qo‘shilgan.
VmPolicy ART virtual mashina darajasida oqishlarni nazorat qiladi: detectActivityLeaks (yo‘q qilinmagan Activity), detectLeakedClosableObjects (yopilmagan Cursor, Stream, Socket), detectLeakedRegistrationObjects (bekor qilinmagan BroadcastReceiver, ServiceConnection). Agar VmPolicy Activity yaratilgan, ammo onDestroy chaqirilganidan keyin yo‘q qilinmaganligini aniqlasa, u to‘liq stack trace ni chiqaradi — bu xotira oqishlarini tuzatishda soatlab vaqtni tejaydi.
| Siyosat | Daraja | Nimani aniqlaydi |
|---|---|---|
| detectDiskReads | Thread | SharedPrefs, SQLite, fayllarni UI ipida o‘qish |
| detectDiskWrites | Thread | SharedPrefs, SQLite, fayllarga UI ipida yozish |
| detectNetwork | Thread | UI ipidagi har qanday tarmoq operatsiyalari |
| detectActivityLeaks | VM | onDestroy dan omon qolgan Activity |
| detectLeakedClosableObjects | VM | Yopilmagan Cursor, Stream, Socket |
detectCustomSlowCalls orqali o‘z metodlaringizni shubhali
deb belgilashingiz va belgilangan chegaradan oshib ketganda ogohlantirish olishingiz mumkin. Masalan, loadUserProfile() metodingiz odatda 5 ms bajarilsa, lekin ba’zi hollarda 200 ms davom etsa — uni StrictMode.noteSlowCall(loadUserProfile
) ga o‘rang. Agar davomiylik chegaradan (odatda 2000 ms) oshsa, StrictMode penalty yaratadi. Chegara setSlowCallDurationThreshold orqali sozlanadi.
StrictMode ni asosiy sozlash 10 qator kodni oladi va maxsus Application sinfining onCreate metodida amalga oshiriladi. Asosiy qoida: StrictMode faqat debug yig‘ilishlarida yoqiladi — release yig‘ilishlarida u dasturni sekinlashtiradi va noto‘g‘ri ishga tushishlarni keltirib chiqarishi mumkin.
Application dan meros oladigan sinf yarating, uni AndroidManifest.xml da android:name atributi orqali ro‘yxatdan o‘tkazing va StrictMode konfiguratsiyasini qo‘shing. ThreadPolicy.Builder barcha detektorlar va barcha penalty turlarini yoqadi (dialog dan tashqari — u faqat debugger ulanganda ishlaydi). VmPolicy.Builder Activity oqishlari va Closable obyektlar detektorlarini qo‘shadi. Katta loyihalar (100+ ekran) uchun VmPolicy ni Activity Leaks detektori bilan penaltyDeath da sozlash tavsiya etiladi — bu qattiq, ammo samarali.
class App : Application() {
override fun onCreate() {
super.onCreate()
if (BuildConfig.DEBUG) {
StrictMode.setVmPolicy(
StrictMode.VmPolicy.Builder()
.detectActivityLeaks()
.detectLeakedClosableObjects()
.detectLeakedRegistrationObjects()
.penaltyLog()
.penaltyDeath()
.build()
)
}
}
}
CI/CD da avtomatik nazorat uchun penaltyDeath dan foydalaning — agar biron test siyosatni buzsa, dastur istisno bilan crash qiladi. Android Test Orchestrator bilan birlashtiring, har bir test toza jarayonda ishga tushsin. UI testlari (Espresso, Compose Test) uchun StrictMode buzilishlarini ushlaydigan va ularni assertion failure ga aylantiradigan maxsus TestRule yozing. Misol: @Before da StrictMode ni yoqing va @After da violations yo‘qligini tekshiring.
Odatiy bo‘yicha customSlowCall chegarasi — 2000 ms, disk_read va disk_write uchun — chegarasiz (har qanday operatsiya ishga tushiradi). setSlowCallDurationThreshold va setSlowIoDurationThreshold orqali o‘z qiymatlaringizni millisekundlarda belgilashingiz mumkin. Agar dasturingiz asosiy ipda SharedPreferences ni qonuniy ravishda o‘qisa (kichik konfig), chegarani 10–20 ms gacha oshiring — bu tez o‘qishlarni kesadi, ammo sekinlarini qoldiradi.
StrictMode — kuchli, ammo injiq vosita. Noto‘g‘ri sozlash millionlab noto‘g‘ri ishga tushishlarga olib keladi, buning natijasida ishlab chiquvchilar ularga e’tibor berishni to‘xtatadilar. Quyida — yirik Android jamoalari tajribasidan to‘plangan tasdiqlangan amaliyotlar keltirilgan.
Bu temir qoida: StrictMode hech qachon release yig‘ilishlarida faol bo‘lmasligi kerak. BuildConfig.DEBUG bayrog‘i yoki maxsus buildConfigField dan foydalaning. Release yig‘ilishlarida ko‘plab uchinchi tomon kutubxonalari qonuniy ravishda asosiy ipda operatsiyalarni bajaradi (SDK ishga tushirish, kesh yozish), va StrictMode noto‘g‘ri ishga tushishlarni yaratadi. Bundan tashqari, penaltyDialog release yig‘ilishida oxirgi foydalanuvchiga dialog ko‘rsatadi — bu qabul qilib bo‘lmaydi.
Kichik loyihalar (1–10 ekran) uchun penaltyLog ni sozlang — qo‘lda tahlil qilish uchun loglar yetarli. O‘rta loyihalar (10–50 ekran) uchun network va customSlowCalls ga penaltyDeath qo‘shing. Katta loyihalar (50+ ekran) uchun CI/CD da penaltyDeath bilan to‘liq siyosatlar to‘plamini yoqing va mahalliy ishlab chiqish uchun — penaltyLog. Bunday gradatsiya ishlab chiquvchini noto‘g‘ri crashlar bilan ortiqcha yuklamaydi, ammo quvurda sifatni qat’iy nazorat qiladi.
Ba’zi kutubxonalar (Firebase, Crashlytics, Adjust) qonuniy ravishda fonda operatsiyalarni bajaradi, StrictMode ularni noto‘g‘ri aniqlashi mumkin. Yechimlar: kutubxonani penaltyListener orqali whitelist ga qo‘shing, kutubxonani background thread ga aniq o‘tish bilan versiyasiga yangilang yoki StrictMode.vmPolicy dan foydalaning. Android 11+ da stacktrace bo‘yicha buzilishlarni dasturiy filtrlash uchun StrictMode.OnVmViolationListener paydo bo‘ldi.
// False positives larni penaltyListener orqali filtrlash
StrictMode.setThreadPolicy(
StrictMode.ThreadPolicy.Builder()
.detectAll()
.penaltyListener { violation ->
val stack = violation.stackTraceToString()
if ("com.google.firebase" !in stack) {
logViolation(violation)
}
}
.build()
)
StrictMode Android ekotizimidagi yagona sifat nazorat vositasi emas. Uning o‘rnini tushunish uchun uni Android Lint, Android Profiler va Perfetto bilan asosiy mezonlar bo‘yicha solishtiramiz: tekshirish vaqti, tahlil chuqurligi va avtomatlashtirish.
| Mezon | StrictMode | Android Lint | Profiler / Perfetto |
|---|---|---|---|
| Tekshirish vaqti | Runtime (dastur ishlash vaqtida) | Compile time (ishga tushirishdan oldin) | Runtime (post-mortem) |
| Nimani tekshiradi | Disk, tarmoq, oqishlar | XML, kod, resurslar | CPU, xotira, tarmoq, energiya |
| Avtomatlashtirish | CI/CD penaltyDeath orqali | Gradle task + lint-baseline | Qo‘lda tahlil talab qiladi |
| Chuqurlik | Faqat UI ip va oqishlar | Kodni statik tahlil qilish | Ishlashning to‘liq tasviri |
| Noto‘g‘ri ishga tushishlar | O‘rtacha (kutubxonalarga bog‘liq) | Kam (sozlangan qoidalar) | Yo‘q (haqiqiy o‘lchovlar) |
Eng yaxshi strategiya — uchala yondashuvni birlashtirish: Android Lint kompilyatsiya bosqichida aniq xatolarni tutadi (masalan, unutilgan IdleHandler), StrictMode ishlash vaqtida muammolarni aniqlaydi, va Android Profiler / Perfetto birinchi ikkita vosita javob bermaganda chuqur tahlil uchun ishlatiladi. Haqiqiy loyihalarda (Google Maps, Instagram) StrictMode ishlab chiqishning ikkinchi haftasida — asosiy arxitektura sozlanganidan so‘ng darhol joriy qilinadi.
StrictMode ishlash muammolarini aniqlash va bartaraf etishga yordam beradigan ikkita real stsenariyni ko‘rib chiqamiz: asosiy ipda SharedPreferences o‘qish va ro‘yxatdan o‘tkazilmagan callback orqali Activity oqishi.
Dastur ishga tushganda, StrictMode detectDiskReads siyosati bilan asosiy ipda SharedPreferences o‘qilishini aniqlaydi. Yechish: konfiguratsiyani CoroutineScope orqali asinxron yuklang yoki ishga tushirishda xotiraga keshlang. SharedPreferences XML faylni diskdan sinxron o‘qiydi — hatto kichik fayl (1–2 KB) bilan operatsiya 1–5 ms davom etadi va arzon qurilmalarda 20 ms gacha, bu kadr o‘tkazib yuborilishiga olib kelishi mumkin.
// ❌ Muammoli kod — SharedPrefs ni UI ipida o‘qish
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
// StrictMode detectDiskReads → VIOLATION!
prefs = getSharedPreferences("config", MODE_PRIVATE)
}
}
// ✅ Tuzatilgan kod — Coroutine orqali o‘qish
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
loadConfigAsync()
}
}
StrictMode VmPolicy.detectActivityLeaks bilan stekdan chiqqan (finish chaqirilgan) Activity ni aniqlaydi, ammo Activity obyekti statik havola yoki ro‘yxatdan o‘tkazilmagan callback tufayli xotirada qoladi. Odatiy stsenariy: onResume da EventBus yoki LocationListener ni onPause da unregister chaqirmasdan ro‘yxatdan o‘tkazish. VmPolicy havola yaratilgan qatorni ko‘rsatadigan stack trace ni chiqaradi.
// ❌ Oqish — callback bekor qilinmagan
private var locationCallback: LocationCallback? = null
override fun onResume() {
super.onResume()
locationCallback = LocationCallback(this::onLocationUpdated)
locationManager.register(locationCallback) // StrictMode → LEAK!
}
override fun onPause() {
super.onPause()
// Unutdingiz: locationManager.unregister(locationCallback)
}
Ko‘p beriladigan savollar
StrictMode haqiqatan ham ozgina overhead qo‘shadi — har bir tizim chaqiruvi siyosatlarga muvofiqligi tekshiriladi. Ishlashga ta’sir debug yig‘ilishida 1–3% ni tashkil qiladi va release da yo‘q (bu yerda StrictMode o‘chirilgan). Eski qurilmalarda (Android 6–8) detectAll yoqilganda overhead 5% gacha yetishi mumkin, shuning uchun faqat kerakli siyosatlarni sozlash tavsiya etiladi.
Ha, StrictMode Jetpack Compose bilan to‘liq mos keladi. Disk va network siyosatlari UI freymvorkidan mustaqil ravishda freymvork darajasida ishlaydi. Bundan tashqari, Compose da UI blokirovkalarining muhimligi yuqoriroq — Compose yuqori yangilanish chastotasiga ega qurilmalarda 120 FPS chastotada kadrlarni qayta chizadi, shuning uchun fayl o‘qish uchun qo‘shimcha 5 ms sezilarli bo‘ladi.
Android 8.1 (API 27) dan boshlab, SharedPreferences xotiraga keshlash dan foydalanishi mumkin — agar fayl allaqachon o‘qilgan bo‘lsa, qayta o‘qish StrictMode ni ishga tushirmaydi. getSharedPreferences ni birinchi marta chaqirayotganingizni (sovuq o‘qish) va detectDiskReads siyosati faol ekanligini tekshiring. Shuningdek, StrictMode parent-free fragment da qayta belgilanmaganligini tekshiring.
JUnit testlarida @Before da StrictMode.allowThreadDiskReads() va StrictMode.allowThreadDiskWrites() dan, @After da esa StrictMode.enableDefaults() orqali sozlamalarni qaytaring. Instrumentation testlari uchun asl siyosatni vaqtinchalik saqlaydigan maxsus TestRunner dan foydalaning. Espresso testlarida StrictMode ga zaif kodni IdlingResource ga o‘rash qulay.
StrictMode faqat Android platformasida Android SDK orqali ishlaydi. Kotlin Multiplatform (KMP) da commonMain kodi StrictMode dan foydalana olmaydi, ammo androidMain uchun uni odatdagidek qo‘shishingiz mumkin. iOS qismi uchun uning analogidan — asosiy ip uchun DispatchQueue.main.async assertion dan foydalaning.
Xulosa
Biz kalit topshirig'i bilan mobil ilovani ishlab chiqamiz
IT Sectr 2017-yildan beri startaplar va korxonalar uchun iOS va Android ilovalarini yaratadi. Biz sizga maslahat beramiz va eng yaxshi yechimni taklif qilamiz.