Recentemente, comecei a lidar com anr on bugly e registrei a direção da otimização.
Empreste uma foto da Internet:
O problema anr aqui é a operação de chamada demorada pertencente ao thread principal. É necessário usar o rastreamento para obter o tempo de chamada do método demorado antes que o anr ocorra e resolver o negócio novamente para resolvê-lo.
Questão 1
Pilha de chamadas Java:
Da pilha de chamadas, descobriu-se que onActivityResult() executa a inicialização do lado do jogo, o que causará anr.
Como confiar na impressão é impreciso e há vários threads interrompendo a CPU, considera-se registrar o tempo real de execução do método obtendo o rastreamento.
Registre o arquivo de rastreamento de amostra desde a inicialização a frio do pacote do canal oppo até a página de login e obtenha uma visão geral dos pontos demorados no rastreamento: aqui está o método de execução no thread principal.
O verde claro é o código do aplicativo. Quanto maior a área ocupada pelo retângulo, mais demorado será.
Verifique o tempo de execução da lógica de onActvityResult:
Verifica-se que Show_GLView() leva mais tempo para executar, dentre os quais vários métodos são chamados na função NativeInit(), e muita lógica é inicializada na camada C++ do jogo.
Questão 2
Pilha de chamadas onde ocorre anr
Através do canal oposto da pilha de chamadas, descobre-se que onResume é executado e anr ocorre para a inicialização do canal.
Por meio do rastreamento, observe o tempo de execução no onResume:
Constatou-se que a inicialização da tarefa do canal de agregação no onResume leva mais de 100 milissegundos. Esta tarefa pode não ser o verdadeiro culpado que causou o anr. Pode ser que onActivityResult() leve muito tempo, o que indiretamente faz com que anr seja julgado pelo sistema durante o processo onResume().
Otimização do programa
Existem três maneiras de resolver tarefas demoradas:
- Colocar tarefas demoradas em threads assíncronos para execução
- Atrase a tarefa demorada preguiçosa para execução de política ou selecione o tempo ocioso com antecedência para execução.
Depois que a interface 1 pula para outra interface 2, quando a interface 2 chama finish() para destruir:
Primeiro execute onStop() da interface 2->onActivityResult() da interface 1->onResume() da interface 1->onstop() da interface 2->onDestroy() da interface 2.
Tente colocar nativeInit() e Show_GLView_Two() depois de onActvivityResult() e onResume(). Para não bloquear a execução de onResume(), use o mecanismo ocioso de hanlde:
Execute tarefas ociosas após onActivityResult:
Adicione tarefas de atraso após Onresume:
Compile o pacote de canais novamente de acordo com a lógica de ajuste acima para ver o efeito de otimização
efeito de otimização
Verifique o tempo de execução de onResume() em onActivityResult():
Ao mesmo tempo, também é realimentado para os colegas na camada c++ no lado do jogo, e as chamadas de inicialização são subdivididas de acordo com o negócio, atraso, assíncrono e outras operações.
Referência de dados:
- https://www.zhihu.com/tardis/bd/art/552305686?source_id=1001