Instruções

A aplicação da qualidade técnica da bateria chegou: como otimizar casos de uso comuns de wake locks

Leitura de 8 minutos
Alice Yuan
Engenheira de relações com desenvolvedores

Reconhecendo que o consumo elevado da bateria é o mais lembrado para os usuários do Android, o Google tem tomado medidas significativas para ajudar os desenvolvedores a criar apps mais eficientes em termos de energia. Em 1º de março de 2026, a Google Play Store começou a lançar os tratamentos de qualidade técnica de wake locks para melhorar o consumo de bateria. Esse tratamento será lançado gradualmente para os apps afetados nas próximas semanas. Os apps que excedem consistentemente o limite de "Wake lock parcial excessivo" no Android vitals podem ter impactos tangíveis na presença da loja, incluindo avisos na página "Detalhes do app" e exclusão de plataformas de descoberta, como recomendações.

appDetails.png

Os usuários podem ver um aviso na página "Detalhes do app" se o app exceder o limite de mau comportamento. 

Essa iniciativa elevou a eficiência da bateria a uma métrica vital principal, juntamente com métricas de estabilidade, como falhas e ANRs. O "limite de mau comportamento" é definido como manter um wake lock parcial não isento por pelo menos duas horas em média enquanto a tela está desligada em mais de 5% das sessões de usuários nos últimos 28 dias. Um wake lock é isento se for um wake lock mantido pelo sistema que oferece benefícios claros ao usuário que não podem ser otimizados ainda mais, como reprodução de áudio, acesso à localização ou transferência de dados iniciada pelo usuário. Consulte a definição completa de wake locks excessivos na nossa documentação do Android vitals.

Como parte da nossa iniciativa contínua para melhorar a duração da bateria em todo o ecossistema Android, analisamos milhares de apps e como eles usam wake locks parciais. Embora os wake locks sejam às vezes necessários, geralmente vemos apps que os mantêm de forma ineficiente ou desnecessária, quando existem soluções mais eficientes. Este blog abordará os cenários mais comuns em que wake locks excessivos ocorrem e nossas recomendações para otimizar os wake locks.Já observamos um sucesso mensurável de parceiros como a WHOOP, que aproveitou essas recomendações para otimizar o comportamento em segundo plano.

Como usar um serviço em primeiro plano em vez de wake locks parciais

Muitas vezes, os desenvolvedores têm dificuldade em entender a diferença entre dois conceitos ao fazer a execução em segundo plano: serviço em primeiro plano e wake locks parciais.

Um serviço em primeiro plano é uma API de ciclo de vida que sinaliza ao sistema que um app está realizando um trabalho perceptível pelo usuário e não deve ser encerrado para recuperar memória, mas não impede automaticamente que a CPU entre em modo de espera quando a tela é desligada. Em contraste, um wake lock parcial é um mecanismo projetado especificamente para manter a CPU em execução mesmo quando a tela está desligada. 

Embora um serviço em primeiro plano seja muitas vezes necessário para continuar uma ação do usuário, uma aquisição manual de um wake lock parcial só é necessária em conjunto com um serviço em primeiro plano durante a atividade da CPU. Além disso, não é necessário usar um wake lock se você já estiver usando uma API que mantém o dispositivo ativo. 

Consulte o fluxograma em Escolher a API certa para manter o dispositivo ativo para garantir que você tenha um bom entendimento de qual ferramenta usar para evitar a aquisição de um wake lock em cenários em que ele não é necessário.

Bibliotecas de terceiros que adquirem wake locks

É comum que um app descubra que foi sinalizado por wake locks excessivos mantidos por um SDK de terceiros ou uma API do sistema agindo em nome dele. Para identificar e resolver esses wake locks, recomendamos as seguintes etapas:

  • Verificar o Android vitals: encontre o nome exato do wake lock ofensivo no painel de wake locks parciais excessivos. Compare este nome com as orientações Identificar wake locks criados por outras APIs para saber se ele foi criado por uma API do sistema conhecida ou uma biblioteca Jetpack. Se for, talvez seja necessário otimizar o uso da API e consultar as orientações recomendadas.
  • Capturar um rastreamento do sistema:se o wake lock não puder ser identificado facilmente, reproduza o problema do wake lock localmente usando um rastreamento do sistema e inspecione-o com a interface do Perfetto. Saiba mais sobre como fazer isso na seção __Depurar outros tipos de wake locks excessivos__ desta postagem do blog.
  • Avaliar alternativas:se uma biblioteca de terceiros ineficiente for responsável e não puder ser configurada para respeitar a duração da bateria, considere comunicar o problema aos proprietários do SDK, encontrar um SDK alternativo ou criar a funcionalidade internamente.

