我有一个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
,对吗?如何预防?
答案 0 :(得分:2)
那怎么会发生?
最有可能的是,发生这种情况时,您的应用会在用户键入时(例如由于来电)进入前台。
如果
Fragment
被销毁,TextWatcher
不应被调用,对吗?
对。但是您错过了Fragment
和Layout
膨胀到“其内”的顺序。这两个对象的销毁并非同时完成-Layout
首先被销毁。
如您所见,TextWatcher
是一个anonymous inner class instance that keeps reference to its outer class,即您的Fragment
,最后将被销毁。这里的关键点是,EditText
中来自TextWatcher
的所有文本更改都是异步完成的-您的应用程序的进程视图从系统中另一个进程的软键盘应用程序({{3 }}。
如果您的EditText
被销毁而您的Fragment
却没有被销毁,那么您会得到 NPE 。
如何预防?
只需使用phone_number_input?.error = ...