Котлин: EditText является нулевым в afterTextChanged () - PullRequest
0 голосов
/ 28 февраля 2019

У меня есть EditText, и я устанавливаю в него ошибку или отклоняю ее после изменения текста.Однако каким-то образом я получаю NPE при попытке доступа к EditText с помощью метода afterTextChanged().

phone_number_input.addTextChangedListener(object : TextWatcher() {
        ...
        override fun afterTextChanged(s: Editable?) {
            if (isValid(s.toString()) 
                phone_number_input.error = null // <-- NPE happens here
            else
                phone_number_input.error = "Number is invalid"
        }
    })

Он не воспроизводится постоянно, но за последний месяц были десяткисбоев на разных устройствах, начиная с Android 4.4.2 до 6.0.1.

Как это может произойти?Если Fragment уничтожен, TextWatcher не должен вызываться, верно?Как это можно предотвратить?

1 Ответ

0 голосов
/ 01 марта 2019

Как это может произойти?

Скорее всего, когда это происходит, ваше приложение выходит на передний план, когда пользователь печатает (например, из-за входящего вызова).

Если Fragment уничтожено, TextWatcher не должно вызываться, верно?

Верно.Но вы упускаете порядок, в котором Fragment и Layout надуваются "внутри", это уничтожается.Разрушение для этих двух не выполняется одновременно - Layout уничтожается первым.

Как видите, TextWatcher является анонимным экземпляром внутреннего класса, который сохраняет ссылку на свой внешний класс , ваш Fragment, который должен быть уничтожен последним.Ключевым моментом здесь является то, что любые изменения текста в EditText, поступающие из TextWatcher, выполняются асинхронно - представление процесса вашего приложения получает «уведомления» от другого процесса в системе, приложение с программной клавиатурой ( значение по умолчанию * 1025)*).

В случае, когда такое «уведомление» приходит одновременно, ваш EditText был уничтожен, а ваш Fragment нет, вы получаете NPE .

Как это можно предотвратить?

Просто используйте phone_number_input?.error = ...

...