3 回答
TA贡献1802条经验 获得超4个赞
AsyncTask 实例只能使用一次。
相反,只需将您的任务称为 new MyAsyncTask().execute("");
来自AsyncTask API文档:
线程规则
此类必须遵循一些线程规则才能正常工作:
必须在UI线程上创建任务实例。
必须在UI线程上调用execute(Params ...)。
不要手动调用onPreExecute(),onPostExecute(Result),doInBackground(Params ...),onProgressUpdate(Progress ...)。
该任务只能执行一次(如果尝试第二次执行,则会抛出异常。)
TA贡献1845条经验 获得超8个赞
在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保留在堆中。
TA贡献1827条经验 获得超8个赞
我遇到过同样的问题。就我而言,我有我想在做任务onCreate()和onResume()。所以我使我的Asynctask静态,并从中获取实例。现在我们仍然有同样的问题。
所以我在onPostExecute()中做的是这样的:
instance = null;
请记住,我检查静态getInstance方法,我的实例不为null,否则我创建它:
if (instance == null){
instance = new Task();
}
return instance;
postExecute中的方法将清空实例并重新创建它。当然这可以在课外完成。
- 3 回答
- 0 关注
- 809 浏览
添加回答
举报