Android 为什么从WeakReference.get()获得的类的非null类型属性会更改为nullable
我试图在需要引用活动的活动中编写处理程序。如果我这样写Android 为什么从WeakReference.get()获得的类的非null类型属性会更改为nullable,android,kotlin,weak-references,android-handler,Android,Kotlin,Weak References,Android Handler,我试图在需要引用活动的活动中编写处理程序。如果我这样写 class MainActivity : AppCompatActivity() { private val mHandler = MainActivityHandler(this) class MainActivityHandler(val activity: MainActivity) : Handler() { override fun handleMessage(msg: Message?) {
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)
}
// ...
}
}
}
}
这段代码按照预期编译和工作。但是,如果我试图传递一个弱引用到像这样的活动
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)
}
// ...
}
}
}
}
class MainActivity:AppCompatActivity(){
private val mHandler=MainActivityHandler(WeakReference(this))
类MainActivityHandler(val activityRef:WeakReference):Handler(){
私人增值税活动
get()=activityRef.get()
覆盖有趣的handleMessage(消息:Message?){
什么时候(味精?。什么){
MSG\u更改\u文本->{
活动?.tv_logged.setText(R.string.title_main)
活动?.mHandler.sendMessageDelayed(获取消息(某物),3000)
}
// ...
}
}
}
}
现在编译器抱怨说,tv_logged和mHandler是可为空的接收器类型,需要使用访问?。
我可以理解处理程序中的
val activity:MainAcitivity?
是可以为空的,因为它来自WeakReference.get(),但是为什么MainActivity中的属性也是可以为空的呢?这是因为activity?的返回类型。tv\u logged
是(假设它是TextView
),TextView。在Kotlin文档中,建议通过if
条件检查null
你的第二个选择是安全呼叫接线员,写着?。
b?长度
如果b不为null,则返回b.length,否则返回null。此表达式的类型为Int
要仅对非空值执行特定操作,可以将safe call运算符与let一起使用:
activity?.let{ //access activity via `it`}
当我在教室里读全文时,我明白了这一点
正如我所怀疑的,这与WeakReference无关。发生这种情况的原因是,即使在访问不可为null的类型属性时,安全调用运算符也会返回可为null的类型。(文档并没有明确说明这一点。)它是有效的。我可以在没有安全呼叫接线员的情况下访问登录的电视。但是,在activity's let block中,tv_logged(或mHandler)如何更改为非空类型?为什么使用“活动”访问时会记录tv_并使mHandler为空?。但是在活动?内部访问时不可为null。让{}块?