Le tomó 300 segundos leer este análisis ANR de Android, ¡y puede verse obligado a probarlo con Ari!

Resumen de ANR

1) Primero, ANR (la aplicación no responde) significa que la aplicación no responde y el sistema Android necesita completar algunos eventos dentro de un cierto rango de tiempo. Si no consigue una respuesta efectiva más allá del tiempo predeterminado o el tiempo de respuesta es demasiado largo, causará ANR . ANR está garantizado por el mecanismo de procesamiento de mensajes. Android implementa un conjunto de mecanismos sofisticados para descubrir ANR en la capa del sistema. El principio central es la programación de mensajes y el procesamiento del tiempo de espera.

2) En segundo lugar, el cuerpo principal del mecanismo ANR se implementa en la capa del sistema. Todos los mensajes relacionados con ANR serán programados por el proceso del sistema (system_server) y luego enviados al proceso de la aplicación para completar el procesamiento real del mensaje. Al mismo tiempo, el proceso del sistema ha diseñado diferentes límites de tiempo de espera para rastrear el procesamiento del mensaje. Una vez que la aplicación procesa el mensaje incorrectamente, el límite de tiempo de espera entra en vigencia. Recopila algunos estados del sistema, como el uso de CPU / IO, la pila de llamadas de función del proceso e informa que el usuario no responde al proceso (cuadro de diálogo ANR).

3) Entonces, el problema ANR es esencialmente un problema de rendimiento. El mecanismo ANR en realidad limita el hilo principal de la aplicación, requiriendo que el hilo principal procese algunas de las operaciones más comunes (servicios de inicio, procesamiento de transmisiones, procesamiento de entrada) dentro de un tiempo limitado. Si el procesamiento se agota, se considera que el hilo principal ha perdido su respuesta Capacidad para realizar otras operaciones. Las operaciones que requieren mucho tiempo en el subproceso principal, como las operaciones intensivas de CPU, una gran cantidad de E / S y el diseño complejo de la interfaz, etc., reducirán la capacidad de respuesta de la aplicación.

¿Qué escenarios causarán ANR?

1. Cuando se produce ANR, se llamará al método AppNotRespondingDialog.show () para que aparezca un cuadro de diálogo que le indique al usuario.

2.  AppErrors.appNotResponding (), este método es la única entrada que finalmente abrirá el cuadro de diálogo ANR , y el mensaje ANR se mostrará cuando se llame al método . También se puede considerar que no importa cuánto tiempo se ejecuten las tareas en el hilo principal, siempre que no se llamen eventualmente En este método, no habrá avisos ANR, y no habrá registros e informes relacionados con ANR, a través de la relación de llamada, puede ver qué escenarios causarán ANR. Hay cuatro escenarios:

(1) Tiempo de espera del servicio: el servicio no se puede procesar en un tiempo específico

(2) Tiempo de espera de BroadcastQueue: BroadcastReceiver no se puede procesar en un tiempo específico

(3) Tiempo de espera del proveedor de contenido: tiempo de espera de ejecución del proveedor de contenido

(4) inputDispatching Timeout: el botón o evento táctil no responde dentro de un tiempo específico.

Mecanismo ANR

El mecanismo ANR se puede dividir en dos partes: ** Mecanismo de monitoreo ANR: ** Android tiene un conjunto de mecanismos de monitoreo para diferentes tipos de ANR (Broadcast, Service, InputEvent). ** Mecanismo de informe ANR: ** Después de detectar ANR, es necesario mostrar el cuadro de diálogo ANR y el registro de salida (pila de llamadas de función de proceso cuando ocurre ANR, uso de CPU, etc.).

El código de todo el mecanismo ANR también abarca varias capas de Android: capa de aplicación : la lógica de procesamiento del subproceso principal de la aplicación; Capa de marco : el núcleo del mecanismo ANR, principalmente AMS, BroadcastQueue, ActiveServices, InputmanagerService, InputMonitor, InputChannel, ProcessCpuTracker, etc. Capa nativa : InputDispatcher.cpp;

El mecanismo de tiempo de espera del proveedor encuentra relativamente pocos y no se analizará por el momento; Broadcast actualmente quiere decir principalmente dos puntos de conocimiento:

Primero: ya sea una transmisión regular o una transmisión ordenada, la recepción del receptor de transmisión final se ejecuta en serie y puede ser verificada por Demo;

