Hilo de interfaz de usuario de Android bloqueado en una nueva actividad
-
20-12-2019 - |
Pregunta
Estoy trabajando en un pequeño juego de Android que maneja el dibujo en lienzo en un hilo de trabajo.Una vez finalizado el juego, este hilo debería iniciar la siguiente actividad, pero de alguna manera el hilo de la interfaz de usuario parece bloquearse al iniciar una nueva función.
Este es el Main-Loop de mis juegos:
while(true)
// Perform Ticks until the player makes a mistake
c = _surfaceHolder.lockCanvas();
if ((toDraw = rh.performTick()) == null) {
lose();
break;
}
_surfaceHolder.unlockCanvasAndPost(draw(toDraw,c));
}
La función performTick()
procesa la lógica del juego y regresa null
cuando termine el juego. draw()
hace el renderizado.Ambas funciones funcionan perfectamente; el problema es lose()
, que no hace nada más que iniciar una nueva Actividad:
protected void lose() {
Handler handler = new Handler(Looper.getMainLooper());
handler.post(new Runnable() {
@Override
public void run() {
Intent intent = new Intent(_context, MainMenu.class);
_context.startActivity(intent);
}
});
}
Cuando finaliza el juego, la nueva actividad (Menú principal) comienza normalmente pero no reacciona ante ningún evento táctil.No hay salida de LogCat y no se produce ninguna excepción.Peor aún, lose()
funciona normalmente cuando se llama ANTES de que comience el ciclo principal.
Llevo días trabajando en esto.Intenté iniciar la Actividad directamente desde el Hilo de trabajo (sin usar un Handler
en lose()
) y busqué en Internet durante horas; nada ayuda.Parece que el subproceso de la interfaz de usuario está de alguna manera bloqueado o atrapado en un bucle infinito y no tengo idea de cómo solucionarlo.
Todo está depurado en un dispositivo Nexus 4.
Por cierto: MainMenu.onCreate()
Funciona normalmente cuando se inicia de otra manera.
Por favor ayuda, ma3o
Solución
No desbloqueas el lienzo cuando la declaración if es verdadera.Break te sacará del tiempo, dejando el lienzo bloqueado.
while(true)
// Perform Ticks until the player makes a mistake
c = _surfaceHolder.lockCanvas();
if ((toDraw = rh.performTick()) == null) {
lose();
break;
}
// this line won't be executed whether the if statement above is true
_surfaceHolder.unlockCanvasAndPost(draw(toDraw,c));
}
También debes desbloquear dentro de la declaración if (antes o después de perder()).
Otros consejos
en cambio si While(true)
podrías tener While(myVar)
dónde myVar
es un valor booleano que es verdadero mientras el juego debe estar ejecutándose y se establece en falso cuando llamas lose()
En tu caso seguiste dibujando aunque no era necesario.