AsyncTask的的get()方法:是否有任何场景,它实际上是最好的选择? [英] AsyncTask's get() method: Is there any scenario where it is actually the best option?
问题描述
在回答<一href="http://stackoverflow.com/questions/16905526/progressdialog-in-android-asynctask-does-not-display-at-the-right-time/16906914">this的问题,我有一个关于使用Android的的AsyncTask类的get()方法的意义/实用性毋庸置疑。
After answering this question, I got a doubt about the sense/usefulness of using the get() method of Android's AsyncTask class.
public final Result get ()
Waits if necessary for the computation to complete, and then retrieves its result.
基本上,一个同步解决了AsyncTask的类,即块(冻结)的用户界面,直至背景操作完成。
Basically, a synchronous solution to the AsyncTask class, that blocks (freezes) the UI until the background operations are finished.
除了测试目的,即使在这种情况下,我真的不能相信任何场景,它实际上是一个很好的解决方案,但我可能是错的,让我感到好奇。
Other than test purposes, and even in those cases, I can't really think in any scenario where it is actually a good solution, but I may be wrong, so I feel curious.
如果您需要用户真正等到AsyncTask的完成,则可以显示一个对话框或ProgressDialog,其在每一个瞬间UI的控制。我知道这是不完全一样的,但恕我直言,这是一个比使用的get()
方法更好的方法。
If you need the user to actually wait until the AsyncTask finishes, you can show a Dialog or ProgressDialog, having the control of the UI in every moment. I know it's not exactly the same, but IMHO it's a much better approach than using the get()
method.
推荐答案
的AsyncTask
是做后台操作中不是唯一的方式。事实上,文件说,的AsyncTask
只能用于业务需要至多几秒钟。所以,如果你有需要较长时间的任务,他们应该是通过实现的 Runnable接口。其他(非AsyncTask的)线程这样的任务,可能需要等待的AsyncTask
来完成,所以在我看来,这个想法有没有情况下,人会愿意使用 AsyncTask.get()
是假的。
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.
更新:在回应评论,强调这可能是一个有效的使用 AsyncTask.get()
,以下是可能的操作:
- 有可能是
的AsyncTask
s表示得到UI线程发起的,这可能涉及到互联网上进行通信,例如:加载网页,或与服务器进行通信。是,有些结果(或全部)都需要无论的AsyncTask
的结果更新屏幕。因此,一个的AsyncTask
及其doInBackground
然后按onPostExecute
的UI线程是有道理的。 - 每当UI线程发起
的AsyncTask
,它把的AsyncTask
对象在队列中,进行额外的处理由一个单独的后台线程,一旦结果出来。 - 对于每个
的AsyncTask
在依次排队,背景线程使用AsyncTask.get()
等待任务的完成,做其他处理之前。额外的处理的一个明显的例子可能仅仅是记录所有这样的的AsyncTask
活动到互联网上的服务器,因此它是有道理的,为此在后台。 - 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 theAsyncTask
are, some (or all) of the results are needed to update the screen. Hence anAsyncTask
with itsdoInBackground
followed byonPostExecute
on the UI thread makes sense. - Whenever the UI thread initiates an
AsyncTask
, it places theAsyncTask
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 usesAsyncTask.get()
to wait for the task to finish, before doing the additional processing. One obvious example of additional processing could simply be logging all suchAsyncTask
activities to a server on the internet, so it makes sense to do this in the background.
Update: In response to a comment, to emphasize that this could be a valid use of AsyncTask.get()
, the following is possible:
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 。另一种可能的有效使用 AsyncTask.get()
发生在我身上。该标准的建议是不要使用 AsyncTask.get()
从UI线程,因为它会导致用户界面冻结,直到结果可用。然而,对于其中需要隐形一个应用程序,这可能正是是必需的。因此,如何对以下情况:詹姆斯·邦德断裂成的Le CHIFFRE 并只有一两分钟来提取反派的手机中的所有数据和安装监控病毒。他安装问: 提供的应用程序,并开始运行,但他听到有人即将所以他要躲起来。 乐CHIFFRE 进入房间,拿起他的手机拨打电话。几秒钟的电话似乎有点反应迟钝,但突然电话醒过来,他做他的电话,没有进一步的思考。当然,对于反应迟钝的原因是一个事实,即 问: 的应用正在运行。它有各种任务做的,其中一些需要被以特定顺序进行。该应用程序使用两个线程做的工作,即UI线程本身和单个后台线程,它处理的AsyncTask
秒。用户界面线程的所有任务全面控制,但由于需要先于其他任务完成某些任务,有在应用点,其中使用的UI线程 AsyncTask.get()
在等待后台任务来完成: - 。)
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 :-).
这篇关于AsyncTask的的get()方法:是否有任何场景,它实际上是最好的选择?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!