同时使用多个AsyncTasks进行HttpClient请求

9

我正在开发一个需要同时下载多个文件的应用程序。我为每个文件创建了一个具有自己的HttpClientAsyncTask,但是下一个文件只会在前一个文件下载完成后才开始下载。

这可能是服务器端的问题吗?


你能提供AsyncTask的代码或者调用它的代码吗? - Jason Sperske
3个回答

20

这是因为在Honeycomb版本中,AsyncTask的管理方式发生了变化。之前,如果你启动了3个AsyncTasks,它们会同时运行。但从HC开始,如果你的目标SDK设置为12或更高版本,则这些任务会排队并逐一执行(请参见此讨论)。为了解决这个问题,请按照以下方式启动你的AsyncTasks:

task.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, params);

改为:

task.execute(params);

如果你的目标也包括旧版本的安卓系统,那么你需要使用条件代码:
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
   task.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, params);
} else {
   task.execute(params);
}

或将其包装在一个单独的辅助类中:

public class Utils {

    public static <P, T extends AsyncTask<P, ?, ?>> void executeAsyncTask(T task) {
        executeAsyncTask(task, (P[]) null);
    }

    @SuppressLint("NewApi")
    public static <P, T extends AsyncTask<P, ?, ?>> void executeAsyncTask(T task, P... params) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
            task.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, params);
        } else {
            task.execute(params);
        }
    }
 }

并且使用将是即:

Utils.executeAsyncTask( new MyAsyncTask() );

1
请注意,如果您要使用线程池执行器发送并行HTTP请求,则需要查看以下内容:如何检查线程池中是否存在正在发送的现有请求,否则它将拒绝并抛出RejectedExecutionException异常。https://dev59.com/-2fWa4cB1Zd3GeqPiJDe - Abs
非常好的答案!对我非常有帮助! - Kunal Singh

1

在首次引入时,AsyncTasks 在单个后台线程上串行执行。从 DONUT 开始,这被更改为线程池,允许多个任务并行操作。从 HONEYCOMB 开始,任务在单个线程上执行,以避免由并行执行引起的常见应用程序错误。来源

因此,根据版本,AsyncTask 可能不会并行执行。对于像文件下载这样的任务,您应该使用线程池,使用 Executor

或者您可以使用 executeOnExecutor 方法。


0

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接