I'm having issues trying to understand how AsyncTask().get()
actually works. I know it's a synchronous
execution, However: I don't know how execute()
and get()
are connected.
I have this sample code from Google's docs:
// Async Task Class
class DownloadMusicfromInternet extends AsyncTask<String, String, String> {
// Show Progress bar before downloading Music
@Override
protected void onPreExecute() {
super.onPreExecute();
Log.d("Task: ", "onPreExecute()");
}
// Download Music File from Internet
@Override
protected String doInBackground(String... f_url) {
for (int i = 0; i < 100; i++){
try {
Thread.sleep(100);
Log.d("Task: ", String.valueOf(i));
} catch (InterruptedException e) {
e.printStackTrace();
}
}
return null;
}
// While Downloading Music File
protected void onProgressUpdate(String... progress) {
// Set progress percentage
Log.d("Task: ", "onProgressUpdate()");
}
// Once Music File is downloaded
@Override
protected void onPostExecute(String file_url) {
Log.d("Task: ", "onPostExecute()");
}
}
Now, from a button.onClick()
I call this in 3 ways:
new DownloadMusicfromInternet().execute("");//works as expected, the "normal" way
//works the normal way, but it's synchronous
try {
new DownloadMusicfromInternet().execute("").get();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
//does not work
try {
new DownloadMusicfromInternet().get();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
I'm confused as to how exactly execute()
triggers doInBackground()
and then immediately returns if get()
is called, while get()
has no effect on doInBackground()
whatsoever.
execute()
schedules the internal FutureTask
(usually on a internal Executor
) and returns immediately.
get()
just calls FutureTask.get() on this internal future, i.e. it waits (if necessary) for the result.
So calling get()
without calling execute()
first waits indefinitely, as the result will never be available.
As you mentioned, when used the normal way, get()
is not needed at all, as the result is handled in onPostExecute()
. I didn't even know it existed before I tried to understand your question