Wspólna klasa dla AsyncTask w Androidzie?

Mam wspólną klasę dla np. klasy A, która rozszerza {[2] } i ma zaimplementowane wszystkie metody tj. onPreExecute, doinbackground i onPostExecute.

Teraz są inne klasy, które chcą używać obiektu klasy A.

Powiedzmy, że Klasa B używa klasy a w poniższy sposób

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

Następnie pobieram wynik w metodzie get. Ale metoda get nie jest właściwym sposobem korzystania z AsyncTask. Chciałbym uzyskać wynik w onPostExecute. W tym celu próbowałem użyć parametru logicznego, który otrzyma true tylko w onpostexecute. Klasa B będzie sprawdzać, aż stanie się prawdziwa, a kiedy stanie się prawdziwa, pobierze wynik.

Ale to w jakiś sposób blokuje aplikację.

Umieściłem kod dla asynctask poniżej.

'

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;
}
}

'

Czy ktoś może mi powiedzieć w czym problem?

Pozdrawiam

Sunil

Author: willcodejavaforfood, 2010-07-20

3 answers

Czystym sposobem użycia AsyncTask, aby uzyskać wynik, byłoby użycie interfejsu zwrotnego.

Oto prosty przykład tego pojęcia:

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

Następnie w Klasie 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);
    }
}

Powinieneś teraz dodać następujący kod do swojej klasy A:

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);
   }  
}

W ten sposób nie musisz czekać na zakończenie zadania, zamiast tego twój główny kod (który jest prawdopodobnie głównym wątkiem UI) czeka w normalnej pętli zdarzeń Androida, a metoda onTaskComplete będzie automatycznie wywołany, pozwalając na obsługę wyniku zadania.

 131
Author: SirDarius,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-05-29 15:46:14
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();



}
 4
Author: Georgy Gobozov,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-04-06 11:20:21

Uczyniłbym klasę A prywatną klasą osadzoną w klasie nadrzędnej, a po wykonaniu tej pracy powinna zaktualizować właściwości klasy nadrzędnej, jest to możliwe napostexecute.

 1
Author: Pentium10,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-07-20 15:25:04