40 votes

Classe commune pour AsyncTask dans Android?

J'ai une classe commune, dire par exemple Une Classe qui étend AsyncTask et dispose de tous les moyens mis en œuvre c'est à dire onPreExecute, doinbackground et onPostExecute.

Maintenant, il y a d'autres classes qui veulent utiliser la Classe d'Un objet.

Dire de la Classe B utilise la classe A dans la manière ci-dessous

A a = new A(context)
a.execute(url)

Puis-je récupérer le résultat dans la méthode get. Mais la méthode get n'est pas la bonne façon d'utiliser des AsyncTask. J'aimerai obtenir le résultat en onPostExecute. Pour cela, j'ai essayé à l'aide d'un paramètre booléen qui sera vrai que dans onpostexecute. La classe B vérifiera jusqu'à ce qu'il obtient une vraie et quand il devient vrai, il va chercher le résultat.

Mais c'est en quelque sorte le blocage de l'application.

J'ai mis le code pour asynctask ci-dessous.

'

import java.io.IOException;

import org.apache.http.client.ClientProtocolException;

import org.apache.http.client.HttpClient;

import org.apache.http.client.ResponseHandler;

import org.apache.http.client.methods.HttpGet;

import org.apache.http.impl.client.BasicResponseHandler;

import org.apache.http.impl.client.DefaultHttpClient;


import android.app.ProgressDialog;
import android.content.Context;
import android.os.AsyncTask;

public class A extends AsyncTask<String, Void, String> 
{
private Context context = null;

private final HttpClient httpClient = new DefaultHttpClient();

private String content = null;
//private String error = null;
private String finalResult = null;
private static boolean isResult = false;

private ProgressDialog progressDialog = null; 

public BabbleVilleSyncTask(Context context)
{
    this.context = context; 
    progressDialog = new ProgressDialog(this.context);
}

protected void onPreExecute() 
{
    progressDialog.setMessage("Please Wait....");
    progressDialog.show();
}

protected String doInBackground(String... urls) 
{
    try 
    {
        //urls[0] = URLEncoder.encode(urls[0], "UTF-8");

        HttpGet httpget = new HttpGet(urls[0]);
        ResponseHandler<String> responseHandler = new BasicResponseHandler();
        content = httpClient.execute(httpget, responseHandler);
    }
    /*catch(UnsupportedEncodingException ue)
    {
        error = ue.getMessage();
    }*/
    catch (ClientProtocolException e) 
    {
        //error = e.getMessage();
        cancel(true);
    }
    catch (IOException e) 
    {
        //error = e.getMessage();
        cancel(true);
    }

    httpClient.getConnectionManager().shutdown();

    return content;
}

protected void onPostExecute(String result) 
{
    finalResult = result;
    progressDialog.dismiss();
    System.out.println("on Post execute called");
    isResult = true;
}  

public boolean getIsResult()
{
    return isResult;
}

public void setIsResult(boolean flag)
{
    isResult = flag;
}

public String getResult()
{
    return finalResult;
}
}

'

Quelqu'un peut-il me faire savoir ce que le problème peut être?

Ce qui concerne

Sunil

138voto

SirDarius Points 13074

Un moyen propre à utiliser AsyncTask pour obtenir un résultat serait d'utiliser une interface de rappel.

Voici un exemple simple de ce concept:

interface AsyncTaskCompleteListener<T> {
   public void onTaskComplete(T result);
}

puis dans votre classe B :

class B implements AsyncTaskCompleteListener<String> {

    public void onTaskComplete(String result) {
        // do whatever you need
    }

    public void launchTask(String url) {
        A a = new A(context, this);
        a.execute(url);
    }
}

vous devez maintenant ajouter le code suivant à votre classe:

class A extends AsyncTask<String, Void, String> {
    private AsyncTaskCompleteListener<String> callback;

    public A(Context context, AsyncTaskCompleteListener<String> cb) {
        this.context = context;
        this.callback = cb;
    }

    protected void onPostExecute(String result) {
       finalResult = result;
       progressDialog.dismiss();
       System.out.println("on Post execute called");
       callback.onTaskComplete(result);
   }  
}

De cette façon, vous n'avez pas besoin d'attendre explicitement pour votre tâche à effectuer, au lieu de cela, votre code principal (qui est probablement la principale thread d'INTERFACE utilisateur), est en attente dans la normale android boucle d'événements, et la onTaskComplete méthode sera appelée automatiquement, permettant de traiter le résultat de la tâche là.

7voto

Georgy Gobozov Points 4814
 public abstract class BaseTask<T> extends AsyncTask<Object, Void, T> {

public Context context;
public ProgressDialog dialog;
public Exception exception;

protected BaseTask() {
}

public BaseTask(Context context) {
    this.context = context;
    this.dialog = new ProgressDialog(context);
}

@Override
protected void onPreExecute() {
    this.dialog.setMessage(context.getResources().getString(R.string.loading));
    this.dialog.show();
}

@Override
protected T doInBackground(Object... objects) {
    try {
       return doWork(objects);
    } catch (Exception e) {
        exception = e;
    }
    return null;
}

@Override
protected void onPostExecute(T result) {
    if (dialog.isShowing()) dialog.dismiss();
    if (exception == null) {
        onResult(result);
    } else {
       onError();
    }
}



public abstract T doWork(Object... objects) throws Exception;
public abstract void onResult(T result);
public abstract void onError();
 

}

1voto

Pentium10 Points 68884

Je ferais de la classe A une classe privée incorporée à la classe parente, et une fois le travail terminé, il devrait mettre à jour les propriétés de la classe parente, c'est possible surPostExecute.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X