RemoveCallbacks не останавливается

Я звоню из метода:

myHandler.postDelayed(mMyRunnableHide, 6000); 

Который вызывает:

 public Runnable mMyRunnableHide = new Runnable() { public void run() { mTextDisplay.setText(""); DisplayX(); } }; 

Если нажата кнопка на экране, я хочу остановить runnable:

  Button next = (Button) findViewById(R.id.Breaction); next.setOnClickListener(new View.OnClickListener() { public void onClick(View view) { myHandler.removeCallbacks(mMyRunnableHide); mTextDisplay.setText(""); DisplayX(); } }); } 

Removeecallbacks не останавливает runnable. Что я делаю не так? Я использую правильный метод? Я просто хочу, чтобы runnable «Not Run», когда пользователь нажимает кнопку.

Спасибо за любую помощь.

Solutions Collecting From Web of "RemoveCallbacks не останавливается"

Мне кажется, что removeCallbacks(..) только останавливает ожидающие сообщения (Runnables). Если ваш runnable уже запущен, тогда его не остановить (по крайней мере, не так).

Кроме того, вы можете расширить класс Runnable и дать ему своего рода kill-переключатель следующим образом:

 public class MyRunnable implements Runnable { private boolean killMe = false; private void run() { if(killMe) return; /* do your work */ } private void killRunnable() { killMe = true; } } 

Это только предотвратит его запуск, но вы можете иногда проверять killMe и выручать. Если вы зацикливаете runnable (например, какой-то фоновый поток), вы можете сказать:

 while(!killMe) { /* do work */ } 

Надеюсь это поможет

EDIT Я просто хотел опубликовать обновление об этом. Начиная с этого оригинального сообщения, Google придумал отличный класс под названием AsyncTask, который обрабатывает все эти вещи для вас. Любой, кто читает это, должен смотреть на него, потому что это правильный способ делать что-то.

Вы можете прочитать об этом здесь

Вот еще один способ выполнить то, что описывает mtmurdock. Этот класс позволит редактировать переменные экземпляра в любом классе, чтобы ваш Runnable был определен как анонимный внутренний класс.

 package support; /** * Runnable that can be stopped from executing * @author JTRONLABS */ public abstract class KillableRunnable implements Runnable{ private boolean isKilled=false; /** * Instead of Overriding run(), override this method to perform a Runnable operation. * This will allow editing instance variables in the class that this Runnable is defined */ public abstract void doWork(); //The handler that posts this Runnable will call this method. //By default, check if it has been killed. doWork() will now be the method //override to implement this Runnable @Override final public void run(){ if(!isKilled){ doWork(); } } final public void kill(){ isKilled=true; } } 

Handler.removeCallback является синхронным и будет прекрасно работать:

  1. Вы вызываете postDelayed всегда в основной поток.
  2. Вы вызываете removeCallback всегда в основной поток
  3. Вы не вызываете postDelayed снова после удаления обратных вызовов.

Поэтому в вашем случае removeCallbacks вызывается из обработчика кнопок, который запускается в основном потоке. Но вы не postDelayed в своем коде точку, откуда вы называете postDelayed . Если вы вызываете это из фонового потока, где ваша проблема.

Если вы уверены, что не вызываете какие-либо из этих методов из фоновых потоков, а порядок звонков правильный, то вы можете оставить незаписанные задачи незарегистрированными из-за активности в настройках конфигурации (поворот экрана и т. Д.). Всегда всегда вызывайте removeCallbacks в методе onDestroy чтобы предотвратить такие проблемы.