在Asynctask中执行线程及其复杂性 [英] Executing a Thread in Asynctask and its complications
问题描述
我想知道是否可以在Asynctask
的doInBackground
方法内执行Thread
.我应该避免在代码中使用这种结构吗?如果是,我为什么要避免呢?这会导致我的应用程序失效吗?
原则上,在AsyncTask
的doInBackground()
中启动线程没有问题,但有时您会看到此信息这样做不是因为这样做是对的,而是因为对AsyncTask
的工作方式有误解.
关键是doInBackground()
将自动 在后台(非GUI)线程上执行,而无需您自己为其创建线程.实际上,这就是AsyncTask
的重点.因此,如果您有一个简单的线性任务要在后台执行,则可以使用AsyncTask
来执行此任务,而无需手动进行任何线程创建.
可能要在AsyncTask
中启动新线程的位置是希望后台任务使用多个线程来完成.假设您正在编写一个应用程序,以检查各种服务器的联机状态,并在屏幕上显示有关其状态的信息.您将使用AsyncTask
在后台进行网络访问.但是,如果您以幼稚的方式进行操作,最终将导致服务器被一个一个地ping通,这将相当慢(特别是如果一个服务器已关闭,并且您需要等待超时).更好的选择是确保每个服务器都在其自己的后台线程中进行处理.然后,您将有几个选择,每个选择都是可辩护的:
- 每个服务器都有一个单独的
AsyncTask
. - 为单个
AsyncTask
的doInBackground()
中的每个服务器创建一个线程,然后确保在所有单个线程都已完成(使用Thread.join()
)之前,doInBackground()
不会完成. - 在单个
AsyncTask
中使用ThreadPool
/某种ExecutorService
/fork/join结构,为您管理线程.
我要说的是,对于现代库而言,几乎不需要手动创建线程.库函数将为您管理所有这些工作,并从中删除一些乏味的内容,并减少出错的可能性.上面的第三个选项在功能上与第二个选项等效,但是只使用了更多的高级机器,而不是在创建线程时进行DIY.
我并不是说永远不要手动创建线程,但是每当您想创建一个线程时,都值得一问,是否有一个高级选项可以更轻松,更安全地为您服务./p>
I was wondering is it ok to execute a Thread
inside the doInBackground
method of Asynctask
. Should I avoid using this kind of structure on my codes? And if yes, why should I avoid it? Would this cause any ineffectiveness in my apps?
In principle, there's no problem with starting a thread in the doInBackground()
of an AsyncTask
, but sometimes you see this done not because it's the right thing to do, but because of a misunderstanding about how AsyncTask
works.
The point is that doInBackground()
will automatically get executed on a background (non-GUI) thread, without you needing to create a thread for it yourself. That, in fact, is the whole point of an AsyncTask
. So if you have a simple, linear task that you want executed in the background, you do it with an AsyncTask
, and you don't need to do any manual thread creation.
Where you might want to start a new thread in an AsyncTask
is if you want your background task to use multiple threads to complete. Suppose that you were writing an app to check the online status of various servers, and display something about their status on the screen. You'd use an AsyncTask
to do the network access in the background; but if you did it in a naive way, you'd end up with the servers being pinged one by one, which would be rather slow (especially if one was down, and you needed to wait for a timeout). The better option would be to make sure that each server was dealt with on its own background thread. You'd then have a few options, each of which would be defensible:
- Have a separate
AsyncTask
for each server. - Create a thread for each server inside the
doInBackground()
of your singleAsyncTask
, and then make sure thatdoInBackground()
doesn't complete until all the individual threads have completed (useThread.join()
). - Use a
ThreadPool
/ some kind ofExecutorService
/ a fork/join structure inside your singleAsyncTask
, to manage the threads for you.
I would say that with modern libraries there is rarely a need for manual thread creation. Library functions will manage all of this for you, and take some of the tedium out of it, and make it less error-prone. The third option above is functionally equivalent to the second, but just uses more of the high-level machinery that you've been given, rather than going DIY with your thread creation.
I'm not saying that threads should never be created manually, but whenever you're tempted to create one, it's well worth asking whether there's a high-level option that will do it for you more easily and more safely.
这篇关于在Asynctask中执行线程及其复杂性的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!