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?
没错。但是你错过了 Fragment
和 Layout
膨胀 "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 = ...
我有一个 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?
没错。但是你错过了 Fragment
和 Layout
膨胀 "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 = ...