Atul
Atul

Reputation: 4340

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.

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:

    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' ?

Thanks in advance.

Upvotes: 0

Views: 1345

Answers (2)

hluhovskyi
hluhovskyi

Reputation: 10116

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

public abstract class BaseActivity extends AppCompatActivity {

    public abstract void callWhatYouNeed();

}

extends from BaseActivity:

public class MyActivity extends BaseActivity {

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

}

and change 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:

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.

Upvotes: 2

Mayur Sakhiya
Mayur Sakhiya

Reputation: 326

 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. So You can get any non-static method from MyActivity class. 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;
}

}

Upvotes: 1

Related Questions