Как удалить весь обратный вызов из обработчика?

У меня есть обработчик из моей суб-активности, который был вызван основным действием. Этот обработчик используется подклассами для postDelay некоторых Runnables, и я не могу управлять ими. Теперь, в событии onStop, мне нужно удалить их, прежде чем закончить действие (как-то я назвал finish (), но он все равно звонит снова и снова). Есть ли способ удалить все обратные вызовы из обработчика?

Solutions Collecting From Web of "Как удалить весь обратный вызов из обработчика?"

По моему опыту, это здорово!

handler.removeCallbacksAndMessages(null); 

В документах для removeCallbacksAndMessages сказано …

Удалите все ожидающие сообщения обратных вызовов и отправленные сообщения, obj которых является токеном. Если токен равен null , все обратные вызовы и сообщения будут удалены.

Для любого конкретного экземпляра Runnable вызовите Handler.removeCallbacks() . Обратите внимание, что он использует экземпляр Runnable сам, чтобы определить, какие обратные вызовы отменить регистрацию, поэтому, если вы создаете новый экземпляр каждый раз при создании сообщения, вам нужно убедиться, что у вас есть ссылки на точный Runnable для отмены. Пример:

 Handler myHandler = new Handler(); Runnable myRunnable = new Runnable() { public void run() { //Some interesting task } }; 

Вы можете вызвать myHandler.postDelayed(myRunnable, x) чтобы отправить другой обратный вызов в очередь сообщений в других местах вашего кода и удалить все ожидающие обратные вызовы с помощью myHandler.removeCallbacks(myRunnable)

К сожалению, вы не можете просто «очистить» весь MessageQueue для Handler , даже если вы сделаете запрос связанного с ним объекта MessageQueue потому что методы добавления и удаления элементов защищены от пакетов (только классы в пакете android.os могут вызывать их). Возможно, вам придется создать тонкий подкласс класса Handler для управления списком Runnable s, поскольку они отправлены / выполнены … или посмотрите на другую парадигму для передачи ваших сообщений между каждым действием

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

Если у вас нет ссылок Runnable, при первом обратном вызове получите obj сообщения и используйте removeCallbacksAndMessages (), чтобы удалить все связанные обратные вызовы.

Определить новый обработчик и запустить:

 private Handler handler = new Handler(Looper.getMainLooper()); private Runnable runnable = new Runnable() { @Override public void run() { // Do what ever you want } }; 

Задержка вызова:

 handler.postDelayed(runnable, sleep_time); 

Удалите обратный вызов из вашего обработчика:

 handler.removeCallbacks(runnable); 

На самом деле здесь есть немного, но очень важный момент. Вы должны сначала определить Handler и Runnable . Фактически removeCallbacks(runnable) работает правильно, но если вы определяете их каждый раз, вы можете не обрабатывать их.

Ложный путь:

  public class FooActivity extends Activity { private void handleSomething(){ Handler handler = new Handler(); Runnable runnable = new Runnable() { @Override public void run() { doIt(); } }; if(shouldIDoIt){ //doIt() works after 3 seconds. handler.postDelayed(runnable, 3000); } else { handler.removeCallbacks(runnable); } } public void onClick(View v){ handleSomething(); } } 

Если вы вызываете метод onClick(..) , вы никогда не прекращаете вызов метода doIt() перед его вызовом. Потому что каждый раз создается new Handler и new Runnable экземпляры new Runnable . Таким образом, вы потеряли необходимые ссылки, которые принадлежат обработчику и исполняемым экземплярам.

Истинный способ:

  public class FooActivity extends Activity { Handler handler = new Handler(); Runnable runnable = new Runnable() { @Override public void run() { doIt(); } }; private void handleSomething(){ if(shouldIDoIt){ //doIt() works after 3 seconds. handler.postDelayed(runnable, 3000); } else { handler.removeCallbacks(runnable); } } public void onClick(View v){ handleSomething(); } } 

Таким образом, вы не потеряли фактические ссылки, а removeCallbacks(runnable) работает успешно.

Ключевое предложение состоит в том, что «определите их как глобальные в своей Activity или Fragment что вы используете» .