En este ejemplo veremos como funciona el timer, y distintas maneras (incluida la erronea) de utilizarlo:
main.xml (layout):
Código:
<?xml version="1.0" encoding="utf-8"?>
Código:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="@string/titulo" android:textSize="30dp" android:gravity="center_horizontal"/>
<ProgressBar
android:id="@+id/progressBar1"
style="?android:attr/progressBarStyleHorizontal"
android:layout_width="fill_parent"
android:layout_height="wrap_content" android:max="100" android:layout_marginTop="50dp" android:layout_marginRight="20dp" android:layout_marginLeft="20dp"/>
<Button
android:id="@+id/button1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Ejemplo 1 " android:layout_gravity="center_horizontal" android:layout_marginTop="10dp"/>
<Button
android:id="@+id/button2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Ejemplo 2" android:layout_gravity="center_horizontal"/>
<Button
android:id="@+id/button3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Ejemplo 3" android:layout_gravity="center_horizontal"/>
<Button
android:id="@+id/button4"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Ejemplo 4" android:layout_gravity="center_horizontal"/>
</LinearLayout>
Aquí solo tenemos un título, un progressBar y cuatro botones que llaman al ProgressBar. A continuación os pongo el ejemplo completo comentado:
Código:
package m8.uf1.ejemploTimer;
Código:
import java.util.Timer;
import java.util.TimerTask;
import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.ProgressBar;
import android.widget.Toast;
public class EjemploTimerActivity extends Activity implements OnClickListener {
ProgressBar pb;
Button btn1;
Button btn2;
Button btn3;
Button btn4;
Timer timer;
boolean enProgreso;
Handler handler;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
btn1 = (Button) findViewById(R.id.button1);
btn1.setOnClickListener(this);
btn2 = (Button) findViewById(R.id.button2);
btn2.setOnClickListener(this);
btn3 = (Button) findViewById(R.id.button3);
btn3.setOnClickListener(this);
btn4 = (Button) findViewById(R.id.button4);
btn4.setOnClickListener(this);
pb = (ProgressBar) findViewById(R.id.progressBar1);
pb.setMax(100);
pb.setProgress(0);
handler = new Handler();
}
@Override
public void onClick(View v) {
if (enProgreso) return;
if (v == btn1) cuenta1();
else if (v == btn2) cuenta2();
else if (v == btn3) cuenta3();
else if (v == btn4) cuenta4();
}
//Este es el metodo que queremos ejecutar cada cierto tiempo
public void progreso(){
int n = pb.getProgress() + 1;
pb.setProgress(n);
if (n==100){
enProgreso = false;
Toast.makeText(this, "Completado", 1000).show();
}
}
// Esta manera es incorrecta porque el hilo principal permanece ocupado
// y no responde a los mensajes,
// la barra de progreso no se actualiza hasta el final
public void cuenta1() {
pb.setProgress(0);
enProgreso = true;
while(enProgreso){
progreso();
//pausa
try {
Thread.sleep(100);
} catch (InterruptedException e) {}
}
}
//Esta manera consiste en ir introduciendo Runnables en la cola de mensajes
//de la Activity mediante postDelayed(),
//Tiene la ventaja de que hasta que no se ejecuta un Runnable no se introduce el siguiente
//Además no se crea ningún hilo con lo cual la aplicación es más ligera
public void cuenta2() {
pb.setProgress(0);
enProgreso = true;
Runnable tarea = new Runnable() {
@Override
public void run() {
progreso();
if ( enProgreso ){
handler.postDelayed(this, 100);
}
}
};
handler.postDelayed(tarea, 100);
}
//Esta manera consiste en crear un hilo separado que va
//introduciendo Runnables en la cola de mensajes del hilo principal
//Puede haber problemas si el hilo principal no es capaz de procesar los
//Runnables con suficiente rapidez
public void cuenta3() {
pb.setProgress(0);
enProgreso = true;
Runnable tarea = new Runnable() {
@Override
public void run() {
while(enProgreso){
//progreso(); //Incorrecto
handler.post(new Runnable(){
public void run() {
progreso();
};
});
try {
Thread.sleep(100);
} catch (InterruptedException e) {}
}
}
};
Thread hilo = new Thread(tarea);
hilo.start();
}
//Esta manera consiste en utilizar un Timer que ejecute una tarea
//cada cierto tiempo.
//En realidad es lo mismo que utilizar un hilo separado
public void cuenta4(){
enProgreso = true;
pb.setProgress(0);
TimerTask tarea = new TimerTask(){
@Override
public void run() {
handler.post(new Runnable(){
public void run() {
progreso();
};
});
if(!enProgreso){
timer.cancel();//esto finaliza el hilo
}
}
};
timer = new Timer();
timer.schedule(tarea, 100,100);//se crea un hilo
}
}