Android causas y soluciones de optimización del rendimiento -ANR

1, la aparición de la situación ANR

Satisface el siguiente caso, el sistema pedirá al estallido de ANR

Los eventos de entrada (clave y táctiles eventos) no ha sido procesada dentro de las 5S;
(método onRecieve ()) eventos BroadcastReceiver dentro del tiempo especificado no procesada (emisión de primer plano para los años 10, de difusión entre bastidores de los años 60);
Servicio de los conocimientos previos 20s 200s fondo no se ha completado el arranque ;
el ContentProvider la publish () no se completará dentro de 10 segundos.
En circunstancias normales, que causó el hilo principal está bloqueada.

2. El principio de la ANR

No respuesta a la entrada de un proceso de ejemplo (basado en 9,0 de código):

ANR de diálogo de posición de cuadro emergente y de clase handleShowAnrUi AppErrors finales del método AMS mismo directorio (). Esta clase se utiliza para manejar una variedad de error se ha producido en el programa, no sólo la ANR, esta clase también obligado proceso de Crash.

 

    // base/core/java/com/android/server/am/AppErrors.java
    void handleShowAnrUi(Message msg) {
        Dialog dialogToShow = null;
        synchronized (mService) {
            AppNotRespondingDialog.Data data = (AppNotRespondingDialog.Data) msg.obj;
            // ...

            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 /* TODO: Verify */);

            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);
                // Just kill the app if there is no dialog to be shown.
                mService.killAppAtUsersRequest(proc, null);
            }
        }
        // If we've created a crash dialog, show it without the lock held
        if (dialogToShow != null) {
            dialogToShow.show();
        }
    }

Sin embargo, las llamadas desde el lugar de ocurrencia de ANR aquí para ir a través de una gran cantidad de clases y métodos. ANR es lanzada inicialmente en InputDispatcher.cpp en. Podemos definir constantes para encontrar la ubicación en la que el desencadenante inicial:

 

// native/services/inputflinger/InputDispatcher.cpp
constexpr nsecs_t DEFAULT_INPUT_DISPATCHING_TIMEOUT = 5000 * 1000000LL; // 5 sec

Desde la posición de esta clase se activará pasado a través de capas de InputManagerService alcance

 

// base/services/core/java/com/android/server/input/InputManagerService.java
private long notifyANR(InputApplicationHandle inputApplicationHandle,
        InputWindowHandle inputWindowHandle, String reason) {
    return mWindowManagerCallbacks.notifyANR(
            inputApplicationHandle, inputWindowHandle, reason);
}

mWindowManagerCallbacks aquí es InputMonitor:

 

// base/services/core/java/com/android/server/wm/InputMonitor.java
public long notifyANR(InputApplicationHandle inputApplicationHandle,
        InputWindowHandle inputWindowHandle, String reason) {
    // ... 略

    if (appWindowToken != null && appWindowToken.appToken != null) {
        final AppWindowContainerController controller = appWindowToken.getController();
        final boolean abort = controller != null
                && controller.keyDispatchingTimedOut(reason,
                        (windowState != null) ? windowState.mSession.mPid : -1);
        if (!abort) {
            return appWindowToken.mInputDispatchingTimeoutNanos;
        }
    } else if (windowState != null) {
        try {
            // 使用 AMS 的方法
            long timeout = ActivityManager.getService().inputDispatchingTimedOut(
                    windowState.mSession.mPid, aboveSystem, reason);
            if (timeout >= 0) {
                return timeout * 1000000L; // nanoseconds
            }
        } catch (RemoteException ex) {
        }
    }
    return 0; // abort dispatching
}

En el método anterior se llama y luego de vuelta a la AMS inputDispatchingTimedOut () método continúa con el proceso y, finalmente, inputDispatchingTimedOut () método se pasará a los AppErrors eventos

 

// base/services/core/java/com/android/server/am/ActivityManagerService.java
public boolean inputDispatchingTimedOut(final ProcessRecord proc,
        final ActivityRecord activity, final ActivityRecord parent,
        final boolean aboveSystem, String reason) {
    // ...

    if (proc != null) {
        synchronized (this) {
            if (proc.debugging) {
                return false;
            }

            if (proc.instr != null) {
                Bundle info = new Bundle();
                info.putString("shortMsg", "keyDispatchingTimedOut");
                info.putString("longMsg", annotation);
                finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
                return true;
            }
        }
        mHandler.post(new Runnable() {
            @Override
            public void run() {
                // 使用 AppErrors 继续处理
                mAppErrors.appNotResponding(proc, activity, parent, aboveSystem, annotation);
            }
        });
    }

    return true;
}

Cuando los eventos se transmiten a los AppErrors, ayudará Handler procesará el mensaje llama al método original y el cuadro de diálogo emergente.

Referencia: "principio ANR Android de análisis"

3, solución de ANR

El análisis de las causas y los principios de la ANR anteriores, vamos a analizar la forma de resolver el ANR.

1. Uso ADB registro ANR exportación y analizar

ANR del sistema se produce cuando la grabación de información y archivo de ANR /data/anr/traces.txt almacenada en el (relativamente nuevo en el sistema se almacenan tanto en / data / / * archivo ANR anr_). Podemos utilizar las siguientes formas de exportar a su ordenador con el fin de razón ANR generados para el análisis:

 

adb root
adb shell ls /data/anr
adb pull /data/anr/<filename>

Cuando el análisis I ANR cuando se utiliza el comando intento ANR a los registros de exportación han surgido Permiso denegado. Después de este tiempo, puede exportar el teléfono después de la raíz, o tratar de modificar los permisos para leer y escribir archivos, u optar por exportar los registros a la tarjeta sd en el modo de programador de sdcard y luego enviar los registros a la terminal de ordenador para su visualización

análisis DDMS 2. Uso traceview

DDMS abren en el AS, o para utilizar el directorio de herramientas DDMs abrir el directorio de instalación del SDK monitor.bat a continuación.

Utilizar las herramientas de TraceView pueden consultar el artículo: "Análisis Android TraceView rendimiento del uso (aplicación de análisis de tiempo)"

Esta idea posicionamiento ANR es: usar la información de ubicación para localizar TraceView método consume mucho tiempo llamada operación que consume tiempo.

información:

3. Uso proyecto de código abierto ANR-vigilancia detecta ANR

Dirección del proyecto es  Github-ANR-WatchDog

El principio del proyecto: crear un hilo de detección que siguen hilo de interfaz de usuario publicar una tarea, luego dormir un tiempo fijo, tal como antes y de nuevo después de la rosca hasta la tarea de detectar si o no para ejecutar el post, suponiendo que la tarea no se está ejecutando, de producción de ANRError, y terminar el proceso.

4. escena común ANR

E / S bloqueando
la congestión de red
multi-hilo estancamiento
debido a los resultados del método en un ciclo de programación reactiva a morir
debido a un tiempo de ejecución de la lógica de negocio es demasiado largo

5. El método de evitar ANR


hilo de interfaz de usuario sólo como medida de lo posible el trabajo asociado con la interfaz de usuario;
consume tiempo de trabajo (tales como las operaciones de base de datos, I / O, las operaciones de red, etc.), utilizando un procesamiento de subproceso de trabajo separada;
con Handler para manejar hilo de interfaz de usuario interactivo y los subprocesos de trabajo;
uso RxJava y otros mensajes asíncronos para procesar.
En resumen, un principio es: no en el hilo principal para hacer la operación que consume tiempo.

Publicado 56 artículos originales · ganado elogios 1 · vistas 2913

Supongo que te gusta

Origin blog.csdn.net/chuhe1989/article/details/104564521
Recomendado
Clasificación