Kotlin:EditText 在 afterTextChanged() 中为空

Kotlin: EditText is null in afterTextChanged()

我有一个 EditText,我正在向其中设置错误或在文本更改后消除错误。但是,当我尝试从 afterTextChanged() 方法访问 EditText 时,我得到了 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 不应该被调用,对吧?如何预防?

How can that happen?

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

If Fragment is destroyed, TextWatcher shouldn't be called, right?

没错。但是你错过了 FragmentLayout 膨胀 "within" 它被销毁的顺序。这两个的销毁不是同时完成的 - Layout 首先被销毁。

如您所见,TextWatcher 是一个 anonymous inner class instance that keeps reference to its outer class, your Fragment, which is to be destroyed last. The key point here is so that any text changes within EditText coming from the TextWatcher are done asynchronously - your app's process view gets "notifications" from another process in the system, soft keyboard app (default one)。

如果这样的 "notification" 在你的 EditText 被摧毁但你的 Fragment 没有被摧毁的时候出现,你会得到 NPE.

How can it be prevented?

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