【问题标题】:Running multiple threads in Asynctask在 Asynctask 中运行多个线程
【发布时间】:2016-08-18 19:32:06
【问题描述】:

我从一个 URL 获取信息并将该信息发送到多个 URL。我在 AsyncTask 中的“for”上运行它,但事实是,如果其他操作没有返回错误或成功,它就不会继续。所以我想在 AsyncTask-ception 中执行此操作,但遗憾的是 Android 不允许我这样做。

所以,我有两个 AsyncTask 类。这就是我发送到网站的课程:

class SendTo extends AsyncTask <Object,Object,String>{

    @Override
    protected String doInBackground(Object... strings) {
        ....
    }
}

这是我从网站上得到的任务:

class GetFrom extends AsyncTask <Object,Object,String>{

    @Override
    protected String doInBackground(Object... strings) {
        ....
        String param = anotherMagicalFunctionThatGivesParamToSend(strings[1]);
        for(i = 1; i < websites.length; i++){
            new SendTo.execute(websites[i],param);
        }
    }
}

但遗憾的是,我在 AS 上遇到了这些错误:

方法execute必须从主线程调用,目前推断 线程是工作者

非静态方法 'execute(Params...)' 不能从 静态上下文

那么您有什么想法、解决方案或方法来实现这一目标吗?感谢您的帮助。

【问题讨论】:

  • SendTo.execute(params);。您不能以这种方式执行或启动 AsyncTask。它甚至可以编译!你应该首先创建一个你的类的实例,比如new SendTo().execute();
  • 从另一个 AsyncTask 的 doInBackground 启动 AsyncTasks 是没有意义的。无意义。你可以在 onPostExecute 中做。
  • @greenapps 有很多理由在另一个任务的后台启动一个任务。例如,您下载的资源需要您下载其他资源。您可以选择在其他 AsyncTask 中执行这些操作。问题是他试图调用一个类的实例方法。
  • @greenapps 请不要质疑我的语法,我已经写了一个示例代码,所以它可能是错误的,如果我收到错误但不是关于“你错过了'新'。”,这意味着我有一个成功的代码,对吧?另外,我想我不能同时运行多个 AsyncTask,对吗?

标签: java android multithreading android-asynctask


【解决方案1】:

正如在某些 cmets 和您看到的异常中所指出的,您不能从任意线程上下文(例如,另一个 AsyncTaskdoInBackground() 方法)启动 AsyncTask。而不是立即启动它们,将您的String“要发送的参数”收集到一个数组或Set 并从您的doInBackground() 方法中返回。然后,在您的onPostExecute() 方法中,返回值将作为参数提供。遍历每个条目在数组或Set 中并触发一个新的AsyncTask 来处理该事务。

如果您希望它们并行运行,请使用备用 executeOnExecutor 代替 AsyncTask,否则它们将各自串行运行。

您也可以使用自己的 ThreadPool 来完成类似的操作,这可以通过创建大量 AsyncTask 对象来减少堆抖动,因为它们是 1 次使用的。

【讨论】:

    【解决方案2】:

    您的第一个错误:Method execute must be called from the main thread, currently inferred thread is worker 是因为您从第一个任务的doInBackground() 调用您的第二个AsyncTaskdoInBackground() 是一个工作线程,你不能从后台线程执行另一个任务,它必须来自 UI 线程。 AsyncTask 用于短操作,如果您需要更复杂的操作,请考虑使用Thread

    您的第二个错误:Non-static method 'execute(Params...)' cannot be referenced from a static context 是因为您正在调用您的 AsyncTask,就好像它是静态的而不是实例一样。您对 new SendTo.execute(websites[i], param) 的调用似乎没问题,除了您不能有 2 个参数,execute() 的参数作为数组传入

    我建议不要为看似相似的请求设置 2 个单独的任务,而是设置 1 个任务,并添加一个定义您想要执行的操作类型的标志。 (发送或获取)然后在您的doInBackground() 检查标志并执行指定的操作。您似乎正在发送数据,然后尝试检索响应,因此当您的 SEND 操作完成时,添加一个您现在想要检索该数据的辅助标志,并在您的 onPostExecute() 中重新运行您的任务以进行其他操作.

    【讨论】:

      【解决方案3】:

      我假设您想启动 AsyncTask 在后台并行执行某些操作。

      为此,不要使用嵌套的AsyncTask,而应该使用ExecutorService,将任务提交到这样的工作池,收集结果,从异步任务返回。

      一些细节在ExecutorService docs for Android

      【讨论】:

      • 不,问题是他在静态上下文中的类而不是实例上调用执行。您可以使用 executeOnExecutor 轻松地并行运行多个 AsyncTask。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-07-16
      相关资源
      最近更新 更多