Segundo: a través de la demostración y el marco para agregar registros relacionados, se ha verificado que las transmisiones ordinarias también tendrán un mecanismo de monitoreo ANR. El mecanismo ANR y los artículos de análisis de problemas creen que solo las transmisiones en serie tienen un mecanismo de monitoreo ANR. Más adelante, explicaremos específicamente el proceso de envío y recepción de transmisiones. Al mismo tiempo, el mecanismo de monitoreo de difusión ANR también se complementará; este artículo analiza principalmente el mecanismo de monitoreo ANR tomando como ejemplo el tiempo de espera del procesamiento de Servi y el tiempo de espera de distribución de eventos de entrada.

Mecanismo de monitoreo de tiempo de espera de servicio

El servicio se ejecuta en el subproceso principal de la aplicación. Si el tiempo de ejecución del servicio supera los 20 segundos, se activará ANR.

Cuando se produce el ANR del servicio, generalmente puede verificar si hay operaciones que requieren mucho tiempo (como operaciones complejas, operaciones de E / S, etc.) en las funciones del ciclo de vida del servicio (onCreate (), onStartCommand (), etc.). Si la lógica del código de la aplicación no puede encontrar el problema, es necesario verificar el estado actual del sistema: uso de la CPU, estado del servicio del sistema, etc. para determinar si el proceso ANR ocurrido en ese momento se vio afectado por la operación anormal del sistema.

¿Cómo detectar el tiempo de espera del servicio? Android se implementa configurando un mensaje de sincronización. Los mensajes cronometrados son procesados ​​por la cola de mensajes de AMS (hilo del Administrador de actividad del servidor del sistema). AMS tiene la información de contexto de la operación del Servicio, por lo que es razonable establecer un mecanismo de detección de tiempo de espera en AMS. Veamos primero dos preguntas: ** ¿Proceso de inicio del servicio? ** Pregunta 1: ¿Cómo monitorear el tiempo de espera del Servicio?

El mecanismo de supervisión del servicio se explica principalmente por los dos problemas anteriores: después de conocer el proceso de inicio del servicio, es más fácil analizar el mecanismo de supervisión del tiempo de espera del servicio a través del proceso de inicio del servicio.

1. El proceso de inicio del servicio se muestra en la siguiente figura:

(1) ActiveServices.realStartServiceLocked () crea un objeto de Servicio a través de scheduleCreateService () de app.thread y llama a Service.onCreate (), y luego llama al método sendServiceArgsLocked () para llamar a otros métodos de Servicio, como onStartCommand. Los dos pasos anteriores son la comunicación entre procesos. La comunicación entre procesos entre la aplicación y AMS puede referirse al proceso de la aplicación y a la comunicación del proceso del sistema.
(2) Los anteriores son solo los pasos clave del proceso de inicio del Servicio. El trabajo específico de cada método necesita ser verificado. Para el código específico, ignórelos por el momento. Para aquellos que estén interesados, pueden consultar la exploración de arte de desarrollo de Android y otros materiales relacionados.

2. Mecanismo de supervisión del tiempo de espera del servicio El mecanismo de supervisión del tiempo de espera del servicio se puede encontrar en el proceso de inicio del servicio.

