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