内部AsyncTask类定期轮询URL

时间:2017-03-14 15:19:14

标签: android android-asynctask

问题: 我想要做的是在后台定期(每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编程的新手,所以我很感激任何建议

1 个答案:

答案 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值。

希望这有帮助!