Kotlin:EditText 在 afterTextChanged() 中为空
Posted
技术标签:
【中文标题】Kotlin:EditText 在 afterTextChanged() 中为空【英文标题】:Kotlin: EditText is null in afterTextChanged() 【发布时间】:2019-07-22 10:20:07 【问题描述】:我有一个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
,对吗?如何预防?
【问题讨论】:
尝试添加this@Activity/Fragment.phone_number_input...
【参考方案1】:
怎么会这样?
最有可能发生这种情况时,您的应用会在用户输入时进入前台(例如,由于来电)。
如果
Fragment
被销毁,TextWatcher
不应该被调用,对吧?
没错。但是你错过了Fragment
和Layout
在“内部”膨胀它被摧毁的顺序。这两者的销毁不会同时进行 - Layout
首先被销毁。
如您所见,TextWatcher
是anonymous inner class instance that keeps reference to its outer class,您的Fragment
,将在最后被销毁。这里的关键点是,EditText
中来自TextWatcher
的任何文本更改都是异步完成的——您的应用程序的进程视图从系统中的另一个进程、软键盘应用程序 (default one) 获取“通知”。
如果您的EditText
已被销毁但您的Fragment
未销毁时出现这样的“通知”,您将获得NPE。
如何预防?
只需使用phone_number_input?.error = ...
【讨论】:
感谢您的回答,请注意,在可空类型上使用s.toString
是可以的,因为 kotlin 具有该 public fun Any?.toString(): String
的扩展名,它会返回 "null"
以防 @987654338 @是null
以上是关于Kotlin:EditText 在 afterTextChanged() 中为空的主要内容,如果未能解决你的问题,请参考以下文章
Kotlin - DialogFragment中Edittext中的字符串不保存在数据类中
kotlin.NotImplementedError: 操作未在 EditText 上使用 addTextChangedListenerher 实现