'How to Pass a List of Objects from activity A to activity B in Kotlin?

I have 2 Activities, I want to pass an arraylist of an Object and show it on a ListView

Activity A:

     btnGuardar.setOnClickListener{

                if(edtNombre.text.toString().equals("") || 
                     edtApellido.text.toString().equals("") || 
                     edtFecha.text.toString().equals("")){

                    Toast.makeText(this@Main2Activity, "Debes llenar todos los campos!", Toast.LENGTH_SHORT).show()
                }else{
                    var estadoSel : String
                    estadoSel = estado.onItemSelectedListener.toString()
                   var per = Persona(edtNombre.text.toString(),edtApellido.text.toString(),estadoSel,edtFecha.text.toString())
                    personas.add(per)
                    val intent = Intent(this@Main2Activity,Main3Activity::class.java)
                    //intent.putExtra("Personas",  personas as Serializable)
                    intent.putParcelableArrayListExtra("Personas", ArrayList(personas))
                    edtFecha.text = null
                    edtApellido.text = null
                    edtNombre.text = null
                    estado.setSelection(0)
                    Toast.makeText(this@Main2Activity, "Registro Guardado", Toast.LENGTH_SHORT).show()
                }
            }

Activity B:

 override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main3)
        supportActionBar?.setDisplayHomeAsUpEnabled(true)
        //val intent = Intent()
        val bundle = getIntent().extras
        var arr  = bundle?.getParcelableArrayList<Persona>("Personas")!!
        //var arr : ArrayList<Persona> = (ArrayList<Persona>())intent.getSerializableExtra("Personas")
        //intent.getSerializableExtra("Personas")
        //arr = intent.extras!!.get("Personas")
        val adapter = ArrayAdapter(this, android.R.layout.simple_list_item_1, arr)
        listaPersonas.adapter = adapter
    }

But I'm getting a Null Pointer Exception



Solution 1:[1]

In your activity B to get your list try like the following

var arr = this.getIntent().getParcelableArrayListExtra<Parcelable>("Personas")

and make sure your Persona is extend Parcelable like below.

class Persona() : Parcelable {
   // ....
   @Override
   public void writeToParcel(Parcel dest, int flags) {
       //....
   }

   private void readFromParcel(Parcel in) {
      //....
   }
   override fun describeContents(): Int {
      return 0
   }

   companion object CREATOR : Creator<Persona> {
    override fun createFromParcel(parcel: Parcel): Persona{
      return Persona(parcel)
    }

    override fun newArray(size: Int): Array<Persona?> {
      return arrayOfNulls(size)
    }
  }

}

Solution 2:[2]

In your app's build.gradle under android scope add this and sync gradle -

androidExtensions {
        experimental = true
    }

Then make your object class parceble as follows -

@Parcelize
data class Persona() : Parcelable {

}

Now you can send and receive Parcelable list by intent.

Update : @Parcelize is no more experimental now, follow this answer for updated implementation https://stackoverflow.com/a/64925204/9854554

Solution 3:[3]

In your, Activity A send array list with

intent.putParcelableArrayListExtra("Personas", personas)

In your, Activity B get array list with

intent.getParcelableArrayListExtra("Personas")

In your app's build.gradle inside android tag add this and sync with gradle -

androidExtensions {
        experimental = true
    }

Data Class

@Parcelize data class Persona(
    val name: String,
    ) : Parcelable

Solution 4:[4]

To pass List of Data via intent implement Parcelable interface on Model class.

Person Model Class:

import android.os.Parcel
import android.os.Parcelable


data class Person(val name: String?, val age: Int) : Parcelable {
    constructor(source: Parcel) : this(
        source.readString(),
        source.readInt()
    )

    override fun describeContents() = 0

    override fun writeToParcel(dest: Parcel, flags: Int) = with(dest) {
        writeString(name)
        writeInt(age)
    }

    companion object {
        @JvmField
        val CREATOR: Parcelable.Creator<Person> = object : Parcelable.Creator<Person> {
            override fun createFromParcel(source: Parcel): Person = Person(source)
            override fun newArray(size: Int): Array<Person?> = arrayOfNulls(size)
        }
    }
}

MainActivity:

class MainActivity : AppCompatActivity() {


    var personList = arrayListOf<Person>()

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)


        personList.add(Person("Person1", 31))
        personList.add(Person("Person2", 32))
        personList.add(Person("Person3", 33))

        var intent = Intent(this, BActivity::class.java)
        intent.putParcelableArrayListExtra("personList", personList)
        Handler().postDelayed( {startActivity(intent)}, 2000)
    }
}

BActivity:

class BActivity : AppCompatActivity() {


    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_b)

        val extras = intent.extras
        val personList = extras?.getParcelableArrayList<Person>("personList")


        if (personList != null) {

            personList.forEach { Log.i("BActivity", "Name: ${it.name} Age: ${it.age}" ) }

        }else{
            Log.i("BActivity", "PersonList in null");
        }
    }
}

Solution 5:[5]

Step 1. add this in your app build.gradle inside android scope.

 androidExtensions {
        experimental = true
    }

Step 2: Make object class implement Parcelable

@Parcelize
 class Persona():Parcelable {
}

Step 3. In activity A send data via intent:

  val intent = Intent(this, B::class.java)
            intent.putParcelableArrayListExtra("list", personaArrayList)
            startActivity(intent)

Step 4: In activity B for recieving data:

 val list = intent.getParcelableArrayListExtra<Persona>("list")

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1
Solution 2
Solution 3
Solution 4 Abu Yousuf
Solution 5