69
fun launchNextScreen(context: Context, people: People): Intent {
    val intent = Intent(context, NextScreenActivity::class.java)
    intent.putExtra(EXTRA_PEOPLE, (Parcelable) people)
    //intent.putExtra(EXTRA_PEOPLE, people as Parcelable)
    //intent.putExtra(EXTRA_PEOPLE, people)
    // tried above all three ways
    return intent
}

I tried the above code to pass an instance of the People class via intent using kotlin, but I am getting an error. What am I doing wrong?

ChrisMcJava
  • 2,145
  • 5
  • 25
  • 33
Ankit Kumar
  • 3,663
  • 2
  • 26
  • 38

9 Answers9

96

First, make sure the People class implements the Serializable interface:

class People : Serializable {
    // your stuff
}

Inner fields of People class must also implement the Serializable interface, otherwise you'll get runtime error.

Then it should work:

fun launchNextScreen(context: Context, people: People): Intent {
    val intent = Intent(context, NextScreenActivity::class.java)
    intent.putExtra(EXTRA_PEOPLE, people)
    return intent
}

To receive people back from Intent you'll need to call:

val people = intent.getSerializableExtra(EXTRA_PEOPLE) as? People
ChrisMcJava
  • 2,145
  • 5
  • 25
  • 33
A. Shevchuk
  • 2,109
  • 14
  • 23
  • 1
    how to get the serializable class in other activity? – Viks Mar 30 '18 at 06:20
  • 3
    @VikashParajuli in the context of this example you'll need to call `val people = getIntent().getExtras().getSerializableExtra(EXTRA_PEOPLE) as? People` – A. Shevchuk Mar 31 '18 at 22:05
  • 2
    its slower, you need to use Parcelable for better performance – a0x2 Apr 01 '20 at 11:22
  • 1
    @a2en that's something that everybody is saying, but nobody knows for sure) on small objects you would not see any difference. However, there is a way to make Serializable faster than Parcelable, for more information see Farhana answer in this thread: https://stackoverflow.com/questions/3323074/android-difference-between-parcelable-and-serializable – A. Shevchuk Apr 01 '20 at 13:38
44

Implement Serializable in the object:

data class Object (
        var param1: Int? = null,
        var param2: String? = null
) : Serializable

or

class Object : Serializable {
        var param1: Int? = null,
        var param2: String? = null
}

Then, you can pass the object using Intent:

val object = Object()
...
val intent = Intent(this, Activity2::class.java)
intent.putExtra("extra_object", object as Serializable)
startActivity(intent)

Finally, in Activity2 you get the object with:

val object = intent.extras.get("extra_object") as Object
fireb86
  • 1,723
  • 21
  • 35
25

Found a better way of doing this:

In your gradle:

apply plugin: 'org.jetbrains.kotlin.android.extensions'

android {
    androidExtensions {
        experimental = true
    }
}

In your data class:

@Parcelize
data class Student(val id: String, val name: String, val grade: String) : Parcelable

In source activity:

val intent = Intent(context, Destination::class.java)
        intent.putExtra("student_id", student)
        context.startActivity(intent)

In destination activity:

student = intent.getParcelableExtra("student_id")
Nicola Gallazzi
  • 7,897
  • 6
  • 45
  • 64
Ankit Kumar
  • 3,663
  • 2
  • 26
  • 38
  • 1
    This works but you have to set this in your build.gradle: apply plugin: 'org.jetbrains.kotlin.android.extensions' android { androidExtensions { experimental = true } } – Nicola Gallazzi Nov 01 '18 at 18:54
24

Parcelize is no longer experimental, as of Kotlin 1.3.60+!

Define a data class, adding @Parcelize annotation and extending Parcelable:

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

To add to intent:

val intent = Intent(context, MyTargetActivity::class.java)
intent.putExtra("people_data", student)
context.startActivity(intent)

In MyTargetActivity:

val people: People = intent.getParcelableExtra("people_data")

If you haven't yet, enable extensions in your app's build.gradle. This also enables data binding and other great advanced features

apply plugin: 'kotlin-android-extensions'
Gibolt
  • 42,564
  • 15
  • 187
  • 127
  • the solution more clean and simple. – Guillermo Tobar Jan 13 '21 at 16:01
  • 2
    `kotlin-android-extensions` is now deprecated, you should use `kotlin-parcelize` plugin for [Parcelable implementation generator](https://developer.android.com/kotlin/parcelize). – Micer Mar 30 '21 at 23:50
8

I found a better way to pass an object from one activity to another using Parcelable, it is faster than Serialization Android: Difference between Parcelable and Serializable?

first, add these lines of code inside build.gradle(app)

apply plugin: 'kotlin-android-extensions' in app.grable 

@Parcelize 
class Model(val title: String, val amount: Int) : Parcelable

passing with Intent--->

val intent = Intent(this, DetailActivity::class.java)
intent.putExtra(DetailActivity.EXTRA, model)
startActivity(intent)

Getting from intent --->

val model: Model = intent.getParcelableExtra(EXTRA)
Ashik Azeez
  • 404
  • 5
  • 8
  • 1
    Good news!! its not experimental anymore – a0x2 Apr 01 '20 at 11:21
  • 1
    that's something that everybody is saying, but nobody knows for sure) on small objects you would not see any difference. Also, nice to have this Kotlin sugar, but what about good old java? However, there is a way to make Serializable faster than Parcelable, for more information see Farhana answer in this thread: https://stackoverflow.com/questions/3323074/android-difference-between-parcelable-and-serializable – A. Shevchuk Apr 09 '20 at 07:51
  • getParcelableExtra & getSerializable both are deprecated – Adam Noor Jun 08 '23 at 07:58
3

This post might be useful for what you intend to do:

Is there a convenient way to create Parcelable data classes in Android with Kotlin?

Basically, kotlin provides some little extras:

@Parcelize
class User(val firstName: String, val lastName: String) : Parcelable

See the post for more info.

Javatar
  • 2,518
  • 1
  • 31
  • 43
0

in kotlin to start activity and pass some data you could try something like this:

startActivity(intentFor<NameOfActivity>(STRING to data))

Have Fun

Rafael Filipake
  • 114
  • 1
  • 4
0

you have to add the type inside <>...its working for me

val people = intent.getParcelableExtra<People>(EXTRA_PEOPLE) as People

In your PeopleDetailActivity activity, initialize viewModel in onCreate

viewModel = this@PeopleDetailActivity.viewModel.apply { postPeopleId(getPeopleFromIntent().id) }

And also initialize this method :

private fun getPeopleFromIntent() = intent.getParcelableExtra<People>(peopleId) as People

Write below code for passing the intent extras :

companion object {
        private const val objectId = "people"
        fun startActivityModel(context: Context?, people: People) {
            if (context != null) {
                val intent = Intent(context, PeopleDetailActivity::class.java).apply {
                    putExtra(
                        objectId,
                        people
                    )
                }
                context.startActivity(intent)
            }
        }
    }

Call the above method in your PeopleListViewHolder onClick

override fun onClick(v: View?) = PeopleDetailActivity.startActivityModel(context(), people)
-1

Your People class needs to implement Parcelable like this:

class People(): Parcelable{
// stuff


}

android studio will show you an error. Simple move your cursor to "People" and hit alt+enter. It should now show the option to generate a Parcelable implementation.

This generated code will contain something like

parcel.writeString(member1)
parcel.writeInt(member2)

and somewhere else

member1=parcel.readString()
member2=parcel.readInt()

Make sure that all members are contained in these methods and when modifying it, make sure that read and write is happening in the exact same order.

Adrian K
  • 3,942
  • 12
  • 15