PDA

Ver la Versión Completa : Para y pausar un progressBar que avanza con un Hilo.


manolazo
04/10/13, 02:20:51
Buenas.

No se si esto esta respondido ya.

La pregunta es:

Como se puede parar y pausar un progressbar cuyo avance se hace a traves de un hilo con un boton?

El metodo stop(); parece ser que no es aconsejable usarlo y esta depreciado y hay que evitarlo.

Por lo que leo los tiros van por usar wait() and notify() .


public void comienzoJuego(){

hilo = new HiloComienzoJuego();
hilo.start();

}


class HiloComienzoJuego extends Thread {
@Override
public void run() {
while(progressTime < totalTime ){
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
progressbar.incrementProgressBy(1);
progressTime++;


/*aqui vendria mas codigo que no no viene al caso */


Como se ve el progressBar avanza cada segundo y quiero pausarlo y reanudarlo usando un boton:




public void botonPause (View v){
if(pulsar==0){
botonPausar.setImageResource(R.drawable.boton_rean udar);
pulsar=1;
setGamePaused(true);

}else{
botonPausar.setImageResource(R.drawable.boton_paus e);
pulsar=0;
setGamePaused(false);
}
}


public void setGamePaused(boolean pausado){
this.gamePaused= pausado;
}

public boolean getGamePaused(){
return gamePaused;
}



Si pongo dentro del while(progressTime < totalTime && !getGamePaused()) se para el bucle y sale

Tambien he probado con hilo.interrupt(); y tampoco.


Alguna idea???

kriogeN
04/10/13, 09:44:08
Es normal que se pare ejecutando esto:

while(progressTime < totalTime && !getGamePaused())

Ya que al no cumplirse la segunda condición no entra en el While y el hilo termina, divide el código:

while(progressTime < totalTime) {
if (!getGamePaused()) {
//AQUÍ TODO EL RESTO DEL CÓDIGO

De esta forma siempre estará dentro del While, pero progressTime sólo se incrementará si se cumple el if.

Por último 2 cosas:

1) No es recomendable actualizar una vista desde un hilo (salvo que sea un SurfaceView, que están pensadas para tal efecto). Así que lo mejor es que cuando accedas a la progressBar lo hagas con un Handler. O mejor aún, que modifiques el código para usar un AsyncTask y lo hagas en el "onProgressUpdate".

2) Aunque no es muy importante y es rariiiisimo que te vaya a fallar, es recomendable que el acceso a gamePaused sea "synchronized", ya que podría coincidir una lectura y escritura a la vez al estar en hilos distintos. Pero como ya te digo es muuuy raro que ocurra. Esto también lo solucionarías con el AsyncTask, poniendo la comprobación de gamePaused también en el "onProgressUpdate".

manolazo
04/10/13, 12:29:32
Hola,

Efectivamente funciona como dices con el if despues del while , la putada es que tengo un contador de segundos puesto arriba con un textView que me actualiza el progressbar tal que asi:


while(progressTime < totalTime ){
if(!getGamePaused()){
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
progressbar.incrementProgressBy(1);
progressTime++;
handler.post(new Runnable(){
@Override
public void run() {
if(!getGameOver()) //si el juego no esta terminado ponemos los segundos que quedan, pero cuando termina no.
//textTiempo.setText(String.valueOf(totalTime-progressTime)+" seg");
textTiempo.setText(String.valueOf( (totalTime-progressTime)<60
?totalTime-progressTime
:((totalTime-progressTime)/60)+":"+String.valueOf(
(totalTime-progressTime)%60>9
?(totalTime-progressTime)%60
:"0"+(totalTime-progressTime)%60) )+" sec");


}
});



y ahora cuando pulsas el boton de pausar , NO PAUSA DE FORMA EXACTA ya que el progressbar se actualiza segundo a segundo y no tiene en cuenta las decimas!!!, vere como lo soluciono porque hay un error de 1 segundo.

Respecto a los handlers esta claro, de hecho tengo el código lleno de handlers para actualizar vistas, pero dices que mejor usar un AsyncTask. ¿Es mas efeciente? lo digo porque cambiar todo por asincTask seria una movida con lo sencillo que es el uso de un handler.

Un saludo.

kriogeN
04/10/13, 12:35:40
Creo que puede solucionar tu desfase de 1 segundo poniendo detrás del Thread.sleep(1000) esto:

if(getGamePaused()) continue;

Aunque lo volverías a tener al reanudar, ya que volvería a contar el segundo desde el principio, independientemente de que lo parases en el X,01 o en el X,99. Pero al menos la ProgressBar y el TextView irían sincronizados.

manolazo
04/10/13, 13:15:12
hola, pues si , se para al instante y luego al reanudar pilla el desfase, pero lo prefiero de esta forma ya que se sincroniza con el textview.

REspecto a los handlers, implementarias al tener tantas vistas AsyncTask o es igual de eficiente para estos casos el uso de handler?

kriogeN
04/10/13, 13:46:56
En el fondo viene a ser casi lo mismo, lo único que con AsyncTask se te queda "más organizado".