0

Maybe it's a silly question, but I've been thinking about it the whole morning. I try to get data from another activity via Register activity result using a nullable class, but Kotlin sees it as a nonnullable class and doesn't allow me to use

it.data?.getSerializableExtra 

or

it.data!!.getSerializableExtra

with it. When I press a button that launches this launcher the app crashes.

var userData = UserDat()

... 
onCreate(){ 

editLauncher = registerForActivityResult(ActivityResultContracts.StartActivityForResult()) {
                if (it.resultCode == RESULT_OK) {
                    userData = (it.data?.getSerializableExtra("userdata") as UserDat)
                    binding.apply {
                        tvUserAge.text = userData.age.toString()
                        tvUserHeight.text = userData.height.toString()
                        tvUserWeight.text = userData.weight.toString()
                    }
                } 
} 

        binding.btEditData.setOnClickListener() {
            editLauncher?.launch(Intent(this@Profile, MeasurmentsEditor::class.java))}

}

      *** Called Activity: ***


var dataSending = UserDat() ... onCreate(){ binding.btMeasureDone.setOnClickListener(){

dataSending.age = 16.0
    dataSending.height = binding.edHeight.text.toString().toDouble()
    dataSending.weight = binding.edWeight.text.toString().toDouble()

val editIntent = Intent().apply { putExtra("userdata", dataSending) } setResult(RESULT_OK, editIntent) finish()}



```   *** Class File: ***
class UserDat(var age:Double? = null, var height:Double? =null, var weight: Double? = null ):Serializable

Error text:

 Caused by: java.lang.NullPointerException: null cannot be cast to non-null type com.example.appname.UserDat
        at com.example.appname.Profile.onCreate$lambda-2(Profile.kt:38) /*38th line is 
userData = (it.data?.getSerializableExtra("userdata") as UserDat) */

I tried to create another class, copying it from another nullable class

class UserMeasurements(var neck:Double? = null, var shoulders:Double? = null, var chest:Double? = null):Serializable

without even changing variable names, but it still didn't work, though another registerActivityForResult that uses UserMeasurements works fine.

Rebuilding project didn't work either.

P.S. pls don't downgrade me, I'm just 16

W1ggex
  • 3
  • 2
  • Thanks, everyone. I really appreciate your help and I'm sorry for wasting your time, because actually the problem was caused because I left a setResult(RESULT_OK) line for another Intent that interrupted this ActivityForResult. Thank you a lot – W1ggex Dec 21 '22 at 00:44

3 Answers3

0

The line it.data?.getSerializableExtra("userdata") checks if data is not null and then gets the serializable data and casts it to UserData. if the data is null it puts null in the userdata field because you don't handle the null case.

Since you want to use a nullable value in the userdata just change this line:

`var userData = UserDat()`

to:

var userData: UserDat? = UserDat()

This specifies that your UserDat object can hold null values.

Daniel Jacob
  • 1,455
  • 9
  • 17
0

You have to use UserDat?

userData = (it.data?.getSerializableExtra("userdata") as UserDat?)

If you have null in you value, you need cast you value in class with <className>?

0

The issue in the following line of code:

userData = (it.data?.getSerializableExtra("userdata") as UserDat)

The right part of expression executed in few steps:

val data = it.data // data is nullable because it.data is nullable

val extraData = if(data != null) {
    data.getSerializableExtra("userdata")
} else {
    null // This is a result of data?.getSerializableExtra so extraData is nullable too
}

userData = extraData as UserDat // Crash here because as can't cast a null to UserDat

So to fix it you have to check result of extraData before cast or use default value.

Some thing like this:

if (it.resultCode == RESULT_OK) {
    userData = (it.data?.getSerializableExtra("userdata") as? UserDat) ?: return@ registerForActivityResult
    binding.apply {
        tvUserAge.text = userData.age.toString()
        tvUserHeight.text = userData.height.toString()
        tvUserWeight.text = userData.weight.toString()
    }
} 
Viacheslav Smityukh
  • 5,652
  • 4
  • 24
  • 42