StrictMode: o que é, modo de regras estritas e depuração no Android

Autor: IT Sectr Publicado: 2026-03-31 Tempo de leitura: 8 min

StrictMode é uma ferramenta de desenvolvedor incorporada ao Android SDK que detecta e relata em tempo real operações acidentais de E/S e chamadas de rede na thread principal do aplicativo. Ela não corrige erros, mas atua como um detector — lança exceções ou escreve no LogCat quando as políticas configuradas são violadas. De acordo com Google, 2024, a configuração adequada do StrictMode pode detectar até 80% dos problemas de desempenho antes do lançamento do aplicativo.

Principais conclusões

  • StrictMode — um detector de violações de desempenho na thread principal do Android
  • Políticas de disco (disk_read, disk_write) e rede (network) formam o conjunto básico de verificações
  • A ferramenta não corrige problemas, mas notifica sobre eles via LogCat, diálogo ou crash
  • A configuração é feita no Application.onCreate usando setThreadPolicy + setVmPolicy
  • Modos de penalidade: lançamento de exceção (death), registro, notificação no dropbox

O que é StrictMode

StrictMode é uma API incluída no Android SDK desde o API Level 9 (Android 2.3 Gingerbread). Sua tarefa é detectar em tempo de execução a execução acidental de operações pesadas na thread principal (UI) que poderiam bloquear a renderização da interface. A thread principal lida com o processamento de entrada do usuário, cálculo de layout e renderização — qualquer bloqueio superior a 16 ms resulta em queda de quadro.

Filosofia da ferramenta

StrictMode segue o princípio de “falhar rápido” — detectar o problema o mais cedo possível, idealmente no momento de sua primeira aparição. Em vez de esperar reclamações de usuários sobre lentidão, o desenvolvedor recebe um sinal (logs, diálogo ou crash) diretamente na fase de desenvolvimento. A ferramenta não requer bibliotecas adicionais ou configuração do Gradle — apenas algumas linhas de código no Application.onCreate, e funciona automaticamente em todos os dispositivos.

Público-alvo

StrictMode é projetado para todos os desenvolvedores Android, independentemente da experiência. Para iniciantes, ajuda a formar bons hábitos (não fazer requisições de rede na thread de UI); para desenvolvedores experientes, automatiza o controle de qualidade no pipeline CI/CD. Grandes projetos (Google, Uber, Spotify) incluem StrictMode em builds de depuração com penaltyDeath, e o desativam em builds de lançamento através da verificação BuildConfig.DEBUG.

Como o StrictMode funciona

StrictMode intercepta chamadas de sistema que poderiam bloquear a thread e as compara com o conjunto de políticas ativas. Se uma chamada corresponde a uma política e é executada na thread principal, o StrictMode aplica a penalidade especificada. O mecanismo de interceptação é implementado através de um hook dentro do processo — não usa reflexão e opera com sobrecarga mínima.

Mecanismo de detecção

Quando a política do StrictMode é ativada, ele injeta seu manipulador nos pontos de entrada das chamadas de sistema (FileInputStream, FileOutputStream, Socket, URLConnection). Quando o aplicativo chama, por exemplo, URLConnection.openStream na thread principal, o StrictMode verifica a thread atual — se for a thread principal, a ferramenta é acionada. No Android 6.0+, o mecanismo é aprimorado: chamadas de rede na thread principal geram NetworkOnMainThreadException mesmo sem StrictMode, mas o StrictMode também permite controlar E/S de disco.

Penalidade

Cada política pode ter seu próprio tipo de penalidade ou combinação: penaltyLog — escreve no LogCat com stack trace, penaltyDialog — mostra um diálogo ao usuário (apenas debug), penaltyDeath — lança uma exceção e causa crash no aplicativo, penaltyDropBox — salva dados no DropBoxManager para análise posterior. Para pipelines CI/CD, penaltyDeath é recomendado — garante que nenhum merge com violações passe despercebido.

kotlin
class App : Application() {
    override fun onCreate() {
        super.onCreate()
        if (BuildConfig.DEBUG) {
            StrictMode.setThreadPolicy(
                StrictMode.ThreadPolicy.Builder()
                    .detectDiskReads()
                    .detectDiskWrites()
                    .detectNetwork()
                    .penaltyLog()
                    .penaltyDeath()
                    .build()
            )
        }
    }
}

