Как передать пользовательский объект через намерение в котлине

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
}

Я пробовал использовать приведенный выше код для передачи экземпляра класса People через намерение с помощью kotlin, но получаю сообщение об ошибке. Что я делаю неправильно?


person Ankit Kumar    schedule 01.12.2017    source источник
comment
Какую именно ошибку вы получаете?   -  person hotkey    schedule 01.12.2017


Ответы (9)


Сначала убедитесь, что класс People реализует интерфейс Serializable:

class People : Serializable {
    // your stuff
}

Внутренние поля класса People также должны реализовывать интерфейс Serializable, иначе вы получите ошибку времени выполнения.

Тогда должно работать:

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

Чтобы вернуть людей из Intent, вам нужно позвонить:

val people = intent.getSerializableExtra(EXTRA_PEOPLE) as? People
person A. Shevchuk    schedule 01.12.2017
comment
как получить сериализуемый класс в другом действии? - person Vikash Parajuli; 30.03.2018
comment
@VikashParajuli в контексте этого примера вам нужно будет вызвать val people = getIntent().getExtras().getSerializableExtra(EXTRA_PEOPLE) as? People - person A. Shevchuk; 01.04.2018
comment
он медленнее, вам нужно использовать Parcelable для лучшей производительности - person a0x2; 01.04.2020
comment
@ a2en это то, что все говорят, но никто не знает наверняка) на небольших объектах вы не увидите никакой разницы. Однако есть способ сделать Serializable быстрее, чем Parcelable, для получения дополнительной информации см. Ответ Фарханы в этой теме: stackoverflow.com/questions/3323074/ - person A. Shevchuk; 01.04.2020

Реализуйте Serializable в объекте:

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

or

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

Затем вы можете передать объект с помощью Intent:

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

Наконец, в Activity2 вы получаете объект с:

val object = intent.extras.get("extra_object") as Object
person fireb86    schedule 16.08.2018

Нашел лучший способ сделать это:

В вашем Gradle:

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

android {
    androidExtensions {
        experimental = true
    }
}

В вашем классе данных:

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

В исходной активности:

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

В целевой деятельности:

student = intent.getParcelableExtra("student_id")
person Ankit Kumar    schedule 28.06.2018
comment
Это работает, но вы должны установить это в своем build.gradle: apply plugin: 'org.jetbrains.kotlin.android.extensions' android {androidExtensions {experimental = true}} - person Nicola Gallazzi; 01.11.2018

Parcelize больше не является экспериментальным, начиная с Kotlin 1.3.60+!

Определите класс данных, добавив @Parcelize аннотацию и расширив Parcelable:

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

Чтобы добавить к намерению:

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

In MyTargetActivity:

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

Если вы еще этого не сделали, включите расширения в build.gradle. Это также включает привязку данных и другие замечательные расширенные функции

apply plugin: 'kotlin-android-extensions'
person Gibolt    schedule 10.12.2019
comment
решение более чистое и простое. - person Guillermo Tobar; 13.01.2021
comment
kotlin-android-extensions устарела, вам следует использовать kotlin-parcelize подключаемый модуль для генератора реализаций Parcelable. - person Micer; 31.03.2021

Я нашел лучший способ передать объект из одного действия в другое с помощью Parcelable, он быстрее, чем Serialization Android: разница между Parcelable и Serializable?

сначала добавьте эти строки кода в build.gradle (app)

Я получил ответ от здесь

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

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

передача с намерением --- ›

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

Исходя из намерения --- ›

val model: Model = intent.getParcelableExtra(EXTRA)
person Ashik Azeez    schedule 07.11.2018
comment
Хорошие новости!! это больше не эксперимент - person a0x2; 01.04.2020
comment
это то, что все говорят, но никто не знает наверняка) на мелких объектах вы не увидите никакой разницы. Кроме того, приятно иметь этот котлинский сахар, но как насчет старой доброй java? Однако есть способ сделать Serializable быстрее, чем Parcelable, для получения дополнительной информации см. Ответ Фарханы в этой теме: stackoverflow.com/questions/3323074/ - person A. Shevchuk; 09.04.2020

Этот пост может быть полезен для того, чем вы собираетесь заниматься:

Есть ли удобный как создать классы данных Parcelable в Android с помощью Kotlin?

По сути, в котлине есть небольшие дополнения:

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

См. Сообщение для получения дополнительной информации.

person Javatar    schedule 13.04.2018

в котлине, чтобы начать активность и передать некоторые данные, вы можете попробовать что-то вроде этого:

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

Развлекайтесь

person Rafael Filipake    schedule 01.12.2017
comment
а как получить данные в другом классе? - person Vikash Parajuli; 30.03.2018

вы должны добавить тип внутри ‹› ... он работает для меня

val people = intent.getParcelableExtra ‹Люди› (EXTRA_PEOPLE) как Люди

В действии PeopleDetailActivity инициализируйте viewModel в onCreate

viewModel = [email protected] { postPeopleId(getPeopleFromIntent().id) }

А также инициализируем этот метод:

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

Напишите ниже код для передачи дополнительных сведений о намерениях:

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)
            }
        }
    }

Вызовите указанный выше метод в своем PeopleListViewHolder onClick

override fun onClick(v: View?) = PeopleDetailActivity.startActivityModel(context(), people)
person Gauresh Kambli    schedule 10.05.2021
comment
Это будет работать только в том случае, если настраиваемый объект доступен для парсинга. Было бы здорово, если бы вы предоставили образец кода. - person Marcel Hofgesang; 10.05.2021
comment
отредактировал ответ примером @MarcelHofgesang - person Gauresh Kambli; 29.05.2021

Ваш класс People должен реализовать Parcelable следующим образом:

class People(): Parcelable{
// stuff


}

Студия Android покажет вам ошибку. Просто переместите курсор на «Люди» и нажмите alt + enter. Теперь он должен показать возможность создания реализации Parcelable.

Этот сгенерированный код будет содержать что-то вроде

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

и где-то еще

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

Убедитесь, что все члены содержатся в этих методах, и при их изменении убедитесь, что чтение и запись происходят в одном и том же порядке.

person Adrian K    schedule 01.12.2017