Как отменить обработчик до времени в коде Android?

#android #android-handler

#Android #android-обработчик

Вопрос:

Я создаю таймер с задержкой в 1 минуту, чтобы завершить работу службы, если она не завершена. Выглядит так:

 private Handler timeoutHandler = new Handler();
  

внутри onCreate()

 timeoutHandler.postDelayed(new Runnable()
        {
            public void run()
            {
                Log.d(LOG_TAG, "timeoutHandler:run");

                DBLog.InsertMessage(getApplicationContext(), "Unable to get fix in 1 minute");
                finalizeService();
            }
        }, 60 * 1000);
  

Если я выполню задание до этой 1 минуты — я хотел бы отменить это отложенное действие, но не уверен, как.

Ответ №1:

На самом деле вы не можете сделать это с анонимным запускаемым файлом. Как насчет сохранения Runnable в именованную переменную?

 Runnable finalizer = new Runnable()
    {
        public void run()
        {
            Log.d(LOG_TAG, "timeoutHandler:run");

            DBLog.InsertMessage(getApplicationContext(), "Unable to get fix in 1 minute");
            finalizeService();
        }
    };
timeoutHandler.postDelayed(finalizer, 60 * 1000);

...

// Cancel the runnable
timeoutHandler.removeCallbacks(finalizer);
  

Комментарии:

1. tiemoutHandler.removeCallbacksAndMessages(null); чтобы удалить все обратные вызовы для обработки анонимного выполняемого файла. (как упоминалось в ответе Абдельхади)

2. Это замечательно, если вы не возражаете против удаления ВСЕХ обратных вызовов, а не только этого. OP спросил об удалении определенного обратного вызова.

Ответ №2:

Если вы не хотите сохранять ссылку на выполняемый объект, вы могли бы просто вызвать:

 timeoutHandler.removeCallbacksAndMessages(null);
  

В официальной документации говорится:

… Если токен равен нулю, все обратные вызовы и сообщения будут удалены.

Ответ №3:

Возможно, вы захотите заменить использование postDelayed на использование sendMessageDelayed вот так:

 private Handler timeoutHandler = new Handler(){
    @Override
    public void handleMessage(Message msg)
    {
            switch (msg.what){
        case 1:
            ((Runnable)msg.obj).run();
            break;
        }
    }
};
  

Затем отправьте сообщение:

 Message m = Message.obtain();
m.what = 1;
m.obj = new Runnable(){
            public void run()
            {
                Log.d(LOG_TAG, "timeoutHandler:run");

                DBLog.InsertMessage(getApplicationContext(), "Unable to get fix in 1 minute");
                finalizeService();
            }
        };
timeoutHandler.sendMessageDelayed(m, 60 * 1000);
  

а затем отменить:

 timeoutHandler.removeMessages(1);
  

Отслеживание выполняемого файла не требуется.

Ответ №4:

Если я выполню задание до этой 1 минуты — я хотел бы отменить это отложенное действие, но не уверен, как.

Используйте Handler.removeCallbacks(yourRunnable) .