ANR (Aplicativo Não Responde) - Um erro que ocorre quando o aplicativo não responde. Como resultado, uma caixa de diálogo é aberta solicitando que o usuário aguarde ou feche o aplicativo.

Condições ANR
- Eventos de entrada (botões e eventos de toque) não são processados por 5 segundos;
- O BroadcastReceiver (onRecieve ()) não foi processado dentro do tempo especificado (primeiro plano - 10 s, plano de fundo - 60 s);
- O ContentProvider não é concluído em 10 segundos.
Normalmente, o segmento principal está bloqueado.
Se você lê meus artigos, provavelmente já está acostumado com o fato de rastrearmos o código-fonte. Então, vamos ver como é o
ANR sob o capô .
A classe
AppErrors controla não apenas o ANR, mas também outros erros que podem ocorrer no aplicativo, incluindo falha. O método handleShowAnrUi () apenas abre essa janela assustadora para muitos desenvolvedores e usuários que exibem ANR.
class AppErrors { ... void handleShowAnrUi(Message msg) { Dialog dialogToShow = null; synchronized (mService) { AppNotRespondingDialog.Data data = (AppNotRespondingDialog.Data) msg.obj; final ProcessRecord proc = data.proc; if (proc == null) { Slog.e(TAG, "handleShowAnrUi: proc is null"); return; } if (proc.anrDialog != null) { Slog.e(TAG, "App already has anr dialog: " + proc); MetricsLogger.action(mContext, MetricsProto.MetricsEvent.ACTION_APP_ANR, AppNotRespondingDialog.ALREADY_SHOWING); return; } Intent intent = new Intent("android.intent.action.ANR"); if (!mService.mProcessesReady) { intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY | Intent.FLAG_RECEIVER_FOREGROUND); } mService.broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null, AppOpsManager.OP_NONE, null, false, false, MY_PID, Process.SYSTEM_UID, 0 ); boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(), Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0; if (mService.canShowErrorDialogs() || showBackground) { dialogToShow = new AppNotRespondingDialog(mService, mContext, data); proc.anrDialog = dialogToShow; } else { MetricsLogger.action(mContext, MetricsProto.MetricsEvent.ACTION_APP_ANR, AppNotRespondingDialog.CANT_SHOW);
No entanto, o ANR não inicia aqui. Como eu disse acima, uma das primeiras causas desse erro é o atraso do evento de entrada, que é de 5 segundos. Por uma breve pesquisa, podemos encontrar onde esse valor está definido.
namespace android {
Agora podemos procurar o código onde a parte nativa é chamada. Isso acontece na classe
InputManagerService .
E aqui está o mWindowManagerCallbacks no
InputMonitor :
if (appWindowToken != null && appWindowToken.appToken != null) {
Vamos dar uma olhada em inputDispatchingTimedOut (). Aqui, apenas mostramos a mensagem no ActivityManager sobre a expiração do tempo limite e permitimos que o usuário decida se deseja cancelar a ação ou continuar aguardando. E é no
ActivityManagerService que AppErrors é chamado em caso de falha ou ANR.
private boolean makeAppCrashingLocked(ProcessRecord app, String shortMsg, String longMsg, String stackTrace) { app.crashing = true; app.crashingReport = generateProcessError(app, ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace); startAppProblemLocked(app); app.stopFreezingAllLocked(); return handleAppCrashLocked(app, shortMsg, longMsg, stackTrace); } private void makeAppNotRespondingLocked(ProcessRecord app, String activity, String shortMsg, String longMsg) { app.notResponding = true; app.notRespondingReport = generateProcessError(app, ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING, activity, shortMsg, longMsg, null); startAppProblemLocked(app); app.stopFreezingAllLocked(); }
As principais causas de ANR
- Bloqueio de entrada / saída
- Congestionamento de rede
- Bloqueio de segmentos
- Loop infinito
- A lógica de negócios leva muito tempo
Evitando ANR
- O encadeamento principal da interface do usuário executa a lógica associada apenas à interface do usuário;
- Cálculos complexos (por exemplo, operações de banco de dados, operações de entrada e saída, operações de rede etc.) são executados em um fluxo separado;
- Use o manipulador para interagir entre o thread da interface do usuário e o fluxo de trabalho;
- Use RxJava etc. para manipular operações assíncronas.
Como pegar ANR
PS
Publico todas as seleções no canal de telegrama
@paradisecurity .