user10748440
user10748440

Reputation:

Android AsyncTask onPreExecute() sequential execution

When using android.os.AsyncTask the method onPreExecute() gets executed asynchronously even when the tasks are posted to a single thread pool via executeOnExecutor(). Is this intended Behaviour?

The Google Documentation simply states:

"When first introduced, AsyncTasks were executed serially on a single background thread. Starting with Build.VERSION_CODES.DONUT, this was changed to a pool of threads allowing multiple tasks to operate in parallel. Starting with Build.VERSION_CODES.HONEYCOMB, tasks are executed on a single thread to avoid common application errors caused by parallel execution.

If you truly want parallel execution, you can invoke executeOnExecutor(java.util.concurrent.Executor, java.lang.Object[]) with THREAD_POOL_EXECUTOR."

This doesnt tell what exactly gets executed sequentially.

class testTask extends AsyncTask<String, String, String> {
            @Override
            protected void onPreExecute() {
                //Gets Executed Asynchronously
                Log.v("TAG","onPreExecute");
            }
            @Override
            protected void onPostExecute(String s) {
                // SEEMS to get executed Sequentially as expected
                Log.v("TAG","onPostExecute");
            }
            @Override
            protected String doInBackground(String... strings) {
                // SEEMS to get executed Sequentially as expected
                Log.v("TAG","doInBackground");
                try {
                    TimeUnit.SECONDS.sleep(10);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                return "";
            }
}
Executor singleThreadExecutor = Executors.newSingleThreadExecutor();
testTask t = new testTask();
t.executeOnExecutor(singleThreadExecutor);
testTask t2 = new testTask();
t2.executeOnExecutor(singleThreadExecutor);

The Code above outputs:

V/TAG: onPreExecute
V/TAG: onPreExecute
V/TAG: doInBackground
V/TAG: onPostExecute
V/TAG: doInBackground
V/TAG: onPostExecute

I Expect:

V/TAG: onPreExecute
V/TAG: doInBackground
V/TAG: onPostExecute
V/TAG: onPreExecute
V/TAG: doInBackground
V/TAG: onPostExecute

I expect the AsyncTask to fully execute Sequentially when the Documentation says so.

EDIT: It seems that this is indeed intended behaviour. I am looking for a way to do exactly what the AsyncTask provides

(eg. post a runnable on the UI Thread -> wait for it to finish -> execute a runnable on a separate thread -> Wait for it to finish -> post another runnable on the UI Thread)

just synchronously, so that when two tasks are running they execute fully sequential.

Upvotes: 0

Views: 336

Answers (1)

user10748440
user10748440

Reputation:

One Possible solution is to use Javas inter thread communications like so:

class mythread extends Thread {
Runnable pre = new Runnable() {
                    @Override
                    public void run() {
                      //Do Stuff on UI Thread
                      synchronized (this) {
                            this.notify();
                      }
                    }
}
Runnable post = new Runnable() {
                    @Override
                    public void run() {
                      //Do Stuff on UI Thread
                      synchronized (this) {
                            this.notify();
                      }
                    }
}
Runnable doinbackground = new Runnable() {
                    @Override
                    public void run() {
                      //Do Stuff on separate thread
                    }
}
synchronized (pre) {
   runOnUiThread(pre);
   try {
      pre.wait();
   } catch (Exception e) {
      e.printStackTrace();
   }
}
doninbackground.run();
synchronized (post) {
   runOnUiThread(post);
   try {
      post.wait();
   } catch (Exception e) {
      e.printStackTrace();
   }
}
}
Executor singleThreadExecutor = Executors.newSingleThreadExecutor();
singleThreadExecutor.execute(new mythread());
singleThreadExecutor.execute(new mythread());

Upvotes: 1

Related Questions