31

I'm using Android SDK 4.0.3 API15 and I want to run multiple AsyncTasks parallely. I'm getting my data from web server and animating(10 fps) it real-time. But depending on user operations I need to send some data to web server also. When this occurs my animation pauses for a short time (sending data gets into queue and getting data waits it to finish ) and therefore I can't catch the real-time.

This answer is quite explaining but I couldn't make it work. So any help will be very appreciated.

I think I need to use this function to achieve that:

AsyncTask.executeOnExecutor(Executor exec, Params... params)

But I can't pass an executor as a parameter and I can't instantiate an executor. This is my AsyncTask class:

public class GetPlayers extends AsyncTask<String, Void, String> {
    @Override
    protected String doInBackground(String... urls) {

        Thread.currentThread().setPriority(Thread.MAX_PRIORITY);

        rawData="";
        for (String url : urls) {
            DefaultHttpClient client = new DefaultHttpClient();
            HttpGet httpGet = new HttpGet(url);
            try {
                HttpResponse execute = client.execute(httpGet);
                InputStream content = execute.getEntity().getContent();

                BufferedReader buffer = new BufferedReader(new InputStreamReader(content));
                if((rawData = buffer.readLine()) == null){
                    rawData = "error";
                }

            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return rawData; 
    }

    @Override
    protected void onPostExecute(String result) {
        manipulate();
    }
}

And I execute it like this:

GetPlayers task = new GetPlayers();
requestString = "web adress is here...";
task.execute(new String[] { requestString });
Community
  • 1
  • 1
Srht
  • 473
  • 3
  • 7
  • 17
  • What do You mean by 'an't pass an executor as a parameter and I can't instantiate an executor.'? Have You checked developer.android.com/reference/java/util/concurrent/Executor.html , http://developer.android.com/reference/java/util/concurrent/ThreadPoolExecutor.html? Which exact executor You're trying to use? – sandrstar Aug 28 '12 at 12:48
  • Actually I don't have much experience on Executors. So I tried to instantiate Executor class. As far as I have understand from the link I need to use ThreadPoolExecutor. I will search for it. Thanks. – Srht Aug 28 '12 at 12:56
  • Right, Executor is just an interface and cannot be instantiated. You can check out 'Known Indirect Subclasses' section of Executor docs for presented executors. However, the typical one seems to be ThreadPoolExecutor. – sandrstar Aug 28 '12 at 13:00
  • One more question. I have my AsyncTasks which should run parallely in different classes. Should I use the same ThreadPoolExecutor instance to make them run parallely? or any instance created from that class work parallely? – Srht Aug 28 '12 at 13:06
  • You need same executor instance to take advantage of it. Actually, executor is just like 'manager' for Your tasks (threads or async tasks) which You can setup (e.g. number of simultaneous tasks etc.). So, single instance of it should be aware of all tasks to have ability to manage them. – sandrstar Aug 28 '12 at 13:23
  • what's wrong with Executors.newFixedSizeThreadPool(n) ? – njzk2 Aug 28 '12 at 13:25

2 Answers2

58

This is how I do that:

if( Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB ) {
    new MyAsyncTask().executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
} else {
    new MyAsyncTask().execute();
}

where MyAsyncTask is regular AsyncTask subclass. Or you can wrap this all in helper class:

class TaskHelper {

    public static <P, T extends AsyncTask<P, ?, ?>> void execute(T task) {
        execute(task, (P[]) null);
    }

    @SuppressLint("NewApi")
    public static <P, T extends AsyncTask<P, ?, ?>> void execute(T task, P... params) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
            task.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, params);
        } else {
            task.execute(params);
        }
    }
}

and then just do:

TaskHelper.execute( new MyTask() );

or

TaskHelper.execute( new MyTask(), args );

or

TaskHelper.execute( new MyTask(constructorParams), args );
Marcin Orlowski
  • 72,056
  • 11
  • 123
  • 141
  • How may I pass my argument to that. Like this? new MyAsyncTask().executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR,new String[] { requestString }); – Srht Aug 28 '12 at 13:30
  • Please ALWAYS start with SDK documentation. Is not perfect, yet it is useful.. On `executeOnExecutor()`: http://developer.android.com/reference/android/os/AsyncTask.html#executeOnExecutor%28java.util.concurrent.Executor,%20Params...%29 so you can pass your parameters – Marcin Orlowski Aug 28 '12 at 13:45
  • I have seen and read that before asking the question, But I didn't know how to use that. I tried to add `executeOnExecutor (Executor exec, Params... params)` to my class definition and as far as you can guess it doesn't worked. I'm a newbie but trying to get things done by myself. In this case I simply doesn't know (and couldn't found) the proper use of this: `new MyAsyncTask().executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);` So thank you very much for this info which worked like a miracle. And please don't get frustrated :) – Srht Aug 28 '12 at 13:55
  • There's no change needed to be done to your AsyncTask subclass. If you had it working already, just replace `myTask.execute()` with `myTask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);`. If you passed params to your task (i.e. `myTask.execute( string1, string2 )` you do the same here `myTask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, string1, string2);`. Nothing changes, but the way you execute your task. – Marcin Orlowski Aug 28 '12 at 14:15
  • can we execute two separate async classes parallely in one activity. – Muhammad Zahid Feb 26 '15 at 07:54
  • Sure you can have more than one, no problem. – Marcin Orlowski Feb 26 '15 at 10:37
  • Can any one tell what is the diffference in AsynTask.execute() and Asynct.executeonexecutor() cudnt find any thing clear on doc – Utsav Gupta Jun 03 '15 at 08:11
  • Just curious @MarcinOrlowski why do you need distinct parameter types P,T when AsyncTask uses the same generic type for both. For instance, I've got basically the same code but the signature is public static void executeAsyncTask(AsyncTask task, T... params) – Matt Wolfe Mar 25 '16 at 16:09
  • @MarcinOrlowski would you please point out where you found that, if the current version is equal or greater to HONEYCOMB the executeOnExecutor should be used, and if the current version is below CODES.HONEYCOMB then execute should be used?? i checked the documentation but i could not find..thank you – Amrmsmb Aug 18 '16 at 07:47
  • It is in [official docs](https://developer.android.com/reference/android/os/AsyncTask.html), chapter "Order of execution". 3 secs googling btw – Marcin Orlowski Aug 18 '16 at 16:56
0

This problem occured to me, when updating my app in AndroidStudio to sdk 25 from Intelliy using Android 2.3 Just the little change (executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, string1, ...); ) works perfectly. I have an AsyncTask running in a Service for download and create AsyncTasks for upload in no service.