2010-08-12 17 views
25

En mi aplicación de Android tengo un bloqueo muy extraño, cuando presiono un botón (Imagen) en la interfaz de usuario toda la aplicación se congela y después de un par de segundos aparece el temido cuadro de diálogo Cerrar.Android - Despacho de clave Tiempo de espera

aquí 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} [email protected] 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} [email protected] 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 por la presión del botón (imagen) no causa del accidente:


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

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

¿Qué tal 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?

Respuesta

35

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, probar:

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

en lugar de sólo

your_stuff() 
4

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

En su caso, usted podría hacer lo siguiente:

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

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

0

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 algo long operation takes place in the "main" hilo. 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 ha tardado 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 se hace el hilo de interfaz de usuario de hacer alguna tarea compleja que sea demasiado ocupado haciendo su tarea de decirle al sistema operativo que todavía está 'vivo'.

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

debe mover su código Análisis de XML a otro hilo, a continuación, utilizar una devolución de llamada para decirle al hilo de interfaz de usuario que haya terminado y hacer algo con el resultado.

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

Detección donde ocurren ANR es fácil si se trata de un bloqueo permanente (estancamiento adquirir algunas cerraduras, por ejemplo), pero es más difícil si es sólo 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 mostrar precisamente que hay de nuevo en el momento de la ANR

Si Logcat hace nada no se emiten útiles, intente tirar de traces.txt /data/anr/traces.txt

adb pull /data/anr/traces.txt . 

como que puede dar más información sobre dónde la excepción ANR occurrred

y this link puede también útiles para la creación de AsyncTask y Temas

Cuestiones relacionadas