Обработчики не заканчиваются после вызова removeCallbacksAndMessages (null) - PullRequest
0 голосов
/ 05 марта 2019

У меня есть два обработчика. Обработчик в обработчике. Они оба в цикле.

Обзор примерно такой,

for{
    handler.postDelayed(runnableA{
        for{
            handler2.postDelayed(runnableB{
                function();
            }, 3000);
        }
    }, 1000);
}

Я хотел прекратить работу обработчиков в любое время, когда пользователь нажимает back button. Итак, я создал два Runnable Classes, чтобы я мог использовать что-то вроде runnableA.removellbacksAndMessages(null).

Handler messageHandler;
Handler countDownHandler;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    Toast.makeText(this, "Start Play in 5 seconds", Toast.LENGTH_SHORT).show();

    countDownHandler = new Handler();

    for (int i = 7; i >= 0; --i) {
        final int idx = i;
        Runnable countRunnable = new CountRunnable(idx, countDownView);
        countDownHandler.postDelayed(countRunnable, 1000 * (7 - i));
    }
}

А это Runnable Classes.

public class CountRunnable implements Runnable {
    int idx;
    TextView countDownView;

    public CountRunnable(int idx, TextView countDownView) {
        this.idx = idx;
        this.countDownView = countDownView;
    }

    @Override
    public void run() {
        int messageSize = messageItems.size();
        for (int j = 0; j < messageSize; j++) {
            final int jdx = j;
            messageHandler = new Handler();
            Runnable messageRunnable = new MessageRunnable(jdx);
            messageHandler.postDelayed(messageRunnable, 3000 * jdx);
        }
    }
}

class MessageRunnable implements Runnable {
    int jdx;

    public MessageRunnable(int jdx) {
        this.jdx = jdx;
    }

    @Override
    public void run() {
        addMessageView(messageItems.get(jdx));
    }
}

Это onBackPressed():

@Override
public void onBackPressed() {
    super.onBackPressed();
    Toast.makeText(getApplicationContext(), "All Work Ended.", Toast.LENGTH_SHORT).show();
    scrollFlag = true;

    try {
        messageHandler.removeCallbacksAndMessages(null);
    } catch (Exception e) {
        Log.d(TAG, "messageHandler never used");
        e.printStackTrace();
    }
    try {
        countDownHandler.removeCallbacksAndMessages(null);
    } catch (Exception e) {
        e.printStackTrace();
    }
}
public void addMessageView(String message){
    try{
        mTextView.setText(message);
    }catch(Exception e){
        Toast.makeText(getApplicationContext(), "Abnormal End", Toast.LENGTH_SHORT).show();
    }
}

Но я продолжаю получать ошибки, потому что действие уже завершено, но обработчики не могут найти действие. Так, Abnormal End Toast сообщение показывает столько, сколько размер внутреннего цикла for.

Я могу проигнорировать это, если не использую сообщение Toast, но боюсь утечки памяти, плохо сформированной программы или чего-то в этом роде.

Как я могу решить эту проблему?

1 Ответ

1 голос
/ 05 марта 2019

Основная проблема в том, что вы создаете n числа CountRunnable с и m число MessageRunnables.Несмотря на создание более одного числа обработчиков, вы удаляете обратные вызовы только для последних созданных Hanlder.

. Вот что вы должны сделать:

Сохраните ссылку на все Handler s.и Runnables и вызовите messageHandler.removeCallbacksAndMessages(null); и countDownHandler.removeCallbacksAndMessages(null); на всех из них.

...