android timeout key freeze dispatch

Android: se agotó el tiempo de envío de claves



timeout key (4)

En mi aplicación para Android tengo un choque muy extraño, cuando presiono un botón (Imagen) en mi UI toda la aplicación se congela y después de un par de segundos aparece el temido cuadro de diálogo de cierre de fuerza.

Esto es lo que se imprime en el registro:

WARN/WindowManager(88): Key dispatching timed out sending to package name/Activity WARN/WindowManager(88): Dispatch state: {{KeyEvent{action=1 code=5 repeat=0 meta=0 scancode=231 mFlags=8} to Window{432bafa0 com.android.launcher/com.android.launcher.Launcher paused=false} @ 1281611789339 lw=Window{432bafa0 com.android.launcher/com.android.launcher.Launcher paused=false} lb=android.os.BinderProxy@431ee8e8 fin=false gfw=true ed=true tts=0 wf=false fp=false mcf=Window{4335fc58 package name/Activity paused=false}}} WARN/WindowManager(88): Current state: {{null to Window{4335fc58 package name/Activity paused=false} @ 1281611821193 lw=Window{4335fc58 package name/Activity paused=false} lb=android.os.BinderProxy@434c9bd0 fin=false gfw=true ed=true tts=0 wf=false fp=false mcf=Window{4335fc58 package name/Activity paused=false}}} INFO/ActivityManager(88): ANR in process: package name (last in package name) INFO/ActivityManager(88): Annotation: keyDispatchingTimedOut INFO/ActivityManager(88): CPU usage: INFO/ActivityManager(88): Load: 5.18 / 5.1 / 4.75 INFO/ActivityManager(88): CPU usage from 7373ms to 1195ms ago: INFO/ActivityManager(88): package name: 6% = 1% user + 5% kernel / faults: 7 minor INFO/ActivityManager(88): system_server: 5% = 4% user + 1% kernel / faults: 27 minor INFO/ActivityManager(88): tiwlan_wifi_wq: 3% = 0% user + 3% kernel INFO/ActivityManager(88): mediaserver: 0% = 0% user + 0% kernel INFO/ActivityManager(88): logcat: 0% = 0% user + 0% kernel INFO/ActivityManager(88): TOTAL: 12% = 5% user + 6% kernel + 0% softirq INFO/ActivityManager(88): Removing old ANR trace file from /data/anr/traces.txt INFO/Process(88): Sending signal. PID: 1812 SIG: 3 INFO/dalvikvm(1812): threadid=7: reacting to signal 3 INFO/dalvikvm(1812): Wrote stack trace to ''/data/anr/traces.txt''

Este es el código para el Botón (Imagen):

findViewById(R.id.endcallimage).setOnClickListener(new OnClickListener() { public void onClick(View v) { mNotificationManager.cancel(2); Log.d("Handler", "Endcallimage pressed"); if(callConnected) elapsedTimeBeforePause = SystemClock.elapsedRealtime() - stopWatch.getBase(); try { serviceBinder.endCall(lineId); } catch (RemoteException e) { e.printStackTrace(); } dispatchKeyEvent(new KeyEvent(KeyEvent.ACTION_DOWN,KeyEvent.FLAG_SOFT_KEYBOARD)); dispatchKeyEvent(new KeyEvent(KeyEvent.ACTION_UP, KeyEvent.KEYCODE_BACK)); } });

Si comento lo siguiente, al presionar el botón (imagen) no se produce el bloqueo:

try { serviceBinder.endCall(lineId); } catch (RemoteException e) { e.printStackTrace(); }

El código anterior llama hacia abajo a través de varios niveles de la aplicación y hacia la capa nativa (NDK), ¿podría la llamada que pasa a través de varios objetos conducir a la fuerza cercana? Parece poco probable ya que muchos otros botones hacen lo mismo sin problema.

¿Qué hay de la capa nativa? ¿Podría algún código que he creado con el NDK causar el problema?

¿Alguna otra idea sobre cuál podría ser la causa del problema?


Debe ser lo más rápido posible en su implementación onClick. Las operaciones costosas deberían, en general, descargarse a un hilo de fondo.

En onClick, intente:

Thread t = new Thread(){ public void run(){ your_stuff(); } }; t.start();

en lugar de simplemente

your_stuff()


Puede encontrar este error cuando bloquea el hilo principal (también conocido como el hilo de UI) durante unos segundos. Las operaciones costosas deberían, en general, descargarse a un hilo de fondo. AsyncTask es muy útil en estos casos.

En tu caso, podrías hacer lo siguiente:

new AsyncTask<Void, Void, Void>() { @Override protected Void doInBackground(Void... params) { try { serviceBinder.endCall(lineId); } catch (RemoteException e) { e.printStackTrace(); } } }.execute();


Si está haciendo una tarea intensiva de recursos, entonces podría suceder. Al reanudar la actividad. 1. Intente detener todo su trabajo intensivo en OnPause y luego reiniciarlo onResume. 2. Si muestra un mapa en la superposición de dibujo de Actividad, deje de actualizar las superposiciones mientras está en modo reposo. Y luego reinícielo onResume.


Haga su operación larga en un hilo separado o use AsyncTask para deshacerse de ANR.

Un ANR (actividad que no responde) se produce cuando se long operation takes place in the "main" subproceso long operation takes place in the "main" . Este es el hilo de bucle de evento, y si está ocupado, Android no puede procesar ningún otro evento GUI en la aplicación y, por lo tanto, arroja un ANR dialog .

Tu actividad tardó mucho en decir al sistema operativo Android ''¡hey, todavía estoy vivo!'' (Esto es lo que hace el hilo de la interfaz de usuario).

http://developer.android.com/guide/practices/design/responsiveness.html

Básicamente, si haces que el subproceso de la interfaz de usuario haga alguna tarea compleja, está demasiado ocupado haciendo tu tarea para decirle al sistema operativo que todavía está "vivo".

http://android-developers.blogspot.co.uk/2009/05/painless-threading.html

Debería mover su código XML Parsing a otro hilo, luego usar una devolución de llamada para indicarle al hilo de UI que terminó y hacer algo con el resultado.

http://developer.android.com/resources/articles/timed-ui-updates.html

Detectar dónde ocurren los ANR es fácil si se trata de un bloqueo permanente (por ejemplo, un punto muerto que adquiere algunos bloqueos), pero más difícil si solo se trata de un retraso temporal. Primero, repase su código y busque lugares vunerables y operaciones de larga duración. Los ejemplos pueden incluir el uso de sockets, bloqueos, secuencias de hilos y otras operaciones de bloqueo desde el hilo del evento. Debes asegurarte de que todo esto suceda en hilos separados. Si nada parece ser el problema, use DDMS y habilite la vista de subprocesos. Esto muestra todos los hilos en su aplicación similar a la traza que tiene. Reproduzca el ANR y actualice el hilo principal al mismo tiempo. Eso debería mostrarle exactamente qué está sucediendo en el momento de la ANR

Si Logcat no genera nada útil, intente extraer traces.txt de /data/anr/traces.txt

adb pull /data/anr/traces.txt .

ya que puede brindar más información sobre dónde se produjo la excepción ANR

Y este enlace también puede ser útil para crear AsyncTask y Threads