我对何时选择AsyncTask和Handler感到困惑。比如说,我想每n秒运行一次某些代码,并更新UI,那么为什么要选择其中之一呢?
我对何时选择AsyncTask和Handler感到困惑。比如说,我想每n秒运行一次某些代码,并更新UI,那么为什么要选择其中之一呢?
在我看来,AsyncTask是为Android应用程序提供一种方便易用的方式来实现后台处理的,而不必太担心低层次的细节(线程、消息循环等)。它提供了回调方法来帮助安排任务,并且在需要时轻松更新UI。
然而,重要的是要注意,当使用AsyncTask时,开发人员要遵守其限制,这是由该类作者所做的设计决策导致的。例如,我最近发现,使用AsyncTasks可以安排的作业数量是有限制的。
Handler是两者中更透明的,可能会给你更多自由;因此,如果您想要更多的控制,您将选择Handler,否则AsynTask也可以正常工作。
AsyncTasks
在一个线程上执行,所以不再有并行性。但您仍然可以在并行的Executor
实现上运行它们。 - MrSnowflake我的经验法则是:
如果你正在做与UI相关的孤立任务,例如下载数据以在列表中显示,请使用 AsyncTask
。
如果你正在进行多个重复任务,例如下载要在ImageViews
中显示的多个图像(如下载缩略图),请使用带有Handler
的任务队列。
尽可能避免使用AsyncTask,主要原因如下:
由于系统设置了线程池的基础和最大大小,如果创建太多的AsyncTask,它们可能会被销毁。
根据活动生命周期,即使在运行时,AsyncTask也可能被自动终止,并且您无法控制它。
像onPostExecute这样在UI线程上运行的AsyncTask方法,可能会在Activity不再可见或可能处于不同的布局状态(例如方向更改后)时执行。
总之,不应使用与UIThread相关的AsyncTask方法,这是其主要优点!此外,您应该仅在doInBackground上执行非关键性工作。有关这些问题的更多见解,请阅读此讨论:
Is AsyncTask really conceptually flawed or am I just missing something?
总之,当以上任何问题可能成为问题时,请尽可能使用IntentServices、HandlerThread或ThreadPoolExecutor代替AsyncTask。这确实需要更多的工作,但您的应用程序将更加安全。
如果想每过 x 秒执行一次计算,你应该在 Handler
上安排一个 Runnable
(使用 postDelayed()
),并且这个 Runnable
应该在当前 UI 线程中开始。如果想要在另一个线程中启动它,可以使用 HandlerThread
。
AsyncTask
对我们来说更容易使用,但不如 handler
好用。
AsyncTask
假定你会在UI线程上完成一些后台工作。另外,你只能执行它一次(之后,它的状态为FINISHED
,如果再试图执行它,你将得到一个异常)。此外,它的灵活性不太大。是的,你可以使用THREAD_POOL_EXECUTOR
进行并行执行,但这可能不值得努力。
Handler
没有什么假定,除了处理Runnables和Messages。此外,你可以随意运行它多次。你可以自由决定它应该附加到哪个线程上,如何与其他处理程序通信,也许使用HandlerThread
生成它们。因此,它更加灵活,适用于一些重复的工作。Handler
示例。
这些是被问到的最好的面试问题。
AsyncTask - 它们用于在UI线程之外进行任务并在后台执行。
Handlers - Android没有直接的方法在UI和后台线程之间进行通信。必须使用Handlers通过消息队列发送消息或可运行对象。
因此,AsyncTasks用于需要在后台执行任务的情况,而Handlers用于UI和后台线程之间的通信。
doInBackground - 在另一个线程中执行工作。
onPostExecute - 将结果发布到UI线程,并且它会内部发送消息到主线程的处理程序。主UI线程已经有一个与之关联的looper和handler。
因此,如果您需要执行一些后台任务,请使用AsyncTask。但是最终,如果需要更新UI,则将使用主线程的处理程序。