当您学习为 Android 开发时,您会了解到如果在 ui 线程中运行任何类型的进程(需要超过 5 秒),系统将显示臭名昭著的 ANR 消息。就在那时他们介绍了邪恶的怪物...... AsyncTask。一开始你认为这个类是你的救星,但后来你意识到它是开发中最大的问题......处理旋转或 ui 事件变得如此成问题,甚至是痛苦的。你们怎么看... AsyncTasks 值得麻烦吗?无论屏幕旋转如何,还有其他方法可以减少执行长时间运行的任务的问题吗?我想你可能会说,嘿,你为什么不把它变成一个服务......是的,这是一个解决方案,但是让我们来看看我真正的问题。为什么我们不直接使用服务并完全停止使用 AsyncTasks...
2 回答
在开发过程中,为执行选择合适的组件总是好的。您需要明确您的要求,并根据要求在 aService
或AsyncTask
.
服务是一个独立于任何其他组件的 Android 组件。活动可能来来去去,但如果您愿意,服务可以持续存在。它们扮演着许多角色,从管理多个活动所依赖的状态到充当 cron 作业,再到处理更长的应用程序小部件更新。
AsyncTask 是一个安排在主应用程序线程之外做一些工作的类。对于 AsyncTask 的实现者和用户来说,它如何执行这种魔法通常并不重要。实际上,它使用线程池和工作队列。AsyncTask 使用 Handler 来帮助安排在主应用程序线程上完成的选定工作(例如,通知用户进度更新)。
有关更多说明,请参阅它们之间的区别。
AsyncTasks 和 Services 不是对等的。任何一个都可以调用另一个,它们的目的是不同的。我只有几件事要添加到路西法的回答中。
要记住的关键一点是,如果您的进程在后台,托管一个服务并被杀死,那么该服务将在某个时候重生。对于可能在进程中运行的 AsyncTask 被杀死时,情况并非如此。这意味着在服务中完成的工作可以保证在未来取得进展(尽管不能保证何时)。如果您有必须完成的工作,最好在服务中完成。
对 Service.onStart 和 Service.onStartCommand 的调用发生在进程的主线程上。如果您长时间阻止此操作,您将获得相同的“应用程序无响应”对话框。因此,在 Service 中使用 AsyncTask 可以很好地完成实际工作。
我倾向于使用从 Activity 启动的 AsyncTasks 来处理与 UI 相关的事情。这些通常是不需要工作的事情,它们的工作可以在未来轻松地重做。例如,这可能是从磁盘读取一堆图像或调用 Web 服务以查看用户是否有任何通知。这项工作可以再次完成,如果 UI 因进程被终止而被破坏,则无论如何都可能需要再次完成这项工作。
另一方面,如果您想说尽快将一组照片上传到网络,我会将其发送给一个服务,该服务将使用一个或多个 AsyncTasks 来完成。这是我想要完成的工作,如果它被打断,我想继续。如果您要使用服务,请考虑使用 IntentService,以便您的服务在其工作完成时停止。