7

In an existing app I have an activity with an inner class which extends AsyncTask, this looks like the following:

public class Activity_1 extends BaseActivity {
    ....
    new async().execute();
    ...

    public class asyncextends AsyncTask<Void, Void, String> {
        protected String doInBackground(Void... progress) { ... }
        protected void onPreExecute() { ... }
        protected void onPostExecute(String result) { ... }
    }
}

Now, I need to call the same doInBackground-method from another activity, but the onPostExecute() of the this inner class operates on some local UI variables and hence it's not possible to use it from outside the clas. Is there any way I can call this AsyncTask, and just override the onPostExecute andonPreExecute-method, or shall I create yet another inner-class in the other activity, do the same background thing (of course move it to common utility-class or something), etc...?

perene
  • 421
  • 2
  • 6
  • 16

4 Answers4

24

You can make a separate abstract package private class, extending AsyncTask and implementing doInBackground() method:

abstract class MyAsyncTask extends AsyncTask<Void, Void, String> {
    @Override
    final protected String doInBackground(Void... progress) { 
        // do stuff, common to both activities in here
    }
}

And in your activities just inherit from MyAsyncTask (new class probably should be private, by the way), implementing onPostExecute() and onPreExecute() methods:

public class Activity_1 extends BaseActivity {

    ...
    new Async1().execute();
    ...

    private class Async1 extends MyAsyncTask {
        @Override
        protected void onPreExecute(){ 
            // Activity 1 GUI stuff
        }

        @Override
        protected void onPostExecute(String result) {
            // Activity 1 GUI stuff
        }
    }
}

If onPreExecute and onPostExecute contain some common actions as well, you can apply the following pattern:

abstract class MyAsyncTask extends AsyncTask<Void, Void, String> {
    public interface MyAsyncTaskListener {
       void onPreExecuteConcluded();
       void onPostExecuteConcluded(String result);  
    }

    private MyAsyncTaskListener mListener;

    final public void setListener(MyAsyncTaskListener listener) {
       mListener = listener;
    }

    @Override
    final protected String doInBackground(Void... progress) { 
        // do stuff, common to both activities in here
    }

    @Override
    final protected void onPreExecute() {
        // common stuff
        ...
        if (mListener != null) 
            mListener.onPreExecuteConcluded();
    }

    @Override
    final protected void onPostExecute(String result) {
        // common stuff
        ...
        if (mListener != null) 
            mListener.onPostExecuteConcluded(result);
    }
}

and use it in your activity as following:

public class Activity_1 extends BaseActivity {

    ...
    MyAsyncTask aTask = new MyAsyncTask();
    aTask.setListener(new MyAsyncTask.MyAsyncTaskListener() {
       @Override
       void onPreExecuteConcluded() {
           // gui stuff
       }

       @Override
       void onPostExecuteConcluded(String result) {
           // gui stuff
       }
    });
    aTask.execute();
    ...
}    

You can also have your Activity implement MyAsyncTaskListener as well:

public class Activity_1 extends BaseActivity implements MyAsyncTask.MyAsyncTaskListener {
    @Override
    void onPreExecuteConcluded() {
        // gui stuff
    }

    @Override
    void onPostExecuteConcluded(String result) {
       // gui stuff
    }

    ...
    MyAsyncTask aTask = new MyAsyncTask();
    aTask.setListener(this);
    aTask.execute();
    ...

}

I wrote the code from the head, so it might contain errors, but it should illustrate the idea.

Vladimir
  • 9,683
  • 6
  • 36
  • 57
  • Exactly something like this I was looking for. Will try to implement it first thing tomorrow morning. – perene May 14 '13 at 19:50
  • Great answer! But I can't work out why I'm getting the following for `MyAsyncTask aTask = new MyAsyncTask();` _Cannot instantiate the type MySyncTask_ Any help would be greatly appreciated! – Smittey Mar 17 '14 at 19:29
  • @Smittey must be a copy-paste error - the second implementation of MyAsyncTask shouldn't be abstract – Vladimir Mar 17 '14 at 19:37
  • 1
    Awesome examples, especially the listener implementation. Worked perfectly in my current project! :) – Machine Tribe Oct 09 '15 at 14:53
16

Its so simple just Simply build an object of main class and than call the inner class like this

 OuterMainClass outer = new OuterMainClass();
       outer.new InnerAsyncClass(param)
         .execute();

this answer is too late to help you but hope it help others.

Thanks

Syeda Zunaira
  • 5,191
  • 3
  • 38
  • 70
  • 1
    Glad it helped someone :) – Syeda Zunaira Apr 30 '15 at 04:58
  • hey can you do me a favor.. it worked really fine but now i have to return value to caller class and how should i do that..? i called Asynctask class from another class . so i want to get result of asyncTask in that caller class. do you know anyway to how to do it.? thanks :) – Aiyaz Parmar Apr 30 '15 at 06:12
  • Call a method of your caller class from onPostExecute() method of Asynctask – Syeda Zunaira Apr 30 '15 at 06:31
  • yeah you are right . that will work but if i want to implement that for more than one class.? – Aiyaz Parmar Apr 30 '15 at 06:34
  • 1
    make a static object thn pass it different values from different classes and onPostExc.. method check the value of that variable in onPostEx.. method, from there you get to know that which class called it thn simply from "if" statements call the appropriate method. – Syeda Zunaira Apr 30 '15 at 06:59
  • yeah i also thought about that to check through if conditions that from which class it is being called. but i think that's not a proper way. although i will do it that way. ;) thanks for your help :) – Aiyaz Parmar Apr 30 '15 at 07:03
1

1.Create a constructor of AsynckTask in ClassOne.

2.Crate object or ClassOne by new keyword.

3.Call Async Task by object

ClassOne{

class AsyncParmas extends AsyncTask {

        public ADDloadGeofenceDetails() {
        }

        @Override
        protected void onPreExecute() {


            super.onPreExecute();
        }

        @Override
        protected Object doInBackground(Object... params) {

}
}

Class ClassTwo{
ClassOne obj= new ClassOne ();

                    obj.new AsyncParmas ().execute();
}
}

GoodLuck Who were facing problem.

Kapil Parmar
  • 881
  • 8
  • 19
-1

If we create one static method which is in one class and and will be execute in any class in doInBackground of AsyncTask we can easily update UI through same class and even in different class .

Abhijeet
  • 392
  • 2
  • 13