(1) El trabajo principal de ActiveServices.realStartServiceLocked () es

    private final void realStartServiceLocked(ServiceRecord r,
            ProcessRecord app, boolean execInFg) throws RemoteException {
        ...
        // 主要是为了设置ANR超时,可以看出在正式启动Service之前开始ANR监测;
        bumpServiceExecutingLocked(r, execInFg, "create");
       // 启动过程调用scheduleCreateService方法,最终会调用Service.onCreate方法;
        app.thread.scheduleCreateService(r, r.serviceInfo,
        // 绑定过程中,这个方法中会调用app.thread.scheduleBindService方法
        requestServiceBindingsLocked(r, execInFg);
        // 调动Service的其他方法,如onStartCommand,也是IPC通讯
        sendServiceArgsLocked(r, execInFg, true);
    }

(2) bumpServiceExecutingLocked () llamará al método scheduleServiceTimeoutLocked ()

    void scheduleServiceTimeoutLocked(ProcessRecord proc) {
        if (proc.executingServices.size() == 0 || proc.thread == null) {
            return;
        }
        Message msg = mAm.mHandler.obtainMessage(
                ActivityManagerService.SERVICE_TIMEOUT_MSG);
        msg.obj = proc;
        // 在serviceDoneExecutingLocked中会remove该SERVICE_TIMEOUT_MSG消息,
        // 当超时后仍没有remove SERVICE_TIMEOUT_MSG消息,则执行ActiveServices. serviceTimeout()方法;
        mAm.mHandler.sendMessageDelayed(msg,
                proc.execServicesFg ? SERVICE_TIMEOUT : SERVICE_BACKGROUND_TIMEOUT);
        // 前台进程中执行Service,SERVICE_TIMEOUT=20s;后台进程中执行Service,SERVICE_BACKGROUND_TIMEOUT=200s
    }

(3) Si no hay un método serviceDoneExecutingLocked () para eliminar el mensaje dentro del tiempo especificado, se llamará al método ActiveServices. ServiceTimeout ()

void serviceTimeout(ProcessRecord proc) {
    ...
    final long maxTime =  now -
              (proc.execServicesFg ? SERVICE_TIMEOUT : SERVICE_BACKGROUND_TIMEOUT);
    ...
    // 寻找运行超时的Service
    for (int i=proc.executingServices.size()-1; i>=0; i--) {
        ServiceRecord sr = proc.executingServices.valueAt(i);
        if (sr.executingStart < maxTime) {
            timeout = sr;
            break;
        }
       ...
    }
    ...
    // 判断执行Service超时的进程是否在最近运行进程列表,如果不在,则忽略这个ANR
    if (timeout != null && mAm.mLruProcesses.contains(proc)) {
        anrMessage = "executing service " + timeout.shortName;
    }
    ...
    if (anrMessage != null) {
        // 当存在timeout的service,则执行appNotResponding,报告ANR
        mAm.appNotResponding(proc, null, null, false, anrMessage);
    }
}

(4) El proceso general de monitoreo del tiempo de espera del Servicio onCreate se muestra en la figura a continuación

Antes de que comience el ciclo de vida de onCreate, inicie la supervisión del tiempo de espera. Si onCreate no se completa dentro del tiempo especificado (este método realiza tareas que requieren mucho tiempo), llamará al método ActiveServices.serviceTimeout () para informar el ANR; si está dentro del tiempo especificado Después de ejecutar onCreate, se llamará al
método ActivityManagerService.serviceDoneExecutingLocked () para eliminar el mensaje SERVICE_TIMEOUT_MSG, lo que indica que el método Service.onCreate no tiene ANR. El servicio está programado por AMS. Usando Handler y Looper, un mensaje TIMEOUT está diseñado para ser procesado por el hilo AMS. Todo el mecanismo de tiempo de espera se implementa en la capa de Java; lo anterior es el proceso general de la supervisión del tiempo de espera del Servicio.

Monitoreo del tiempo de espera del evento de entrada

La aplicación puede recibir eventos de entrada (presionar un botón, pantalla táctil, trackball, etc.), y ANR se activará cuando el procesamiento no se complete en 5 segundos.

Aquí, primero se plantea la pregunta: ¿por qué proceso pasó el evento de entrada antes de que se pudiera enviar a la interfaz de la aplicación? ¿Cómo detectar el tiempo de espera del procesamiento del tiempo de entrada?

1.  Introducción al sistema de entrada de Android El proceso general y los participantes del sistema de entrada de Android se muestran en la figura a continuación.

En pocas palabras, el núcleo escribe los eventos originales en el nodo del dispositivo, InputReader extrae continuamente los eventos de entrada originales del EventHub en su bucle de subprocesos y procesa los eventos procesados ​​en la cola de envío de InputDispatcher. InputDispatcher saca los eventos en la cola de despacho en su bucle de subprocesos, encuentra la ventana adecuada y escribe el evento en la canalización de recepción de eventos de la ventana.

El hilo receptor del evento Looper of the window saca el evento de la tubería y lo entrega al controlador de eventos de la ventana para responder al evento. Los procesos clave son: lectura y procesamiento de eventos de entrada originales; distribución de eventos de entrada; envío, recepción y retroalimentación de eventos de entrada. El envío de eventos de entrada se refiere al proceso por el cual InputDispatcher extrae continuamente eventos de la cola de envío y encuentra una ventana adecuada para enviar.El envío de eventos de entrada es el proceso mediante el cual InputDispatcher envía eventos a la ventana a través del objeto Connection.

La comunicación entre procesos entre InputDispatcher y window se realiza principalmente a través de InputChannel. Después de que InputDispatcher y la ventana establezcan una conexión a través de InputChannel, puede enviar, recibir y retroalimentar eventos; el proceso principal de envío y recepción de eventos de entrada se muestra en la figura:

Entre ellos, después de que el evento de entrada se inyecte en la cola de despacho, el subproceso de despacho se despertará y la función InputDispatcher.dispatchOnce completará el ciclo de subproceso de envío; después de que InputDispatcher escriba el evento como InputMessage en InputChannel, el looper en el lado de la ventana se despertará y luego NativeEputReceiver :: handleEventReceiver :: handleEventReceiver comienza La recepción de eventos de entrada, los eventos de entrada se envían a la interfaz de usuario desde InputEventReceiver; lo anterior es solo el proceso general de eventos de entrada, un proceso más detallado puede referirse a información relacionada; después de comprender el proceso general del sistema de entrada, analizamos el monitoreo del tiempo de espera de los eventos de entrada Mecanismo

2.  Monitoreo de tiempo de espera de evento de entrada El proceso general de monitoreo de tiempo de espera de evento clave se muestra en la figura a continuación

(1) InputDispatcher :: dispatchOnceInnerLocked ():
Seleccione diferentes métodos de procesamiento de eventos de acuerdo con el tipo de evento: InputDispatcher :: dispatchKeyLocked () o InputDispatcher :: dispatchMotionLocked (), tomamos la supervisión del tiempo de espera del evento clave como un ejemplo para ilustrar;
(2) findFocusedWindowTargetsLocked ( ) El método llamará a checkWindowReadyForMoreInputLocked (); este método verifica si la ventana es capaz de recibir nuevos eventos de entrada; puede haber una serie de escenas que impiden que el evento continúe siendo enviado.

Escenario 1: la ventana está en pausa y no puede procesar el evento de entrada "En espera porque la ventana [targetType] está en pausa".

Escenario 2: la ventana no se ha registrado con InputDispatcher y el evento no se puede enviar a la ventana "En espera porque el canal de entrada de la ventana [targetType] no está registrado con el despachador de entrada. La ventana puede estar en proceso de eliminación".

Escenario 3: la conexión entre la ventana y InputDispatcher se ha interrumpido, es decir, InputChannel no funciona correctamente "Esperando porque la conexión de entrada de la ventana [targetType] es [estado]. La ventana puede estar en proceso de eliminación".

Escenario 4: InputChannel está saturado y no se pueden procesar nuevos eventos "Esperando porque el canal de entrada de la ventana [targetType] está lleno. Longitud de la cola de salida:% d. Longitud de la cola de espera:% d".

Escenario 5: para los eventos de entrada KeyEvent, debe esperar a que se procese el último evento. "Esperando para enviar el evento clave porque la ventana [targetType] no ha terminado de procesar todos los eventos de entrada que se le entregaron anteriormente. longitud:% d. Espera longitud de la cola:% d. "

Escenario 6: Para los eventos táctiles (TouchEvent), los eventos de entrada se pueden enviar a la ventana actual inmediatamente, porque los eventos táctiles ocurren en la ventana actualmente visible para el usuario. Pero existe una situación, si la aplicación actual tiene demasiados eventos de entrada en espera de ser enviados, lo que resulta en ANR, entonces los eventos TouchEvent deben ponerse en cola para su envío. "Esperando el envío de un evento que no es clave porque la ventana% s no ha terminado de procesar ciertos eventos de entrada que se le entregaron hace más de% 0.1fms. Espere la longitud de la cola:% d. Espere la edad del encabezado de la cola:% 0.1fms".

Los escenarios anteriores son la impresión de causas de ANR que a menudo vemos en los registros.

(3) El límite de 5s de distribución de eventos se define en InputDispatcher.cpp; InputDispatcher :: handleTargetsNotReadyLocked () método Si el evento no se ha distribuido dentro de 5s, llame a InputDispatcher :: onANRLocked () para solicitar al usuario que aplique ANR;

//默认分发超时间为5s
const nsecs_t DEFAULT_INPUT_DISPATCHING_TIMEOUT = 5000 * 1000000LL; 
int32_t InputDispatcher::handleTargetsNotReadyLocked(nsecs_t currentTime,
        const EventEntry* entry,
        const sp<InputApplicationHandle>& applicationHandle,
        const sp<InputWindowHandle>& windowHandle,
        nsecs_t* nextWakeupTime, const char* reason) {
    // 1.如果当前没有聚焦窗口,也没有聚焦的应用
    if (applicationHandle == NULL && windowHandle == NULL) {
        ...
    } else {
        // 2.有聚焦窗口或者有聚焦的应用
        if (mInputTargetWaitCause != INPUT_TARGET_WAIT_CAUSE_APPLICATION_NOT_READY) {
            // 获取等待的时间值
            if (windowHandle != NULL) {
                // 存在聚焦窗口,DEFAULT_INPUT_DISPATCHING_TIMEOUT事件为5s
                timeout = windowHandle->getDispatchingTimeout(DEFAULT_INPUT_DISPATCHING_TIMEOUT);
            } else if (applicationHandle != NULL) {
                // 存在聚焦应用,则获取聚焦应用的分发超时时间
                timeout = applicationHandle->getDispatchingTimeout(
                        DEFAULT_INPUT_DISPATCHING_TIMEOUT);
            } else {
                // 默认的分发超时时间为5s
                timeout = DEFAULT_INPUT_DISPATCHING_TIMEOUT;
            }
        }
    }
    // 如果当前时间大于输入目标等待超时时间,即当超时5s时进入ANR处理流程
    // currentTime 就是系统的当前时间,mInputTargetWaitTimeoutTime 是一个全局变量,
    if (currentTime >= mInputTargetWaitTimeoutTime) {
        // 调用ANR处理流程
        onANRLocked(currentTime, applicationHandle, windowHandle,
                entry->eventTime, mInputTargetWaitStartTime, reason);
        // 返回需要等待处理
        return INPUT_EVENT_INJECTION_PENDING;
    } 
}

(4) Cuando el hilo principal de la aplicación está atascado, al hacer clic en otros componentes de la aplicación tampoco responde, porque el envío del evento es serial, el evento anterior no se procesa y el siguiente evento no se procesará.

(5) Activity.onCreate realiza operaciones que requieren mucho tiempo, no importa cómo opere el usuario, ANR no ocurrirá, porque el mecanismo de monitoreo relacionado con el evento de entrada no se ha establecido; el canal InputChannel no se ha establecido en este momento, no responderá a los eventos de entrada, y InputDispatcher aún no puede eventos Después de ser enviado a la ventana de la aplicación, el mecanismo de monitoreo de ANR no se ha establecido, por lo que ANR no se informará en este momento.

(6) Los eventos de entrada son programados por InputDispatcher. Todos los eventos de entrada pendientes entrarán en la cola y esperarán. Se diseñó un juicio de tiempo de espera. El mecanismo de tiempo de espera se implementa en la capa nativa. Lo anterior es el mecanismo de monitoreo ANR del evento de entrada; para una lógica específica, consulte el código fuente relevante;

Mecanismo de informe ANR

No importa qué tipo de ANR ocurra, el método AppErrors.appNotResponding () eventualmente se llamará, las llamadas "diferentes rutas conducen al mismo resultado". La función de este método es informar al usuario o desarrollador que se ha producido ANR. La manifestación final es: aparece un cuadro de diálogo emergente para decirle al usuario que cierto programa actualmente no responde; ingrese muchos registros relacionados con ANR, para que los desarrolladores puedan resolver problemas.

    final void appNotResponding(ProcessRecord app, ActivityRecord activity,
            ActivityRecord parent, boolean aboveSystem, final String annotation) {
        ...
        if (ActivityManagerService.MONITOR_CPU_USAGE) {
            // 1. 更新CPU使用信息。ANR的第一次CPU信息采样,采样数据会保存在mProcessStats这个变量中
            mService.updateCpuStatsNow();
        }
            // 记录ANR到EventLog中
            EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid,
                    app.processName, app.info.flags, annotation);
        // 输出ANR到main log.
        StringBuilder info = new StringBuilder();
        info.setLength(0);
        info.append("ANR in ").append(app.processName);
        if (activity != null && activity.shortComponentName != null) {
            info.append(" (").append(activity.shortComponentName).append(")");
        }
        info.append("\n");
        info.append("PID: ").append(app.pid).append("\n");
        if (annotation != null) {
            info.append("Reason: ").append(annotation).append("\n");
        }
        if (parent != null && parent != activity) {
            info.append("Parent: ").append(parent.shortComponentName).append("\n");
        }
        // 3. 打印调用栈。具体实现由dumpStackTraces()函数完成
        File tracesFile = ActivityManagerService.dumpStackTraces(
                true, firstPids,
                (isSilentANR) ? null : processCpuTracker,
                (isSilentANR) ? null : lastPids,
                nativePids);

        String cpuInfo = null;
        // MONITOR_CPU_USAGE默认为true
        if (ActivityManagerService.MONITOR_CPU_USAGE) {
            // 4. 更新CPU使用信息。ANR的第二次CPU使用信息采样。两次采样的数据分别对应ANR发生前后的CPU使用情况
            mService.updateCpuStatsNow();
            synchronized (mService.mProcessCpuTracker) {
                // 输出ANR发生前一段时间内各个进程的CPU使用情况
                cpuInfo = mService.mProcessCpuTracker.printCurrentState(anrTime);
            }
            // 输出CPU负载
            info.append(processCpuTracker.printCurrentLoad());
            info.append(cpuInfo);
        }

        // 输出ANR发生后一段时间内各个进程的CPU使用率
        info.append(processCpuTracker.printCurrentState(anrTime));
        //会打印发生ANR的原因,如输入事件导致ANR的不同场景
        Slog.e(TAG, info.toString());
        if (tracesFile == null) {
            // There is no trace file, so dump (only) the alleged culprit's threads to the log
            // 发送signal 3(SIGNAL_QUIT)来dump栈信息
            Process.sendSignal(app.pid, Process.SIGNAL_QUIT);
        }

        // 将anr信息同时输出到DropBox
        mService.addErrorToDropBox("anr", app, app.processName, activity, parent, annotation,
                cpuInfo, tracesFile, null);
            // Bring up the infamous App Not Responding dialog
            // 5. 显示ANR对话框。抛出SHOW_NOT_RESPONDING_MSG消息,
            // AMS.MainHandler会处理这条消息,显示AppNotRespondingDialog对话框提示用户发生ANR
            Message msg = Message.obtain();
            HashMap<String, Object> map = new HashMap<String, Object>();
            msg.what = ActivityManagerService.SHOW_NOT_RESPONDING_UI_MSG;
            msg.obj = map;
            msg.arg1 = aboveSystem ? 1 : 0;
            map.put("app", app);
            if (activity != null) {
                map.put("activity", activity);
            }

            mService.mUiHandler.sendMessage(msg);
        }
    }

