Android:如何从AsyncTask调用非静态方法(通过doInBackground)

时间:2016-04-23 08:22:46

标签: android android-asynctask

我有class负责执行后台任务。

public class BackgroundTask extends AsyncTask<Void, Void, Void>
{
    private ProgressDialog dialog;

    public BackgroundTask(AppCompatActivity activity)
    {
        dialog = new ProgressDialog(activity);
    }

    @Override
    protected void onPreExecute()
    {
        dialog.setMessage("Doing something, please wait.");
        dialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);
        dialog.setCancelable(false);
        dialog.setProgress(0);
        dialog.setMax(100);
        dialog.show();
    }

    @Override
    protected void onPostExecute(Void result)
    {
        if (dialog.isShowing())
        {
            dialog.dismiss();
        }
    }

    @Override
    protected Void doInBackground(Void... params)
    {
        try
        {
            // How can I call non-static method of MyActivity here?
        }
        catch (InterruptedException e) 
        {
            e.printStackTrace();
        }

        return null;
    }
}

在我的活动MyActivity(源自AppCompatActivity)中,只要有耗时的任务,我就这样称呼它:

    BackgroundTask task = new BackgroundTask(MyActivity.this);
    task.execute();

然后在对话框中显示等待动画,完全没问题。我想知道:我如何将属于MyActivity(以及任何其他活动)的非静态方法(消耗时间)传递给此BackgroundTask ,以便我可以调用它来自`doInBackground'?

提前致谢。

2 个答案:

答案 0 :(得分:2)

public class BackgroundTask extends AsyncTask<Void, Void, Void> {

    private ProgressDialog dialog;
    private MyActivity activity;

    public BackgroundTask(MyActivity activity) {
        this.activity = activity;
        dialog = new ProgressDialog(activity);
    }

    ...    

    @Override
    protected Void doInBackground(Void... params) {
        try {
            activity.callWhatYouNeed();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        return null;
    }
}

但要注意你在doInBackground中调用的内容,因为这个方法在非主线程上执行,所以你不能对Views做任何事情。如果您需要对视图执行某些操作,请像这样进行调用

public class BackgroundTask extends AsyncTask<Void, Void, Void> {

    private ProgressDialog dialog;
    private MyActivity activity;
    private Handler uiHandler;

    public BackgroundTask(MyActivity activity) {
        this.activity = activity;
        dialog = new ProgressDialog(activity);
        uiHandler = new Handler(Looper.getMainLooper());
    }

    ...

    @Override
    protected Void doInBackground(Void... params) {
        try {
            mHandler.post(new Runnable() {
                @Override
                public void run() {
                    activity.callWhatYouNeed();
                }
            });
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        return null;
    }
}

更新:如果您希望将AsyncTask用于其他活动,则应使用继承并使用BaseActivity

创建一个callWhatYouNeed()
public abstract class BaseActivity extends AppCompatActivity {

    public abstract void callWhatYouNeed();

}

BaseActivity延伸:

public class MyActivity extends BaseActivity {

    @Override
    public void callWhatYouNeed() {
         //Implementation
    }

}

并更改AsyncTask

public class BackgroundTask extends AsyncTask<Void, Void, Void>
{
    private ProgressDialog dialog;
    private BaseActivity activity;

    public BackgroundTask(BaseActivity activity)
    {
        this.activity = activity;
        dialog = new ProgressDialog(activity);
    }

    @Override
    protected Void doInBackground(Void... params) {
        try {
            activity.callWhatYouNeed();
        }
        catch (InterruptedException e) {
            e.printStackTrace();
        }
        return null;
    }
}

或者您可以使用 instanceof 运算符检查活动:

public class BackgroundTask extends AsyncTask<Void, Void, Void> {

    private ProgressDialog dialog;
    private AppCompatActivity activity;

    public BackgroundTask(AppCompatActivity activity) {
        this.activity = activity;
        dialog = new ProgressDialog(activity);
    }

    ...

    @Override
    protected Void doInBackground(Void... params){
        try {
            if (activity instanceof MyActivity) {
                ((MyActivity) activity).callWhatYouNeed();
            } else if (acitivty instanceof SeocndActivity) {
                ((SecondActivity) activity).secondCall();
            }
        }
        catch (InterruptedException e) {
            e.printStackTrace();
        }

        return null;
    }
}

但是使用instanceof是不好的做法,所以我强烈建议使用继承。

答案 1 :(得分:1)

 BackgroundTask task = new BackgroundTask(MyActivity.this);
 task.execute();

当你在MyActivity类中调用上面的代码时你已经在构造函数中传递了类上的实例。所以你可以从MyActivity类中获取任何非静态方法。例如

    public class BackgroundTask extends AsyncTask<Void, Void, Void>{
    private ProgressDialog dialog;

    private MyActivity activity;

public BackgroundTask(MyActivity activity)
{
    this.activity = activity;
    dialog = new ProgressDialog(activity);
}

@Override
protected void onPreExecute()
{
    dialog.setMessage("Doing something, please wait.");
    dialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);
    dialog.setCancelable(false);
    dialog.setProgress(0);
    dialog.setMax(100);
    dialog.show();
}

@Override
protected void onPostExecute(Void result)
{
    if (dialog.isShowing())
    {
        dialog.dismiss();
    }
}

@Override
protected Void doInBackground(Void... params)
{
    try
    {
      activity.callyourmethod();

    }
    catch (InterruptedException e) 
    {
        e.printStackTrace();
    }

    return null;
}

}