Reputation:
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
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