Políticas do StrictMode

StrictMode divide as políticas em dois níveis: ThreadPolicy (nível de thread — o que não pode ser feito na thread principal) e VmPolicy (máquina virtual — vazamentos de memória e recursos). Ambos os níveis são configurados independentemente e funcionam em paralelo.

ThreadPolicy: Disco e Rede

No nível de thread, o StrictMode controla quatro tipos de violações: leituras de disco (detectDiskReads), escritas em disco (detectDiskWrites), operações de rede (detectNetwork) e chamadas lentas personalizadas (detectCustomSlowCalls). disk_read é acionado em qualquer leitura de SharedPreferences, SQLite ou arquivos na thread principal. network é acionado em requisições HTTP, WebSocket e conexões Socket. No Android 11+, foi adicionado detectUnbufferedIO para detectar E/S sem buffer.

VmPolicy: Vazamentos de Memória

VmPolicy controla vazamentos no nível da máquina virtual ART: detectActivityLeaks (atividades que não foram destruídas), detectLeakedClosableObjects (Cursor, Stream, Socket não fechados), detectLeakedRegistrationObjects (BroadcastReceiver, ServiceConnection não registrados). Se VmPolicy detectar que uma Activity foi criada mas não destruída após chamar onDestroy, ele exibe um stack trace completo — economizando horas de depuração de vazamentos de memória.

PolíticaNívelO que detecta
detectDiskReadsThreadLeitura de SharedPrefs, SQLite, arquivos na thread de UI
detectDiskWritesThreadEscrita em SharedPrefs, SQLite, arquivos na thread de UI
detectNetworkThreadQualquer operação de rede na thread de UI
detectActivityLeaksVMActivities que sobrevivem ao onDestroy
detectLeakedClosableObjectsVMCursor, Stream, Socket não fechados

Chamadas Lentas Personalizadas

Através de detectCustomSlowCalls, você pode marcar seus próprios métodos como “suspeitos” e receber um aviso quando um limite especificado for excedido. Por exemplo, se seu método loadUserProfile() normalmente leva 5 ms mas às vezes leva 200 ms — envolva-o em StrictMode.noteSlowCall(“loadUserProfile”). Se a duração exceder o limite (padrão 2000 ms), o StrictMode gerará uma penalidade. O limite é configurado através de setSlowCallDurationThreshold.

Como configurar o StrictMode

A configuração básica do StrictMode leva 10 linhas de código e é feita no método onCreate de uma classe Application personalizada. A regra principal: StrictMode é ativado apenas em builds de depuração — em builds de lançamento ele diminui a velocidade do aplicativo e pode criar falsos positivos.

Configuração básica

Crie uma classe que estenda Application, registre-a no AndroidManifest.xml através do atributo android:name e adicione a configuração do StrictMode. ThreadPolicy.Builder inclui todos os detectores e todos os tipos de penalidade (exceto dialog — funciona apenas quando um depurador está anexado). VmPolicy.Builder adiciona detectores para vazamentos de Activity e objetos Closable. Para projetos grandes (100+ telas), é recomendado configurar VmPolicy com penaltyDeath no detector de vazamentos de Activity — é rigoroso mas eficaz.

kotlin
class App : Application() {
    override fun onCreate() {
        super.onCreate()
        if (BuildConfig.DEBUG) {
            StrictMode.setVmPolicy(
                StrictMode.VmPolicy.Builder()
                    .detectActivityLeaks()
                    .detectLeakedClosableObjects()
                    .detectLeakedRegistrationObjects()
                    .penaltyLog()
                    .penaltyDeath()
                    .build()
            )
        }
    }
}

Integração CI/CD

Para controle automático em CI/CD, use penaltyDeath — se algum teste violar a política, o aplicativo falhará com uma exceção. Combine com Android Test Orchestrator para que cada teste seja executado em um processo limpo. Para testes de UI (Espresso, Compose Test), escreva um TestRule personalizado que intercepte violações do StrictMode e as transforme em falhas de assertion. Exemplo: em @Before, ative o StrictMode, e em @After, verifique se não houve violações.

Configuração de limites

Por padrão, o limite para customSlowCall é 2000 ms, para disk_read e disk_write — sem limite (qualquer operação aciona). Através de setSlowCallDurationThreshold e setSlowIoDurationThreshold, você pode definir seus próprios valores em milissegundos. Se seu aplicativo lê legitimamente SharedPreferences na thread principal (config pequena), aumente o limite para 10–20 ms — isso filtrará leituras rápidas enquanto mantém as lentas.

