A partir do Android 17, os apps direcionados ao Android 17 (nível 37 da API)
ou mais recente recebem uma nova implementação sem bloqueio de
android.os.MessageQueue. A nova implementação melhora o desempenho e reduz os frames perdidos, mas pode interromper clientes que refletem sobre campos e métodos particulares do MessageQueue.
O Android 17 introduz uma revisão significativa de como o Looper e
Handler funcionam, reescrevendo a classe MessageQueue subjacente.
Desde o primeiro lançamento do sistema operacional Android, o MessageQueue dependia de um único bloqueio para gerenciar a fila de tarefas da linha de execução principal. Esse design geralmente causava contenção de bloqueio. A linha de execução principal podia ser bloqueada por uma linha de execução em segundo plano, levando a frames descartados e instabilidade na interface.
Reduzir o impacto
Seu app poderá ser afetado por essa mudança se ele ou as dependências dele dependem de
reflexão de tempo de execução para espiar dentro de MessageQueue. Evite usar a reflexão de tempo de execução para inspecionar o MessageQueue.
Com a implementação legada, os desenvolvedores às vezes acessavam campos particulares, como MessageQueue.mMessages, para inspecionar mensagens pendentes. Com a nova implementação sem bloqueio, as estruturas de dados internas mudaram completamente.
Para manter a compatibilidade binária, o Android 17 mantém o campo mMessages, mas em
a nova implementação, este campo é sempre nulo, independentemente de haver
mensagens na fila.
Além disso, se você usar algumas bibliotecas de teste populares, será necessário atualizar as bibliotecas para que sejam compatíveis com a nova implementação do MessageQueue.
Espresso
O Espresso é usado com frequência para testes de interface. A biblioteca do Espresso precisa saber quando a linha de execução principal está inativa para fazer asserções corretamente no estado da interface. As versões anteriores do Espresso dependiam de técnicas de reflexão que não são mais compatíveis com o MessageQueue sem bloqueio.
Ação
Atualize para o Espresso 3.7.0 ou mais recente. Essa versão usa a
TestLooperManager API, principalmente novas APIs introduzidas pelo Android 16,
para interagir com o Looper com segurança sem depender de detalhes de implementação
internos.
Robolectric
Da mesma forma, se você executar testes de unidade usando o Robolectric, poderá encontrar problemas se os testes dependerem do modo Looper legado.
Ação
Atualize para o Robolectric 4.17 ou mais recente. Se você estiver usando @LooperMode(LEGACY), será necessário migrar os testes para o novo @LooperMode(PAUSED). Consulte o
guia de migração do Robolectric para mais informações.
Testar o comportamento
Você pode testar seu app com a mudança de comportamento no Android 17 sem atualizar o targetSDK executando o seguinte comando:
adb am compat enable USE_NEW_MESSAGEQUEUE <your-package-name>
Esse comando ativa o MessageQueue sem bloqueio no app, se ele for uma build depurável.
Se o app for direcionado ao Android 17 (nível 37 da API), o novo comportamento será ativado por padrão. Se você notar um comportamento inesperado ou falhas após direcionar esse nível da API, desative temporariamente a nova implementação para verificar se o MessageQueue é a causa.
Você pode ativar ou desativar a mudança usando uma das duas opções:
O menu Mudanças na compatibilidade do app em Opções do desenvolvedor.
Executando o seguinte comando do ADB:
adb am compat disable USE_NEW_MESSAGEQUEUE <your-package-name>
Isso reverte o app para a implementação legada baseada em bloqueio, permitindo identificar se o problema foi resultado da mudança de comportamento da fila de mensagens.