Cenários comuns de wake locks

Confira abaixo uma análise de alguns dos casos de uso específicos que analisamos, juntamente com o caminho recomendado para otimizar a implementação de wake locks.

Upload ou download iniciado pelo usuário

Exemplos de casos de uso:

  • Apps de streaming de vídeo em que o usuário aciona o download de um arquivo grande para acesso off-line.
  • Apps de backup de mídia em que o usuário aciona o upload das fotos recentes por meio de um aviso de notificação.

Como reduzir wake locks: 

Sincronizações em segundo plano únicas ou periódicas

Exemplos de casos de uso:

  • Um app realiza sincronizações periódicas em segundo plano para buscar dados para acesso off-line. 
  • Apps de pedômetro que buscam a contagem de passos periodicamente.

Como reduzir wake locks:

  • Não adquira um wake lock manual. Use WorkManager configurado para trabalho único ou periódico. O WorkManager respeita a integridade do sistema ao agrupar tarefas e tem um intervalo periódico mínimo (15 minutos), que geralmente é suficiente para atualizações em segundo plano. 
  • Se você identificar wake locks criados pelo WorkManager ou JobScheduler com alto uso de wake locks, isso pode ocorrer porque você configurou incorretamente o worker para não ser concluído em determinados cenários. Considere analisar os motivos de interrupção do worker, principalmente se você estiver observando ocorrências altas de STOP_REASON_TIMEOUT
workManager.getWorkInfoByIdFlow(syncWorker.id)
  .collect { workInfo ->
      if (workInfo != null) {
        val stopReason = workInfo.stopReason
        logStopReason(syncWorker.id, stopReason)
      }
  }
  • Além de registrar os motivos de interrupção do worker, consulte nossa documentação sobre depuração de workers. Além disso, considere coletar e analisar rastreamentos do sistema para entender quando os wake locks são adquiridos e liberados.
  • Por fim, confira nosso estudo de caso com a WHOOP, em que eles conseguiram descobrir um problema com a configuração dos workers e reduzir significativamente o impacto do wake lock.

Comunicação Bluetooth

Exemplos de casos de uso:

  • O app do dispositivo complementar solicita que o usuário pareie o dispositivo externo Bluetooth.
  • O app do dispositivo complementar fica à escuta de eventos de hardware em um dispositivo externo e de mudanças visíveis ao usuário na notificação.
  • O usuário do app do dispositivo complementar inicia uma transferência de arquivos entre o dispositivo móvel e o Bluetooth.
  • O app do dispositivo complementar realiza atualizações ocasionais de firmware em um dispositivo externo via Bluetooth.

Como reduzir wake locks:

  • Use o pareamento de dispositivos complementares para parear dispositivos Bluetooth e evitar a aquisição de um wake lock manual durante o pareamento Bluetooth. 
  • Consulte as orientações ____Comunicar em segundo plano para entender como fazer a comunicação Bluetooth em segundo plano. 
  • O uso do WorkManager geralmente é suficiente se não houver impacto do usuário em uma comunicação atrasada. Se um wake lock manual for considerado necessário, mantenha o wake lock apenas durante a atividade Bluetooth ou o processamento dos dados de atividade.

Rastreamento de local

Exemplos de casos de uso:

  • Apps de fitness que armazenam dados de localização em cache para upload posterior, como o traçado de rotas de corrida
  • Apps de entrega de comida que extraem dados de localização com alta frequência para atualizar o progresso da entrega em uma notificação ou interface de widget.

Como reduzir wake locks:

  • Consulte nossas orientações para otimizar o uso da localização. Considere implementar tempos limite, aproveitar o lote de solicitações de localização ou usar atualizações de localização passivas para garantir a eficiência da bateria.
  • Ao solicitar atualizações de localização usando as APIs FusedLocationProvider ou LocationManager, o sistema aciona automaticamente uma ativação do dispositivo durante o callback do evento de localização. Esse wake lock breve e gerenciado pelo sistema é isento de cálculos de wake locks parciais excessivos.
  • Evite adquirir um wake lock contínuo separado para armazenar dados de localização em cache, porque isso é redundante. Em vez disso, persista eventos de localização na memória ou no armazenamento local e aproveite WorkManager para processá-los em intervalos periódicos.
