Answers:
AsyncTask
实例只能使用一次。
而是像这样调用您的任务 new MyAsyncTask().execute("");
从AsyncTask API文档中:
为了使此类正常工作,必须遵循一些线程规则:
史蒂夫·普伦蒂斯(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。
IllegalMonitorStateException
在runAgain
(通过所谓的onProgressUpdate
)看到这样的回答:stackoverflow.com/a/42646476/2711811。它建议(并为我工作)signal()
需要用lock
/ 包围unlock
。这可能与publishProgress
呼叫的时间有关onProgressUpdate
。
是的,这是真的,医生说只能执行一个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> {
}