使用AsyncTask进行多个文件下载

3

针对我的应用程序(支持Android 2.2+),我必须检查大量(约700个)不同网页的HTML代码,并从每个网页中检索单个名称。我已经将所有URL存储在一个数组中。

我现在使用单个Asynctask并像这样迭代URL数组:

(来自Asynctask的doinbackground片段)

publishProgress(urls.size());
int a = 0;
for(String code : urls) {
    if(!running) return null;
    try {
    URL url = new URL(code);
    HttpURLConnection con = (HttpURLConnection) url.openConnection();
    naam_codes.put(readStream(con.getInputStream(), true).get(0), code);
      } catch (Exception e) {
        running = false;
      }
    publishProgress(++a);

并且readstream为:

BufferedReader reader = null;
      ArrayList<String> html = new ArrayList<String>();
      try {
          reader = new BufferedReader(new InputStreamReader(in, Charset.forName("ISO-8859-1")));
          if (snel){
              //reading, matching and stuff
          }
          else {
              //other reading, matching and stuff
            }
          }       
      } catch (IOException e) {
        //pass
      } finally {
         if (reader != null) {
             try {
                 reader.close();
             } catch (IOException e) {
                 return null;
             }
         }
      }
      return html;

现在我的问题是必须等待一个下载和匹配完成后才能开始下一个。这应该可以加速,不是吗?在监控一段时间后,此过程似乎未充分利用CPU或网络带宽(?)。那我是否应该在单个Asynctask内迭代,还是在UI线程上进行迭代并执行多个Asynctasks?如果是后者,应该如何操作?


你是否急于处理这些数据?例如,Google Play目前不支持多个下载,只能一个一个地下载应用程序。 - Wroclai
请看我修改后的答案,使用了另一种方法。 - Vincent Mimoun-Prat
1个回答

2

在API 11之前,多个AsyncTasks不能充分利用多核处理器。此后,您可以为每个下载/解析创建一个AsyncTask,并使用executeOnExecutor函数和参数AsyncTask.THREAD_POOL_EXECUTOR并行执行它们。

来自文档

执行顺序

最初引入时,AsyncTasks在单个后台线程上串行执行。从DONUT开始,这已更改为一组线程,允许多个任务并行运行。从HONEYCOMB开始,为了避免并行执行导致的常见应用程序错误,任务在单个线程上执行。

如果您真正想要并行执行,可以使用THREAD_POOL_EXECUTOR调用executeOnExecutor(java.util.concurrent.Executor, Object[])。


如果我是你,我会构建自己的服务器(只需在某处启动一个CRON任务并运行一个PHP脚本+ MySQL数据库+用于提供数据的PHP脚本),不会让应用程序进行处理。

让您的服务器执行700次下载、解析,将您需要的内容存储到数据库中。然后让您的应用程序访问您的服务器脚本,该脚本将从数据库中选择所需的信息。

优势:

  • 您的服务器具有更好的带宽
  • 它具有更强的处理能力
  • 您的应用程序可以请求所需的任何数据,而不是下载和解析数百个页面。

不便之处:

  • 您可能会在提供新数据时引入一些延迟(取决于CRON任务执行周期和更新数据库的执行时间)

谢谢您的答复,我会从尝试您的第一个建议开始。如果那不能满足我的需求,我会尝试构建自己的服务器,这需要更多时间,因为我之前从没有做过 SQL 或 PHP,就像我之前从未制作过应用程序和进行过任何 Java(我的第一个)应用程序一样。 - XorJoep

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