要使用 AsyncTask 还是 Service?

Posted

技术标签:

【中文标题】要使用 AsyncTask 还是 Service?【英文标题】:To use AsyncTask or Service? 【发布时间】:2016-12-08 19:07:31 【问题描述】:

这是场景,在我的应用程序中,我有一个故事帖子功能。在创建帖子时,用户可以附加照片。然后,我想要的是在用户从中选择照片后将照片上传到我的服务器图库,而不是在用户单击发布按钮之后。上传完成后,回调会给出上传是否成功的信息。另外,如果有照片上传到服务器,然后用户点击发布按钮,所有正在上传的照片都将被取消。

伪代码

List tempList = [photoUri,photoUri,photoUri] 
List attachedPhotoUriList.copyValue(tempList);

for each photoUri in tempList

    uploadPhotoToServer(attachedPhotoUri,callback
           onSuccess:
              attachedPhotoUriList.remove(photoUri)
           onError:
    )

问题: 我在哪里可以上传照片以便将其与主线程分离,然后如果照片已成功上传或未在活动中返回回调?可以取消吗?

在 AsyncTask 或 Service 中?虽然答案不限于这两个,但您可以提出任何您认为合适的建议。

【问题讨论】:

【参考方案1】:

请记住,Service 默认在 UI 线程上运行,因此如果您使用它,您应该创建和管理自己的新 Thread,这意味着需要维护更多行代码。 IntentService 在自己的线程上运行,所以我更喜欢这个而不是 ServiceAsyncTask

我的建议是使用像retrofit 这样的第三方库来为您管理连接详细信息,如果考虑到您的项目要求的话;在this tutorial 中,您可以看到如何将文件上传到服务器,改造处理 UI 线程问题,在其外部执行请求,并在其中返回响应,因此您可以更新您的视图。

【讨论】:

谢谢,这个答案真的很有帮助。还有一个问题,我也可以使用 Volley 吗? 当然,Volley 是另一个非常常见的用于处理 HTTP 请求的库。我没有用它上传文件,但这样做应该没有问题。【参考方案2】:

如果您使用 AsyncTask,则必须注意方向更改。对我来说,这并不是最好的方式。

我认为使用服务更清洁。更具体的是IntentService。

此服务旨在在其自己的线程上处理一次性任务(普通服务在 UI 线程上运行)。您可以通过发送带有图像 Uri 作为额外内容的 Intent 来启动它。在 IntentService 中,您处理接收到的带有附加内容的 Intent(从 Uri 上传图像)。完成后,您通过向该 Activity 发送广播来通知您的 Activity(当然您必须为此注册一个侦听器)。一个很好的教程是here。 Google 的官方指南是here。

一旦开始,您就不必关心方向变化。

取消 IntentService 有点棘手,but can be done。但也许你应该让它上传并在服务器端丢弃它,如果一段时间后没有上传合适的帖子(或其他机制)。

在您的情况下不需要带有AIDL 的服务,因为活动和服务在同一个进程中运行。

【讨论】:

以上是关于要使用 AsyncTask 还是 Service?的主要内容,如果未能解决你的问题,请参考以下文章

在服务中使用 AsyncTask

在 AsyncTask 或 Service 上下载文件?

Android最好使用AsyncTask、Service或其他

Android:需要一个使用的想法:Service、Thread、AsyncTask 或其他东西

我应该为我的应用程序使用 AsyncTask 还是 IntentService?

谁能用 service 和 asyncTask 向我解释我的简单应用程序中的服务?