Обход ошибки Android SDK: Handler.getLooper () очищает состояние прерывания потока - PullRequest
0 голосов
/ 19 марта 2020

Я потратил часы на то, чтобы выяснить причину, по которой мой код терял статус прерывания потока, только чтобы обнаружить, что это на самом деле вызвано ошибкой в ​​Android SDK! Взгляните на метод Looper.getLooper():

    /**
     * This method returns the Looper associated with this thread. If this thread not been started
     * or for any reason isAlive() returns false, this method will return null. If this thread
     * has been started, this method will block until the looper has been initialized.  
     * @return The looper.
     */
    public Looper getLooper() {
        if (!isAlive()) {
            return null;
        }

        // If the thread has been started, wait until the looper has been created.
        synchronized (this) {
            while (isAlive() && mLooper == null) {
                try {
                    wait();
                } catch (InterruptedException e) {
                }
            }
        }
        return mLooper;
    }

Обратите внимание, что он ест InterruptedException без повторного прерывания!

Итак, теперь я знаю, что это не проблема с моим код, каков наилучший способ обойти это? Должен ли я сохранять состояние прерывания моего потока во флаге перед вызовом .getLooper(), а затем после этого вызова прерывать себя, если установлен флаг? Любые идеи будут оценены:)

1 Ответ

0 голосов
/ 19 марта 2020

Этот метод общедоступен, вы можете создать свой собственный обработчик, расширив его и переопределив метод, чтобы заставить его делать то, что вы хотите, не вызывая супер

 public class BetterHandler extends Handler {
   @Override
   public Looper getLooper(){ 
        if (!isAlive()) {
        return null;
    }

    // If the thread has been started, wait until the looper has been created.
    synchronized (this) {
        while (isAlive() && mLooper == null) {
            try {
                wait();
            } catch (InterruptedException e) {
               throw e
            }
        }
    }
    return mLooper;
   }

 }

И использовать новый обработчик где вам нужно. Очевидно, вы не можете заменить класс обработчика для тех, кто использует его вне вашего кода.

...