Kotlin:afterTextChanged()中EditText为null

时间:2019-02-28 13:21:28

标签: android kotlin nullpointerexception android-lifecycle android-textwatcher

我有一个EditText,并且在其中设置了错误或在更改文本后消除了该错误。但是,以某种方式尝试从EditText方法访问afterTextChanged()时得到 NPE

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 :(得分:2)

  

那怎么会发生?

最有可能的是,发生这种情况时,您的应用会在用户键入时(例如由于来电)进入前台。

  

如果Fragment被销毁,TextWatcher不应被调用,对吗?

对。但是您错过了FragmentLayout膨胀到“其内”的顺序。这两个对象的销毁并非同时完成-Layout首先被销毁。

如您所见,TextWatcher是一个anonymous inner class instance that keeps reference to its outer class,即您的Fragment,最后将被销毁。这里的关键点是,EditText中来自TextWatcher的所有文本更改都是异步完成的-您的应用程序的进程视图从系统中另一个进程的软键盘应用程序({{3 }}。

如果您的EditText被销毁而您的Fragment却没有被销毁,那么您会得到 NPE

  

如何预防?

只需使用phone_number_input?.error = ...