简体   繁体   English

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

[英]Android: How to call non static method of an activity from AsyncTask (via doInBackground)

I have a class that takes care of performing background tasks. 我有一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;
    }
}

In my activity MyActivity (derived from AppCompatActivity ) whenever there are time consuming task, I call it like this: 在我的活动MyActivity (派生自AppCompatActivity )中,每当有耗时的任务时,我都这样称呼它:

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

And then displays waiting animation in dialog which is perfectly fine. 然后在对话框中显示等待的动画,这非常好。 I like to know: How can I pass non static method (that consumes time) which belongs to MyActivity (and any other activities) to this BackgroundTask so that I can call it from `doInBackground' ? 我想知道:如何将属于MyActivity (以及其他任何活动)的非静态方法(占用时间)传递给此BackgroundTask以便可以从“ doInBackground”调用它?

Thanks in advance. 提前致谢。

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

But take care about what you call inside doInBackground, becasue this method executes on non-main thread , so you can't do anything with Views. 但是请注意在doInBackground内部调用的内容,因为此方法在非主线程上执行,因此您无法对Views进行任何操作。 If you need do something with views, make call like this 如果您需要对视图进行处理,请像这样进行通话

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

UPDATE: if you want use AsyncTask with other activities, you should use inheritance and create one BaseActivity with callWhatYouNeed() 更新:如果要与其他活动一起使用AsyncTask,则应使用继承并通过callWhatYouNeed()创建一个BaseActivity

public abstract class BaseActivity extends AppCompatActivity {

    public abstract void callWhatYouNeed();

}

extends from BaseActivity : BaseActivity扩展:

public class MyActivity extends BaseActivity {

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

}

and change AsyncTask 并更改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;
    }
}

Or you can check activity with instanceof operator: 或者,您可以使用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;
    }
}

But it is bad practice to use instanceof, so i strongly recommend use inheritance. 但是使用instanceof是不好的做法,因此我强烈建议使用继承。

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

When you call above code in MyActivity class at that time You have passed the instance on class in a constructer. 那时,当您在MyActivity类中调用以上代码时,您已经在构造函数中的类上传递了实例。 So You can get any non-static method from MyActivity class. 因此,您可以从MyActivity类中获取任何非静态方法。 for example 例如

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

} }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM