android - 为什么通过自定义编辑文本从 onSelectionChanged 引用变量时没有实例化?
问题描述
根据调试器,引用的任何变量onSelectionChanged
都是空的,如果我运行示例应用程序并将以下内容添加到简单布局中,我的应用程序会因空指针而崩溃。
<com.dummy.DummyEditText
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
最简单的自定义示例AppCompatEditText
package com.dummy
import android.content.Context
import android.util.AttributeSet
import androidx.appcompat.widget.AppCompatEditText
class DummyEditText : AppCompatEditText {
constructor(context: Context) : super(context)
constructor(context: Context, attributeSet: AttributeSet) : super(context, attributeSet)
constructor(context: Context, attrs: AttributeSet, defStyleAttr: Int) : super(context, attrs, defStyleAttr)
private val a = String()
override fun onSelectionChanged(selStart: Int, selEnd: Int) {
a.toString()
}
}
使用堆栈跟踪
Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.String java.lang.String.toString()' on a null object reference
at com.dummy.DummyEditText.onSelectionChanged(DummyEditText.kt:15)
2020-10-05 12:14:25.794 22859-22859/com.dummy E/AndroidRuntime: at android.widget.TextView.spanChange(TextView.java:10744)
at android.widget.TextView$ChangeWatcher.onSpanAdded(TextView.java:13600)
at android.text.SpannableStringBuilder.sendSpanAdded(SpannableStringBuilder.java:1287)
at android.text.SpannableStringBuilder.setSpan(SpannableStringBuilder.java:777)
at android.text.SpannableStringBuilder.setSpan(SpannableStringBuilder.java:676)
at android.text.Selection.setSelection(Selection.java:96)
at android.text.Selection.setSelection(Selection.java:78)
at android.text.Selection.setSelection(Selection.java:153)
at android.text.method.ArrowKeyMovementMethod.initialize(ArrowKeyMovementMethod.java:312)
at android.widget.TextView.setText(TextView.java:6299)
at android.widget.TextView.setText(TextView.java:6139)
at android.widget.EditText.setText(EditText.java:121)
at android.widget.TextView.<init>(TextView.java:1642)
at android.widget.EditText.<init>(EditText.java:87)
at android.widget.EditText.<init>(EditText.java:83)
at androidx.appcompat.widget.AppCompatEditText.<init>(AppCompatEditText.java:74)
at androidx.appcompat.widget.AppCompatEditText.<init>(AppCompatEditText.java:69)
at com.dummy.DummyEditText.<init>(DummyEditText.kt:10)
所以问题是为什么变量为a
空?onSelectionChanged
无论如何实例化,它都应该在第一次被引用时DummyEditText
被实例化。我在这里想念什么?
任何有关正在发生的事情的指示都表示赞赏!
解决方案
在调试时,我发现它在块运行onSelectionChanged
之前被调用。init
如文档中所述:
在实例初始化期间,初始化程序块的执行顺序与它们在类主体中出现的顺序相同,并与属性初始化程序交错
OnSelectionChanged
调用时属性尚未初始化。
所以,我相信,发生的事情是在其中一个超类中,构造函数中的某些代码必须导致onSelectionChanged
被调用。因此,在初始化任何属性之前,onSelectionChanged
都会调用它,因此您的字段为空。
这是一个复制场景的示例:
open class Parent {
init {
demo()
}
open fun demo() {
print("Base class function called")
}
}
class Child() : Parent() {
val demoText = "12345"
override fun demo() {
super.demo()
println(demoText.toString()) // This line will throw a NPE as demoText is not yet instantiated
}
}
推荐阅读
- python - Python 到 ffmpeg 的 exe
- windows - 创建一个批处理文件以登录到 UNIX 服务器和 cd
- google-rich-snippets - 星级评分丰富的片段未在 Google 上显示
- amazon-web-services - 为什么 ec2 实例中的 2/2 检查未能达到 1/2
- python - 在 python 中使用多处理来创建对二维矩阵切片进行操作的进程
- java - 从 tomcat/lib Jar 访问打包在 war/lib 中的 Jaxb Jax 时出现 OpenJDK-11 问题
- sql-server - SQL SERVER DB 中的 COUNT 函数能否接受多个值
- uno-platform - 无法在 iPhone 模拟器中运行/部署 iOS 应用程序
- node.js - 节点:在路径中找不到带有两个 /npm/npm 的命令
- python - 分析列表列表中的数据并在 Python 中提取所需信息