AsyncTask
isn't the only way of doing background operations. Indeed, the documentation says that AsyncTask
should only be used for operations take at most a few seconds. So if you've got tasks that take longer, they should be coded via classes that implement the runnable interface. Such tasks in other (non AsyncTask) threads may well want to wait for an AsyncTask
to finish, so it seems to me that the idea that there are no situations where one would want to use AsyncTask.get()
is false.
Update: In response to a comment, to emphasize that this could be a valid use of AsyncTask.get()
, the following is possible:
- There could be
AsyncTask
s that get initiated from the UI thread, which might involve communicating over the internet, e.g. loading a web page, or communicating with a server. Whatever the results of the AsyncTask
are, some (or all) of the results are needed to update the screen. Hence an AsyncTask
with its doInBackground
followed by onPostExecute
on the UI thread makes sense. - Whenever the UI thread initiates an
AsyncTask
, it places the AsyncTask
object in a queue, for additional processing by a separate background thread once the results are available. - For each
AsyncTask
in the queue in turn, the background thread uses AsyncTask.get()
to wait for the task to finish, before doing the additional processing. One obvious example of additional processing could simply be logging all such AsyncTask
activities to a server on the internet, so it makes sense to do this in the background.
The following code shows what I mean. The app calls
KickOffAsynctask(...)
whenever it wants to do an AsyncTask, and there's a background thread that will automatically pickup the task for post-processing once the task is complete.
public class MyActivity extends Activity {
static class MyAsyncTaskParameters { }
static class MyAsyncTaskResults { }
Queue<MyAsyncTask> queue; // task queue for post-processing of AsyncTasks in the background
BackgroundThread b_thread; // class related to the background thread that does the post-processing of AsyncTasks
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
queue = new ConcurrentLinkedQueue<MyAsyncTask>();
b_thread = new BackgroundThread(queue);
b_thread.Start();
}
void KickOffAsynctask(MyAsyncTaskParameters params) {
MyAsyncTask newtask = new MyAsyncTask();
newtask.execute(params);
synchronized(queue) {
queue.add(newtask);
}
}
static class MyAsyncTask extends AsyncTask<MyAsyncTaskParameters, Void, MyAsyncTaskResults> {
@Override
protected MyAsyncTaskResults doInBackground(MyAsyncTaskParameters... params) {
MyAsyncTaskResults results = new MyAsyncTaskResults();
// do AsyncTask in background
return results;
}
@Override
protected void onPostExecute(MyAsyncTaskResults res){
// take required results from MyAsyncResults for use in the user interface
}
}
static class BackgroundThread implements Runnable {
// class that controls the post processing of AsyncTask results in background
private Queue<MyAsyncTask> queue;
private Thread thisthread;
public boolean continue_running;
public BackgroundThread(Queue<MyAsyncTask> queue) {
this.queue=queue; thisthread = null; continue_running = true;
}
public void Start() {
thisthread = new Thread(this);
thisthread.start();
}
@Override
public void run() {
try {
do {
MyAsyncTask task;
synchronized(queue) {
task = queue.poll();
}
if (task == null) {
Thread.sleep(100);
} else {
MyAsyncTaskResults results = task.get();
// post processing of AsyncTask results in background, e.g. log to a server somewhere
}
} while (continue_running);
} catch(Throwable e) {
e.printStackTrace();
}
}
}
}
Update2. Another possible valid use of AsyncTask.get()
has occurred to me. The standard advice is not to use AsyncTask.get()
from the UI thread, because it causes the user interface to freeze until the result is available. However, for an app where stealth is needed, that may be exactly what is required. So how about the following situation: James Bond breaks into the hotel room of Le Chiffre and only has a couple of minutes to extract all the data from the villian's phone and install the monitoring virus. He installs the app provided by Q and starts it running, but he hears someone coming so he has to hide. Le Chiffre enters the room and picks up his phone to make a call. For a few seconds the phone seems a bit unresponsive, but suddenly the phone wakes up and he makes his phone call without further thought. Of course, the reason for the unresponsiveness was the fact that Q's app was running. It had various tasks to do, and some of them needed to be done in a particular order. The app used two threads to do the work, namely the UI thread itself and the single background thread that processes AsyncTask
s. The UI thread was in overall control of all the tasks, but because some tasks needed to be done before other tasks, there were points in the app where the UI thread used AsyncTask.get()
while waiting for the background task to finish :-).
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…