Además de la lógica principal, también se generan varios tipos de registros cuando se produce ANR: registro de eventos : al recuperar la palabra clave "am_anr", puede encontrar la aplicación donde se produjo el registro principal de ANR : al recuperar la palabra clave "ANR in", puede encontrar información de ANR , El contexto del registro contendrá el cuadro de uso de CPU : al recuperar el tipo "anr", puede encontrar rastros de información ANR : cuando se produce ANR, la función llama a la información de la pila de cada proceso

En este punto, el informe relacionado con ANR se ha completado, y el problema de ANR debe analizarse más tarde. El análisis de ANR a menudo comienza con el uso de la CPU en el registro principal y la pila de llamadas de función en los seguimientos. Por lo tanto, la actualización de la información de uso de la CPU, el método updateCpuStatsNow () y la función de impresión stack dumpStackTraces () es la clave para que el sistema informe problemas ANR. Para un análisis específico de los problemas ANR, consulte los materiales relacionados.

Resumen

1.  Mecanismo de monitoreo de ANR : primero analice el flujo de trabajo general del Servicio y los eventos de entrada, y luego comience desde la implementación del código fuente de dos mecanismos de monitoreo de ANR diferentes, Servicio y Evento de entrada, y analice cómo Android encuentra varios tipos de ANR. Al iniciar servicios y distribuir eventos de entrada, se implanta la detección de tiempo de espera para descubrir ANR. 2.  Mecanismo de informes ANR : analiza cómo Android genera registros ANR. Cuando se descubre ANR, las dos salidas de registro muy importantes son: uso de CPU y la pila de llamadas de función del proceso. Estos dos tipos de registros son nuestra arma para resolver el problema de ANR. 3.  El principio central de la supervisión de ANR es la programación de mensajes y el procesamiento del tiempo de espera. 4. Solo las escenas monitoreadas por ANR tendrán un informe ANR y un cuadro de aviso ANR.

Referencias

Mecanismo ANR y análisis de problemas Comprensión del principio de activación de Android ANR Comprensión profunda del volumen tres de Android (sistema de entrada de Android) Desarrollo de Android exploración de arte código fuente de Android

Finalmente, gracias al autor del artículo al que se hace referencia en este artículo.

Enlace original: https://www.jianshu.com/p/ad1a84b6ec69

El artículo no es fácil. Si le gusta este artículo, o si le resulta útil, espero que pueda disfrutarlo. ** Me gusta, reenviar y seguir **. El artículo se actualizará continuamente. ¡Productos absolutamente secos! ! !

Publicado 34 artículos originales · Me gusta1 · Visitas 756

Supongo que te gusta

Origin blog.csdn.net/Android725/article/details/105534876
Recomendado
Clasificación