Melhores práticas do StrictMode

StrictMode é uma ferramenta poderosa mas delicada. Configuração incorreta leva a milhões de falsos positivos, fazendo com que os desenvolvedores parem de prestar atenção neles. Abaixo estão práticas comprovadas reunidas da experiência de grandes equipes Android.

Ativar apenas em builds de depuração

Esta é uma regra rígida: StrictMode NUNCA deve estar ativo em builds de lançamento. Use o flag BuildConfig.DEBUG ou um buildConfigField personalizado. Em builds de lançamento, muitas bibliotecas de terceiros legitimamente executam operações na thread principal (inicialização de SDK, escrita de cache), e o StrictMode criará falsos positivos. Além disso, penaltyDialog em um build de lançamento mostrará um diálogo ao usuário final — o que é inaceitável.

Usar três níveis de rigor

Para projetos pequenos (1–10 telas), configure penaltyLog — logs são suficientes para análise manual. Para projetos médios (10–50 telas), adicione penaltyDeath em network e customSlowCalls. Para projetos grandes (50+ telas), ative o conjunto completo de políticas com penaltyDeath em CI/CD, e penaltyLog para desenvolvimento local. Essa gradação evita sobrecarregar os desenvolvedores com falsos crashes enquanto controla rigorosamente a qualidade no pipeline.

Lidando com falsos positivos

Algumas bibliotecas (Firebase, Crashlytics, Adjust) legitimamente executam operações em segundo plano que o StrictMode pode detectar incorretamente. Soluções: adicione a biblioteca a uma lista branca através de penaltyListener, atualize a biblioteca para uma versão com comutação explícita para thread em segundo plano, ou use StrictMode.vmPolicy. No Android 11+, foi introduzido StrictMode.OnVmViolationListener para filtragem programática de violações por stack trace.

kotlin
// Filtrando falsos positivos através de penaltyListener
StrictMode.setThreadPolicy(
    StrictMode.ThreadPolicy.Builder()
        .detectAll()
        .penaltyListener { violation ->
            val stack = violation.stackTraceToString()
            if ("com.google.firebase" !in stack) {
                logViolation(violation)
            }
        }
        .build()
)

StrictMode vs Android Lint vs Profilers

StrictMode não é a única ferramenta de controle de qualidade no ecossistema Android. Para entender seu lugar, vamos compará-la com Android Lint, Android Profiler e Perfetto em critérios-chave: tempo de verificação, profundidade de análise e automação.

CritérioStrictModeAndroid LintProfiler / Perfetto
Tempo de verificaçãoRuntime (enquanto o app está executando)Tempo de compilação (antes do lançamento)Runtime (post-mortem)
O que verificaDisco, rede, vazamentosXML, código, recursosCPU, memória, rede, energia
AutomaçãoCI/CD via penaltyDeathTarefa Gradle + lint-baselineRequer análise manual
ProfundidadeApenas thread de UI e vazamentosAnálise estática de códigoImagem completa de desempenho
Falsos positivosMédios (dependem das bibliotecas)Baixos (regras configuradas)Nenhum (medições reais)

A melhor estratégia é combinar todas as três abordagens: Android Lint captura erros óbvios em tempo de compilação (por exemplo, um IdleHandler esquecido), StrictMode detecta problemas em tempo de execução, e Android Profiler / Perfetto é usado para análise profunda quando as duas primeiras ferramentas não fornecem respostas. Em projetos reais (Google Maps, Instagram), o StrictMode é introduzido na segunda semana de desenvolvimento — logo após configurar a arquitetura básica.

Exemplos de código com StrictMode

Vamos ver dois cenários reais onde o StrictMode ajuda a detectar e corrigir problemas de desempenho: leitura de SharedPreferences na thread principal e vazamento de Activity através de um callback não registrado.

Detectando SharedPreferences lentos

Na inicialização do aplicativo, o StrictMode com a política detectDiskReads detectará a leitura de SharedPreferences na thread principal. Solução: carregar a configuração assincronamente através de CoroutineScope ou armazenar em cache na memória na inicialização. SharedPreferences lê sincronamente um arquivo XML do disco — mesmo com um arquivo pequeno (1–2 KB), a operação leva de 1 a 5 ms, e até 20 ms em dispositivos baratos, o que pode causar queda de quadros.

