在我的活动中,我使用了一个从AsyncTask扩展的类和一个参数,它是AsyncTask的一个实例。当我调用mInstanceOfAT.execute("")
时,一切都很好。但当我按下更新按钮,再次调用AsyncTask时,应用程序崩溃(以防网络作业不起作用)。原因然后出现了一个异常,它说
无法执行任务:任务已经执行(一个任务只能执行一次)
我试着为Asyctask的实例调用cancel(true),但也不起作用。到目前为止,唯一的解决方案是创建Asyntask的新实例。这是正确的方式吗?
谢谢。
发布于 2011-06-16 22:49:03
AsyncTask
实例只能使用一次。
取而代之的是,将你的任务命名为new MyAsyncTask().execute("");
在AsyncTask应用编程接口文档中:
线程化规则
要让这个类正常工作,必须遵循一些线程规则:
必须在UI thread.
,则会引发异常
发布于 2011-06-16 23:09:57
Steve Prentice的回答很好地解释了ASyncTask“即发即忘”实例的原因--然而,当你执行一个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。
发布于 2016-03-04 19:51:03
我也有同样的问题。在我的例子中,我有一个任务,我想用onCreate()
和onResume(
来完成)。所以我把我的Asynctask设为静态的,并从中获取实例。现在我们仍然有同样的问题。
所以我在onPostExecute()中做的是:
instance = null;
请记住,我在静态getInstance方法中检查我的实例不为空,否则我将创建它:
if (instance == null){
instance = new Task();
}
return instance;
postExecute中的方法将清空实例并重新创建它。当然,这可以在课外完成。
https://stackoverflow.com/questions/6373826
复制相似问题