скасування процесу handler.postdelayed


259

Я використовую handler.postDelayed()для створення періоду очікування до наступного етапу мого додатка. Під час періоду очікування я показую діалогове вікно із панеллю прогресу та кнопкою скасування .

Моя проблема полягає в тому, що я не можу знайти спосіб скасувати завдання postDelayed до того, як закінчиться час.



Сподіваємось, що ця суть допоможе gist.github.com/imammubin/a587192982ff8db221da14d094df6fb4 MainActivity як запуск екрана з функцією обробника та зруйнованого режиму, запуск Runnable на сторінку входу або сторінку подачі з базовою перевагою користувача для входу з firebase.
Мубін

Відповіді:


479

Я роблю це, щоб опублікувати затримку запуску:

myHandler.postDelayed(myRunnable, SPLASH_DISPLAY_LENGTH); 

І це для його видалення: myHandler.removeCallbacks(myRunnable);


74
Якщо ви можете дозволити скасувати всі зворотні дзвінки та повідомлення на обробниках і не хочете зберігати посилання на програму, третя точка у прийнятій відповіді на це питання - це ще одна альтернатива, яка, здається, працює в моєму випадку: stackoverflow. com / questions / 11299440 /… (по суті, викликає myHandler.removeCallbacksAndMessages (null);)
Мік

removeCallbacksAndMessages може зробити трюк, але особисто я вважаю за краще мати контроль над запланованими випусками. Ігнорування та обробка пари Runnables не призведе до вбивства вашої програми; інакше, якщо вам потрібно більше двох-трьох Runnables, вам може знадобитися щось більш потужне, imho.
andrea.rinaldi

59

У випадку, якщо у вас є кілька внутрішніх / анонімних бігунів, переданих одному обробнику, і ви хочете скасувати все при використанні одного і того ж події

handler.removeCallbacksAndMessages(null);

Відповідно до документації,

Видаліть очікувані повідомлення про зворотні дзвінки та надіслані повідомлення, об'єкт яких є маркером. Якщо маркер недійсний, всі зворотні дзвінки та повідомлення будуть видалені.


Це призведе до видалення всіх зворотних зворотних дзвінків одноразово. В іншому випадку зателефонуйте, removeCallbacks(callback) щоб видалити конкретний зворотний дзвінок
FindOutIslamNow

18

Інший спосіб - це сама поводження з Runnable:

Runnable r = new Runnable {
    public void run() {
        if (booleanCancelMember != false) {
            //do what you need
        }
    }
}

14
Чи не повинен booleanCancelMember бути остаточним, це означає, що його неможливо змінити і, таким чином, марно використовувати для цієї мети?
stealthcopter

9
@stealthcopter ні це не повинно бути.
Бенуа Джадінон

7
@pablisco Це не повинно бути остаточним, навіть якщо Runnable анонімний. Він може бути членом вкладеного класу.
Мартін

6
Не зволікаючи цього, але будьте обережні. При такому підході, якщо кілька забігів буде розміщено із затримкою, ви можете зіткнутися з неприємними умовами гонки. Це не скасовує Runnable, тому те, чи буде виконуватися цей код, залежить від значення booleanCancelMember в конкретний момент для кожного розміщеного Runnable. Що може швидко стати непередбачуваним.
Денніс К

1
Якщо Runnable НЕ є анонімним, це означає, що я маю на нього посилання ( rв даному випадку), що означає, що я можу використовувати myHandler.removeCallbacks(r);. Якщо Runnable є анонімним, тоді прапор буде членом класу, що додається, а це означає, що мені потрібна посилання на цей об’єкт, щоб змінити прапор, а це означає, що мені знову доведеться це мати r, а значить, я можу це зробити myHandler.removeCallbacks(r);. І якщо я роблю, myHandler.removeCallbacks(r);то такий прапор взагалі не потрібен. Я щось пропускаю?
nacho4d

1

Ось клас, що забезпечує метод скасування для дії, що затримується

public class DelayedAction {

private Handler _handler;
private Runnable _runnable;

/**
 * Constructor
 * @param runnable The runnable
 * @param delay The delay (in milli sec) to wait before running the runnable
 */
public DelayedAction(Runnable runnable, long delay) {
    _handler = new Handler(Looper.getMainLooper());
    _runnable = runnable;
    _handler.postDelayed(_runnable, delay);
}

/**
 * Cancel a runnable
 */
public void cancel() {
    if ( _handler == null || _runnable == null ) {
        return;
    }
    _handler.removeCallbacks(_runnable);
}}

0

Це працювало для мене, коли я зателефонував CancelCallBacks (це) всередині посади, який затримується для запуску, передаючи його через булевий

Runnable runnable = new Runnable(){
    @Override
    public void run() {
        Log.e("HANDLER", "run: Outside Runnable");
        if (IsRecording) {
            Log.e("HANDLER", "run: Runnable");
            handler.postDelayed(this, 2000);
        }else{
            handler.removeCallbacks(this);
        }
    }
};

3
У вашому коді немає "CancelCallBacks". Може, тому, що його не існує? :)
Неймовірний січень

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.