多次执行AsyncTask

在我的Activity中,我使用了一个从AsyncTask和一个AsyncTask实例参数的类。 当我调用mInstanceOfAT.execute("")一切都很好。 但是,当我按下一个更新button时,应用程序崩溃,再次调用AsyncTask(万一networking工作不起作用)。 原因然后出现一个例外说

无法执行任务:任务已经执行(任务只能执行一次)

我曾尝试调用Asyctask实例的cancel(true),但它也不起作用。 迄今为止唯一的解决scheme是创buildAsyntask的新实例。 那是正确的方法吗?

谢谢。

AsyncTask实例只能使用一次。

相反,只需要调用你的任务像new MyAsyncTask().execute("");

从AsyncTask API文档:

线程规则

有一些线程规则必须遵循这个类才能正常工作:

  • 任务实例必须在UI线程上创build。
  • 必须在UI线程上调用execute(Params …)。
  • 不要手动调用onExcute(),onPostExecute(Result),doInBackground(Params …),onProgressUpdate(Progress …)。
  • 该任务只能执行一次(如果尝试执行第二次执行,则会引发exception。)

在Steve Prentice的回答中,详细介绍了ASyncTask的实际发生的原因。然而,尽pipe您限制了多less次执行ASyncTask,但是在线程运行时,您可以自由地做自己喜欢的事情。 。

把你的可执行代码放到doInBackground()中的一个循环中,并使用并发锁来触发每个执行。 您可以使用publishProgress()/ onProgressUpdate()检索结果。

例:

 class GetDataFromServerTask extends AsyncTask<Input, Result, Void> { private final ReentrantLock lock = new ReentrantLock(); private final Condition tryAgain = lock.newCondition(); private volatile boolean finished = false; @Override protected Void doInBackground(Input... params) { lock.lockInterruptibly(); do { // This is the bulk of our task, request the data, and put in "result" Result result = .... // Return it to the activity thread using publishProgress() publishProgress(result); // At the end, we acquire a lock that will delay // the next execution until runAgain() is called.. tryAgain.await(); } while(!finished); lock.unlock(); } @Override protected void onProgressUpdate(Result... result) { // Treat this like onPostExecute(), do something with result // This is an example... if (result != whatWeWant && userWantsToTryAgain()) { runAgain(); } } public void runAgain() { // Call this to request data from the server again tryAgain.signal(); } public void terminateTask() { // The task will only finish when we call this method finished = true; lock.unlock(); } @Override protected void onCancelled() { // Make sure we clean up if the task is killed terminateTask(); } } 

当然,这比传统的ASyncTask使用稍微复杂一些,并且您放弃使用publishProgress()来进行实际的进度报告。 但是如果你关心内存,那么这种方法将确保在运行时只有一个ASyncTask保留在堆中。

我已经做了我的旋转任务静态,然后帮助我附加,分离,并重新附加到旋转更改UI线程。 但回到你的问题,我所做的是创build一个标志,看看线程是否正在运行。 当你想重新启动线程时,我检查是否正在运行循环任务,如果我吐司警告。 如果不是,我把它设为空,然后创build一个新的,这将解决你所看到的错误。 此外,成功完成后,将已完成的旋转感知任务清零,以便再次准备好。

我遇到过同样的问题。 在我的情况下,我有一个任务,我想在onCreate()onResume( )。 所以我做了我的Asynctask静态,并从中获取实例。 现在我们仍然有同样的问题。

那么我在onPostExecute()中做了什么:

 instance = null; 

请记住,我检查静态getInstance方法,我的实例不是null,否则我创build它:

 if (instance == null){ instance = new Task(); } return instance; 

postExecute中的方法将清空实例并重新创build它。 当然,这可以在课堂以外完成。

是的,这是真的,文件说只能执行一个Asyntask。

每当你需要使用它,你必须实例:

 // Any time if you need to call her final FirmwareDownload fDownload = new FirmwareDownload(); fDownload.execute("your parameter"); static class FirmwareDownload extends AsyncTask<String, String, String> { }