问题: 我想要做的是在后台定期(每5秒左右)让AsyncTask轮询一个URL,如果收到特定数据,则禁用活动上的元素。我尝试创建一个单独的类并使用onPostExecute从activity类运行该方法以禁用ImageView,但我遇到了问题。我无法从其他类调用该方法,除非我将其设置为静态,如果我将其声明为静态,则无法使用findViewById访问ImageView。
当前状态: 我有一个运行RetrieveColorTask的TimerTask,它每隔5秒就会定期扩展AsyncTask。但这会导致异常,因为它试图多次执行同一个线程。
Timer timer = new Timer();
final RetrieveColorTask task = new RetrieveColorTask();
task.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, true);
AsyncTask.Status status = task.getStatus();
TimerTask doTask = new TimerTask() {
@Override
public void run() {
if(status.compareTo(AsyncTask.Status.FINISHED) == 0)
task.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, true);
}
};
timer.schedule(doTask, 5000, 5000);
我尝试的另一种方法是在TimerTask中创建一个新的RetrieveColorTask,但后来我不知道旧线程是否已经完成运行,最终创建了多个AsyncTasks,其中大多数处于WAIT状态。我所取得的最大进步是使用此代码:
Timer timer = new Timer();
final RetrieveColorTask[] task = new RetrieveColorTask[1];
final AsyncTask.Status[] status = new AsyncTask.Status[1];
final boolean[] isRun = {false};
TimerTask doTask = new TimerTask() {
@Override
public void run() {
if(task[0] == null) {
task[0] = new RetrieveColorTask();
status[0] = task[0].getStatus();
task[0].executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, true);
} else {
if(status[0].compareTo(AsyncTask.Status.FINISHED) == 0) {
task[0] = new RetrieveColorTask();
task[0].executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, true);
}
}
}
};
timer.schedule(doTask, 5000, 5000);
但是一旦任务第一次执行,它就会在此之后保持PENDING状态,所以它只运行一次。
我是Android编程的新手,所以我很感激任何建议
答案 0 :(得分:0)
放线
status[0] = task[0].getStatus();
在run()
- 方法的开头,以便每当TimerTask
执行该方法时它都会更新本地状态变量,因为现在您正在存储任务的状态。是第一次创建,但是在5秒后再次运行该方法并且task[0]
不再为null时,您不会更新它。
另外,我建议您创建一个常规变量来放置任务和状态,以使其更清晰,而不是使用数组,因为您只使用一个元素初始化它们,所以换句话说声明任务而像这样的状态变量:
RetrieveColorTask task = null;
RetrieveColorTask.Status status = null;
而且,我个人也会像这样进行状态检查
if(status == RetrieveColorTask.Status.FINISHED) ...
而不是使用compareTo()
方法,因为您永远不会使用它也可能返回的1
或-1
值。
希望这有帮助!