Android: Tareas en segundo plano ( AsyncTask)

Blog >Lista Soluciones > AsyncTask : lanzar segundo hilo



Lanzar un segundo hilo

Todos los componentes de una aplicación Android, tanto las actividades, los servicios o los broadcast receivers que se ejecutan en el mismo hilo de ejecución, el hilo principal. Cualquier operación larga o costosa que realicemos en este hilo va a bloquear la ejecución del resto de componentes de la aplicación, produciendo al usuario un efecto evidente de lentitud o bloqueo. 

Y como no queremos que nos ocurra, vamos a usar hilos segundarios para ejecutar las operaciones tan "costosas" :

Creamos un nuevo proyecto y colocamos un botón y un ProgressBar en nuestra actividad :





y en el onCreate() de nuestra actividad principal, les hacemos referencia :

        b1=(Button) findViewById(R.id.button1);
        progress= (ProgressBar) findViewById(R.id.progressBar1);
  progress.setMax(100);
        progress.setProgress(0);
        
        b1.setOnClickListener(new OnClickListener(){

   @Override
   public void onClick(View arg0) {
    // TODO Auto-generated method stub
    
   }
         
        });


Ahora, haremos una función que nos haga esperar un segundo cuando hagamos click en el botón, que se llamará desde esta otra que irá dentro del onClick de nuestro botón :

public void onClick(View arg0) {
 reiterarHilo(); 
}

public void reiterarHilo(){
      for(int x=1; x<=10; x++) {
       hilounseg();
             progress.incrementProgressBy(10);
         }
    }

public void hilounseg(){
    try {
        Thread.sleep(1000);
    } catch(InterruptedException e) {}
}

Ejecutamos la aplicación para observar el resultado, de momento el efecto no es el deseado, se ha quedado colgada y a los 10 segundos se ha llenado, esto es porque esta corriendo en el hilo principal.Ahora vemos el método thread, que internamente tiene el run() :

new Thread(new Runnable() {
    public void run() {
        //COMIENZO DE OTRO HILO
    }
}).start();

El código entero :

public class MainActivity extends Activity {

 private Button b1;
 private ProgressBar progress;
 
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        b1=(Button) findViewById(R.id.button1);
        progress= (ProgressBar) findViewById(R.id.progressBar1);
        //LIMITES
  progress.setMax(100);
        progress.setProgress(0);    
        b1.setOnClickListener(new OnClickListener(){
   @Override
   public void onClick(View arg0) {
    new Thread(new Runnable() {
        public void run() {
           //COMIENZO HILO EN SEGUNDO PLANO
         reiterarHilo();
        }
        public void post(){
         
        }
    }).start(); 
   }
        });
        
    }
    public void reiterarHilo(){
      for(int x=1; x<=10; x++) {
       hilounseg();
             progress.incrementProgressBy(10);
         }
    }
    
    public void hilounseg(){
        try {
         //ESTA ES LA LINEA QUE NOS HACE ESPERAR UN SEGUNDO
            Thread.sleep(1000);
        } catch(InterruptedException e) {}
    }
    
}



Ahora sí podemos ver el progreso de nuestro progressBar. La creación de otro hilo nos ha permitido mantener el hilo principal libre para que nuestra interfaz de usuario se actualize durante la ejecución de la tarea en segundo plano. 





AsyncTask

Ahora vamos a ver AsynkTask, esta clase es menos engorroso y más práctico.Si quereis ver más información, ya que yo me enfoco sólo en el ámbito práctico del código y quereis curiosear podeis meteros aquí.

La forma más básica de usar la clase AsyncTask consiste en crear una nueva clase que extienda de ella y sobrescribir varios de sus métodos :

  • onPreExecute() : Se ejecutará antes del código principal de nuestra tarea. 
  • doInBackground() : Contendrá el código principal de nuestra tarea. 
  • onProgressUpdate() : Se ejecutará cada vez que llamemos al método publicProgrees() desde el método doInBackground(). 
  • onPostExecute() : Se ejecutará al finalizar la tarea o tras la finalización de doInBackground()
  • onCancelled() : Se ejecutará cuando se cancele la ejecución de la tarea antes de su finalización normal. 


AsyncTask nos permite un uso fácil del hilo, permitiendonos realizar procesos en background y publicandolos posteriormente sin necesidad de usar handlers. Son tareas asíncronas : Estas tareas asíncronas se definen con tres tipos, llamados Params, Progress y Result, y cuatro métodos, onPreExecute, doInBackground, onProgressUpdate y onPostExecute. Por ejemplo, para cargar los elementos en un ListView :

private class ListViewTask extends AsyncTask>{
    Context context;
    ProgressDialog pDialog;
 //CONSTRUCTOR
    public CargarListView(Context context){
        this.context = context;
    }
 
    @Override
    protected void onPreExecute() {
        // TODO Auto-generated method stub
        super.onPreExecute();
 
        pDialog = new ProgressDialog(context);
        pDialog.setMessage("Cargando");
        pDialog.setCancelable(true);
        pDialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);
        pDialog.show();
    }
 
    @Override
    protected ArrayAdapter<String> doInBackground(Void... arg0) {
        // TODO Auto-generated method stub
 
        try{
            Thread.sleep(2000);
        }catch(Exception ex){
            ex.printStackTrace();
        }
 
        ArrayAdapter adaptador = new ArrayAdapter(context, android.R.layout.simple_list_item_1, sistemas);
        return adaptador;
    }
 
    @Override
    protected void onPostExecute(ArrayAdapter result) {
        // TODO Auto-generated method stub
        super.onPostExecute(result);
        list.setAdapter(result);
        pDialog.dismiss();
    }
}


Para llamarla...
new CargarListViewTask(activity).execute();



O por ejemplo, para cargar una foto a traves de Internet por medio de un enlace :

class DownloadImageTask extends AsyncTask {
  ImageView bmImage;

  public DownloadImageTask(ImageView bmImage) {
   this.bmImage = bmImage;
  }

  @Override
  protected Bitmap doInBackground(String... urls) {
   String urldisplay = urls[0];
   Bitmap mIcon11 = null;
   try {
    InputStream in = new java.net.URL(urldisplay).openStream();
    mIcon11 = BitmapFactory.decodeStream(in);
   } catch (Exception e) {
    Log.e("Error", e.getMessage());
    e.printStackTrace();
   }
   return mIcon11;
  }

  @Override
  protected void onPostExecute(Bitmap result) {
   bmImage.setImageBitmap(result);
  }
 }
}


Para llamarla...
new DownloadImageTask(R.id.image).execute("http//:miImagenColgada.jpg");




Compartir Compartir Compartir Compartir


0 comentarios:

Publicar un comentario