override fun onCreate(savedInstanceState: Bundle?) {
    locationCallback = object : LocationCallback() {
        override fun onLocationResult(locationResult: LocationResult?) {
            locationResult ?: return
            // System wakes up CPU for short duration
            for (location in locationResult.locations){
                // Store data in memory to process at another time
            }
        }
    }
}

Monitoramento de sensores de alta frequência

Exemplos de casos de uso:

  • Apps de pedômetro que coletam passos ou distância percorrida de forma passiva. 
  • Apps de segurança que monitoram os sensores do dispositivo para mudanças rápidas em tempo real, para fornecer recursos como detecção de falhas ou detecção de quedas.

Como reduzir wake locks:

  • Se você estiver usando SensorManager, reduza o uso para intervalos periódicos e somente quando o usuário tiver concedido acesso explicitamente por meio de uma interação da interface. O monitoramento de sensores de alta frequência pode consumir muita bateria devido ao número de ativações e processamento da CPU que ocorrem.
  • Se você estiver rastreando a contagem de passos ou a distância percorrida, em vez de usar o SensorManager, aproveite a API Recording ou considere usar o Conexão Saúde para acessar contagens de passos históricas e agregadas do dispositivo para capturar dados de maneira eficiente em termos de bateria.
  • Se você estiver registrando um sensor com SensorManager, especifique um maxReportLatencyUs de 30 segundos ou mais para aproveitar o lote de sensores e minimizar a frequência de interrupções da CPU. Quando o dispositivo for ativado posteriormente por outro acionador, como uma interação do usuário, recuperação de localização ou um job programado, o sistema vai enviar imediatamente os dados do sensor armazenados em cache.
val accelerometer = sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER)

sensorManager.registerListener(this,
                 accelerometer,
                 samplingPeriodUs, // How often to sample data
                 maxReportLatencyUs // Key for sensor batching 
              )
  • Se o app exigir dados de localização e dados do sensor, sincronize a recuperação e o processamento de eventos. Ao usar leituras de sensor no wake lock breve que o sistema mantém para atualizações de localização, você evita a necessidade de um wake lock para manter a CPU ativa. Use um worker ou um wake lock de curta duração para processar o upload e o processamento desses dados combinados.

Mensagens remotas

Exemplos de casos de uso:

  • Apps complementares de monitoramento de vídeo ou som que precisam monitorar eventos que ocorrem em um dispositivo externo conectado usando uma rede local.
  • Apps de mensagens que mantêm uma conexão de soquete de rede com a variante para computador.

Como reduzir wake locks:

  • Se os eventos de rede puderem ser processados no lado do servidor, use FCM para receber informações no cliente. Você pode programar um worker acelerado se for necessário processar mais dados do FCM. 
  • Se os eventos precisarem ser processados no lado do cliente por meio de uma conexão de soquete, não será necessário um wake lock para ouvir interrupções de eventos. Quando os pacotes de dados chegam ao rádio Wi-Fi ou celular, o hardware de rádio aciona uma interrupção de hardware na forma de um wake lock do kernel. Em seguida, você pode programar um worker ou adquirir um wake lock para processar os dados.
  • Por exemplo, se você estiver usando ktor-network para ouvir pacotes de dados em um soquete de rede, só adquira um wake lock quando os pacotes forem entregues ao cliente e precisarem ser processados.
val readChannel = socket.openReadChannel()
while (!readChannel.isClosedForRead) {
    // CPU can safely sleep here while waiting for the next packet
    val packet = readChannel.readRemaining(1024) 
    if (!packet.isEmpty) {
         // Data Arrived: The system woke the CPU and we should keep it awake via manual wake lock (urgent) or scheduling a worker (non-urgent)
         performWorkWithWakeLock { 
              val data = packet.readBytes()
              // Additional logic to process data packets
         }
    }
}

Resumo

Ao adotar essas soluções recomendadas para casos de uso comuns, como sincronizações em segundo plano, rastreamento de localização, monitoramento de sensores e comunicação de rede, os desenvolvedores podem trabalhar para reduzir o uso desnecessário de wake locks. Para continuar aprendendo, leia nossa outra postagem técnica do blog ou assista nosso vídeo técnico sobre como descobrir e depurar wake locks: Otimize a bateria do app usando a métrica de wake lock do Android vitals. Além disso, consulte nossa documentação atualizada sobre wake locks. Para nos ajudar a continuar melhorando nossos recursos técnicos, compartilhe outros comentários sobre nossas orientações na pesquisa de feedback da documentação.

Escrito por:

Continuar lendo