Reputation: 410
I am trying to write a Handler in an Activity that needs a reference to the activity. If I write like this
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)
}
// ...
}
}
}
}
This code compiles and works as expected. But if I try to pass a weak reference to the activity like this
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)
}
// ...
}
}
}
}
Now the compiler complains that tv_logged and mHandler are nullable receiver type and need to be accessed using ?.
I can understand that the val activity: MainAcitivity?
inside the handler is nullable because it comes from WeakReference.get() but how come the properties in MainActivity are also nullable?
Upvotes: 0
Views: 65
Reputation: 410
I understood this when I read the whole text at https://kotlinlang.org/docs/reference/null-safety.html#safe-calls
This has nothing to do with WeakReference as I suspected. It happens because safe call operator returns a nullable type even when accessing non-nullable type properties. (The doc doesn't really specify this as explicitly and clearly.)
Upvotes: 0
Reputation: 8841
Its because the return type of activity?.tv_logged
is (assuming its a TextView
) , TextView? . In Kotlin docs , where an alternative is proposed to checking null
via if
condition
Your second option is the safe call operator, written ?. b?.length This returns b.length if b is not null, and null otherwise. The type of this expression is Int? .
To perform a certain operation only for non-null values, you can use the safe call operator together with let:
activity?.let{ //access activity via `it`}
Upvotes: 1