How to Pass custom object via intent in kotlin
Asked Answered
N

10

72
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?

Neutralize answered 1/12, 2017 at 12:15 Comment(1)
What exactly is the error you are getting?Bond
G
100

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
Gubernatorial answered 1/12, 2017 at 14:48 Comment(4)
how to get the serializable class in other activity?Nod
@VikashParajuli in the context of this example you'll need to call val people = getIntent().getExtras().getSerializableExtra(EXTRA_PEOPLE) as? PeopleGubernatorial
its slower, you need to use Parcelable for better performanceCarbonate
@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: #3323574Gubernatorial
A
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
Auschwitz answered 16/8, 2018 at 14:38 Comment(0)
N
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")
Neutralize answered 28/6, 2018 at 7:30 Comment(1)
This works but you have to set this in your build.gradle: apply plugin: 'org.jetbrains.kotlin.android.extensions' android { androidExtensions { experimental = true } }Phylloxera
C
25

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'
Cole answered 10/12, 2019 at 19:24 Comment(2)
the solution more clean and simple.Sisyphus
kotlin-android-extensions is now deprecated, you should use kotlin-parcelize plugin for Parcelable implementation generator.Tortosa
A
9

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)
Allisonallissa answered 7/11, 2018 at 10:4 Comment(3)
Good news!! its not experimental anymoreCarbonate
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: #3323574Gubernatorial
getParcelableExtra & getSerializable both are deprecatedTalkingto
S
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.

Smack answered 13/4, 2018 at 7:33 Comment(0)
C
0

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

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

Have Fun

Calumny answered 1/12, 2017 at 12:19 Comment(1)
and how to receive data in another class?Nod
G
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 = [email protected] { 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)
Glabrous answered 10/5, 2021 at 10:52 Comment(2)
This will just work if the custom object is parcable. Would be great if you provide some sample Code.Mcclenaghan
edited the answer with an example @MarcelHofgesangGlabrous
G
0

Code for linking the two activities and passing name to second activity MainActivity.kt

val button = findViewById<Button>(R.id.button)

    button.setOnClickListener() {
        val name = findViewById<EditText>(R.id.editText)
        val message = name.text.toString()

        intent = Intent(this, SecondActivity::class.java)
        intent.putExtra("EXTRA MESSAGE", message)
        startActivity(intent)
    }

Main.xml

 <Button
    android:id="@+id/button"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_marginStart="8dp"
    android:layout_marginEnd="8dp"
    android:layout_marginBottom="8dp"
    android:text="Click"
    app:layout_constraintBottom_toBottomOf="parent"
    app:layout_constraintEnd_toEndOf="parent"
    app:layout_constraintStart_toStartOf="parent" />

<EditText
    android:id="@+id/editText"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:ems="10"
    android:inputType="text"
    android:text="Name"
    app:layout_constraintBottom_toBottomOf="parent"
    app:layout_constraintEnd_toEndOf="parent"
    app:layout_constraintStart_toStartOf="parent"
    app:layout_constraintTop_toTopOf="parent" />

secondactivity.kt

 val message = intent.getStringExtra("EXTRA MESSAGE")
    val textView = findViewById<TextView>(R.id.textView2).apply {
        text = message
    }


    Toast.makeText(this, "Name is : $message",Toast.LENGTH_LONG).show()
    val button2 = findViewById<Button>(R.id.button2)
    button2.setOnClickListener(){
        intent = Intent(this,MainActivity::class.java)
        startActivity(intent)
    }

second.xml

  <TextView
    android:id="@+id/textView2"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_marginStart="8dp"
    android:layout_marginTop="8dp"
    android:layout_marginEnd="8dp"
    android:layout_marginBottom="8dp"
    android:text="SecondActivity"
    android:textSize="18sp"
    app:layout_constraintBottom_toBottomOf="parent"
    app:layout_constraintEnd_toEndOf="parent"
    app:layout_constraintHorizontal_bias="0.498"
    app:layout_constraintStart_toStartOf="parent"
    app:layout_constraintTop_toTopOf="parent"
    app:layout_constraintVertical_bias="0.345" />

<Button
    android:id="@+id/button2"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_marginBottom="8dp"
    android:layout_marginEnd="8dp"
    android:layout_marginStart="8dp"
    android:layout_marginTop="8dp"
    android:text="back"
    app:layout_constraintBottom_toBottomOf="parent"
    app:layout_constraintEnd_toEndOf="parent"
    app:layout_constraintStart_toStartOf="parent"
    app:layout_constraintTop_toTopOf="parent"
    app:layout_constraintVertical_bias="0.774" />
Gayegayel answered 13/3, 2024 at 13:29 Comment(0)
A
-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.

Agleam answered 1/12, 2017 at 12:26 Comment(0)

© 2022 - 2025 — McMap. All rights reserved.