停止定期运行AsyncTask

时间:2014-06-04 11:23:53

标签: android android-asynctask

请参阅下面的更新部分,了解我的修改后的解决方案


目标

  • 定期轮询网址(例如每30秒),但仅限于活动位于前台
  • 如果活动不在前台,则停止轮询

定期执行

  • 处理程序对象通过postDelayed方法
  • 接收Runnable对象
  • 在Runnable对象的run方法中启动AsyncTask
  • 在AsyncTask的onPostExecute中,再次调用Handler对象的postDelayed
  • 在活动的onResume中,调用Handler对象的post方法
  • 在活动的onPause中,调用Handler对象的removeCallbacks以删除邮件队列中Runnable的待处理帖子

取消投票的问题

  • 即使我在onPause中删除了Runnable的待处理帖子,仍然会发生当前运行的执行其doInBackground方法的AsyncTask在其onPostExecute时将新的Runnable添加到队列中已启动(基本上在removeCallbacks
  • 中调用onPause后不久)

我现在如何解决

  • 布尔成员变量shouldPoll已添加到活动
  • onResume中设置为true,在onPause
  • 中设置为false
  • 在AsyncTask的onPostExecute中,我检查shouldPoll是否为真,只在那种情况下调用Handler对象的postDelayed

的关注

  • 正在使用shouldPoll变量吗?
  • 我有点担心,在极少数情况下,活动(以及shouldPoll变量)是否会发生某些事情;因此,以某种方式打破了AsyncTask的onPostExecute
  • 的逻辑

源代码段

MainActivity

boolean shouldPoll = false;

@Override
protected void onResume() {
    super.onResume();
    shouldPoll = true;
    handler.post(pollURLRunnable);
}

@Override
protected void onPause() {
    shouldPoll = false;
    handler.removeCallbacks(pollURLRunnable);
    super.onPause();
}

final Handler handler = new Handler();

final Runnable pollURLRunnable = new Runnable() {
    public void run() {
        PollingAsyncTask pollTimestampAsyncTask = new PollingAsyncTask();
        pollTimestampAsyncTask.execute();
    }
};

的AsyncTask

@Override
protected void onPostExecute(Result result) {
    if (result != null) {
        //Do something here
    }
    if (shouldPoll) {
        handler.postDelayed(pollURLRunnable, 10000);
    }
}

更新

MainActivity

@Override
protected void onResume() {
    super.onResume();
    handler.post(startIntentServiceRunnable);
    LocalBroadcastManager.getInstance(this).registerReceiver(statusBroadcastReceiver, new IntentFilter(Constants.MY_INTENT_FILTER));
}

@Override
protected void onPause() {
    handler.removeCallbacks(startIntentServiceRunnable);
    LocalBroadcastManager.getInstance(this).unregisterReceiver(statusBroadcastReceiver);        
    super.onPause();
}

final Handler handler = new Handler();

final Runnable startIntentServiceRunnable = new Runnable() {
    public void run() {
        Intent intent = new Intent(MainActivity.this, PollingService.class);
        startService(intent);
    }
};


final BroadcastReceiver statusBroadcastReceiver = new BroadcastReceiver() {
    public void onReceive(Context context, Intent intent) {
        //...
        //Do something useful with the extras from intent here
        //...
        handler.postDelayed(startIntentServiceRunnable, 2000);
    }
};

PollingService

@Override
protected void onHandleIntent(Intent intent) {
    //...
    //Perform the polling and prepare results here
    //...
    broadcastResults();

}

private void broadcastResults() {
    Intent intent = new Intent(Constants.MY_INTENT_FILTER);
    //...
    //Fill the intent extras with the data here
    //...
    LocalBroadcastManager.getInstance(this).sendBroadcast(intent);
}

1 个答案:

答案 0 :(得分:1)

您可以通过在后台线程中运行hander来跳过AsyncTask。然后将工作移动到您发布给处理程序的runnable。

    HandlerThread handlerThread = new HandlerThread("Background thread");
    handlerThread.start();
    handler = new Handler(handlerThread.getLooper());