我意识到您可以获得更多的自定义,但是使用并发库类是否比仅使用库存 AsyncTask 或仅创建线程并调用运行有性能(内存/速度)优势?
3 回答
如果您查看AsyncTask
源代码,您会发现它都是FutureTask
基于java.util.concurrent.*
.
我想如果有的话,使用AsyncTask
更方便和纯粹FutureTask
只会带来一点好处。尽管您可以选择使用其他 APIjava.util.concurrent.*
来完成更复杂的任务。
AsyncTask 带来的主要是易用性。这种工作范式,在后台运行这个方法,而在 UI 线程上的这个其他方法非常适合可用性(尽管我通过创建 vanilla AsyncTask 的子类进行了改进,使异常处理更简单)。我认为 AsyncTask 非常适合使用请求-响应类型的调用来调用服务。但是,并非所有类型的并发都对 AsyncTask 有效。
现在,有些任务 AsyncTask 不适合。例如,如果您想一次从服务器加载多个图像。AsyncTask 可能不是最佳选择。一方面,AsyncTasks 只能运行一次并且不能重新启动。AsyncTasks 拥有他们运行后台方法的线程,并且该线程不能被重用或共享。因此,如果您有 10 或 20 个图像,则意味着如果您使用 AsyncTasks,则需要创建和关闭 10 或 20 个线程。或者一次加载所有图像,这意味着在通过 20 次单独调用从服务器完全加载所有图像之前,您的 UI 不会更新。要么你为更好的 UI 响应支付更多的内存、资源等,要么你的 UI 为更低的开销付出了代价。两者都不是很好。
一个更好的选择是加载一个线程一次,发送几个轻量级的作业来运行,然后将它们发送回 UI 线程。我创建了自己的 AsyncTask 版本,我称之为 PipelineHandler,它创建一个线程,并运行发布到它的作业。这些作业与 AsyncTask 非常相似,因为它们有一个在 UI 线程上调用的方法,以及另一个在 UI 线程上调用以执行更新的方法。这样做的好处是我可以利用单个线程来运行任意数量的作业。而且我可以根据需要轻松扩展为队列服务的线程,而无需更改配置选项以外的任何内容。在幕后,它使用 Java 并发类 ExecutorService,但也利用 Handler 提供在 UI 线程上运行某些东西的能力。
因此,为了回答您的问题,我认为 AsyncTask 非常适合服务请求响应类型调用等单次作业,但不适用于下载图像或下载文件等批处理,尤其是在您必须同时拨打多个电话的情况下。Java 并发库可以在帮助您执行这些类型的任务方面发挥作用,但由于它们只解决了一半的问题,即在线程上运行事物,因此受到限制。Java 并发库适合批处理作业运行,但不适合与 UI 线程交互。因此,您必须经常将它们组合在一起才能获得解决方案。
AsyncTask
主要是SwingWorker
在桌面上比较,而不是并发 API。它在后台使用线程,但提供了帮助您在 UI 线程中与 UI 组件交互的方法。