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


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

5 191

5 ответов:

по моему опыту называя это работал отлично!

handler.removeCallbacksAndMessages(null);

в документах для removeCallbacksAndMessages он говорит...

удалите все ожидающие сообщения обратных вызовов и отправленных сообщений, объект которых является токеном. если маркер 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.пакет ОС может вызвать их). Возможно, вам придется создать тонкий Handler подкласс для управления списком Runnables по мере их размещения / выполнения...или посмотрите на другую парадигму для передачи ваших сообщений между каждым Activity

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

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

определите новый обработчик и runnable:

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 экземпляров. Таким образом, вы потеряли необходимые ссылки, которые принадлежат проводник и 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 что вы используете'.