kotlin
// ❌ Código problemático — leitura de SharedPrefs na thread de UI
class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        // StrictMode detectDiskReads → VIOLAÇÃO!
        prefs = getSharedPreferences("config", MODE_PRIVATE)
    }
}

// ✅ Código corrigido — leitura via Coroutine
class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        loadConfigAsync()
    }
}

Detectando vazamentos de Activity

StrictMode com VmPolicy.detectActivityLeaks detectará uma Activity que saiu da pilha (finish foi chamado) mas o objeto Activity permanece na memória devido a uma referência estática ou um callback não registrado. Cenário típico: registrar EventBus ou LocationListener em onResume sem chamar unregister em onPause. VmPolicy exibirá um stack trace indicando a linha onde a referência foi criada.

kotlin
// ❌ Vazamento — callback não cancelado
private var locationCallback: LocationCallback? = null

override fun onResume() {
    super.onResume()
    locationCallback = LocationCallback(this::onLocationUpdated)
    locationManager.register(locationCallback) // StrictMode → VAZAMENTO!
}

override fun onPause() {
    super.onPause()
    // Esqueceu: locationManager.unregister(locationCallback)
}

Perguntas frequentes

StrictMode diminui a velocidade do aplicativo?

StrictMode realmente adiciona uma pequena sobrecarga — cada chamada de sistema é verificada contra as políticas. O impacto no desempenho é de 1–3% em builds de depuração e está ausente em release (onde o StrictMode é desativado). Ao ativar detectAll em dispositivos antigos (Android 6–8), a sobrecarga pode chegar a 5%, por isso é recomendado configurar apenas as políticas necessárias.

StrictMode pode ser usado com Jetpack Compose?

Sim, StrictMode é totalmente compatível com Jetpack Compose. As políticas de disco e rede funcionam no nível do framework, independentemente do framework de UI. Além disso, no Compose a criticidade dos bloqueios de UI é maior — o Compose redesenha quadros a 120 FPS em dispositivos com alta taxa de atualização, então 5 ms extras na leitura de arquivo se tornam mais perceptíveis.

Por que o StrictMode não é acionado ao ler SharedPreferences?

A partir do Android 8.1 (API 27), o SharedPreferences pode usar cache em memória — se o arquivo já foi lido, a releitura não acionará o StrictMode. Certifique-se de estar chamando getSharedPreferences pela primeira vez (leitura a frio) e que a política detectDiskReads está ativa. Verifique também se o StrictMode não foi sobrescrito em um fragment sem pai.

Como desativar o StrictMode para testes individuais?

Em testes JUnit, use StrictMode.allowThreadDiskReads() e StrictMode.allowThreadDiskWrites() em @Before, e restaure as configurações em @After via StrictMode.enableDefaults(). Para testes de Instrumentação, use um TestRunner personalizado com preservação temporária da política original. Em testes Espresso, é conveniente envolver o código sensível ao StrictMode em um IdlingResource.

StrictMode é necessário no Kotlin Multiplatform?

StrictMode funciona apenas na plataforma Android através do Android SDK. No Kotlin Multiplatform (KMP), o código commonMain não pode usar StrictMode, mas para androidMain você pode adicioná-lo normalmente. Para a parte iOS, use um análogo — a asserção DispatchQueue.main.async para a thread principal.

Resumo

  • StrictMode — um detector em tempo de execução de problemas de desempenho na thread principal do Android
  • As políticas são divididas em ThreadPolicy (disco, rede) e VmPolicy (vazamentos de memória)
  • A configuração leva 10 linhas de código em Application.onCreate com uma verificação BuildConfig.DEBUG
  • Para CI/CD, use penaltyDeath — uma violação de política causa falha no aplicativo
  • StrictMode não substitui, mas complementa Android Lint e Perfetto
  • A filtragem adequada de falsos positivos é a chave para o uso eficaz da ferramenta
  • É recomendado introduzir StrictMode na segunda semana de desenvolvimento do projeto

Vamos desenvolver um aplicativo móvel chave na mão

A IT Sectr cria aplicativos para iOS e Android para startups e empresas desde 2017. Nós vamos aconselhá-lo e propor a melhor solução.

Discutir o projeto

Leia também