我正在尝试在需要引用活动的Activity中编写Handler。如果我这样写
class MainActivity : AppCompatActivity() {
private val mHandler = MainActivityHandler(this)
class MainActivityHandler(val activity: MainActivity) : Handler() {
override fun handleMessage(msg: Message?) {
when(msg?.what) {
MSG_CHANGE_TEXT -> {
activity.tv_logged.setText(R.string.title_main)
activity.mHandler.sendMessageDelayed(obtainMessage(SOMETHING), 3000)
}
// ...
}
}
}
}
此代码按预期编译和工作。但是如果我尝试将弱引用传递给像这样的活动
class MainActivity : AppCompatActivity() {
private val mHandler = MainActivityHandler(WeakReference(this))
class MainActivityHandler(val activityRef: WeakReference<MainActivity>) : Handler() {
private val activity
get() = activityRef.get()
override fun handleMessage(msg: Message?) {
when(msg?.what) {
MSG_CHANGE_TEXT -> {
activity?.tv_logged.setText(R.string.title_main)
activity?.mHandler.sendMessageDelayed(obtainMessage(SOMETHING), 3000)
}
// ...
}
}
}
}
现在编译器抱怨 tv_logged 和 mHandler 是可以为空的接收器类型,需要使用?进行访问。
我可以理解,处理程序中的val activity: MainAcitivity?
是可以为空的,因为它来自WeakReference.get()但是MainActivity中的属性怎么也可以为空?
答案 0 :(得分:1)
因为activity?.tv_logged
的返回类型是(假设它是TextView
),TextView? 。在Kotlin文档中,提出了通过null
条件检查if
的替代方案
您的第二个选项是安全通话操作员,写的? B'。长度 如果b不为null,则返回b.length,否则返回null。这个表达式的类型是Int?
要仅针对非空值执行特定操作,您可以使用安全调用操作符和let:
activity?.let{ //access activity via `it`}
答案 1 :(得分:0)
当我在https://kotlinlang.org/docs/reference/null-safety.html#safe-calls
阅读整篇文章时,我理解这一点这与我怀疑的WeakReference无关。这是因为安全调用操作符即使在访问非可空类型属性时也返回可空类型。 (该文档并没有明确而明确地指明这一点。)