Android 中 AsyncTask 的通用类?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/3291490/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-20 09:31:26  来源:igfitidea点击:

Common class for AsyncTask in Android?

androidandroid-asynctask

提问by sunil

I have a common class say for eg Class A which extends AsyncTaskand has all the methods implemented i.e. onPreExecute, doinbackgroundand onPostExecute.

我有一个通用类,例如 A 类,它扩展AsyncTask并实现了所有方法,即onPreExecute,doinbackgroundonPostExecute

Now, there are other classes which want to use Class A object.

现在,还有其他类想要使用 A 类对象。

Say Class B uses class A in the below manner

说 B 类以下面的方式使用 A 类

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

Then i fetch the result in get method. But get method is not the proper way of using AsyncTask. I will like to get the result in onPostExecute. For that i tried using a boolean parameter which will get true only in onpostexecute. The class B will check till it gets true and when it gets true it will fetch the result.

然后我在 get 方法中获取结果。但是 get 方法不是使用 AsyncTask 的正确方法。我想在onPostExecute. 为此,我尝试使用一个布尔参数,该参数仅在onpostexecute. B 类将检查直到它为真,当它为真时,它将获取结果。

But this is somehow blocking the application.

但这以某种方式阻止了应用程序。

I have placed the code for asynctask below.

我在下面放置了 asynctask 的代码。

'

'

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

'

'

Can someone let me know what the issue may be?

有人可以让我知道可能是什么问题吗?

Regards

问候

Sunil

苏尼尔

回答by SirDarius

A clean way to use AsyncTask to get a result would be to use a callback interface.

使用 AsyncTask 获取结果的一种干净方法是使用回调接口。

Here is a simple example of this concept:

下面是这个概念的一个简单例子:

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

then in your B class :

然后在你的 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);
    }
}

you should now add the following code to your A class:

您现在应该将以下代码添加到您的 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);
   }  
}

This way, you don't need to wait explicitely for your task to complete, instead, your main code (which is probably the main UI thread), is waiting in the normal android event loop, and the onTaskComplete method will be automatically called, allowing to handle the task result there.

这样,你不需要明确地等待你的任务完成,相反,你的主代码(可能是主 UI 线程)在正常的 android 事件循环中等待,并且 onTaskComplete 方法将被自动调用,允许在那里处理任务结果。

回答by Georgy Gobozov

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



}

回答by Pentium10

I would make class A a private class embedded in parent class, and once it's done with the work it should update the parent class properties, that's possible onPostExecute.

我会让 A 类成为嵌入在父类中的私有类,一旦它完成工作,它应该更新父类属性,这是可能的 onPostExecute。