如何通过 kotlin 中的意图传递自定义对象
Posted
技术标签:
【中文标题】如何通过 kotlin 中的意图传递自定义对象【英文标题】:How to Pass custom object via intent in kotlin 【发布时间】:2018-05-15 13:09:13 【问题描述】: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
我尝试使用上面的代码使用 kotlin 通过意图传递 People
类的实例,但出现错误。
我做错了什么?
【问题讨论】:
您遇到的具体错误是什么? 【参考方案1】:首先,确保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
【讨论】:
其他activity中如何获取序列化类? @VikashParajuli 在本示例的上下文中,您需要调用val people = getIntent().getExtras().getSerializableExtra(EXTRA_PEOPLE) as? People
速度较慢,您需要使用 Parcelable 以获得更好的性能
@a2en 这是每个人都在说的话,但没有人确切知道)在小物体上你不会看到任何区别。但是,有一种方法可以使 Serializable 比 Parcelable 更快,有关更多信息,请参阅此线程中的 Farhana 答案:***.com/questions/3323074/…【参考方案2】:
在对象中实现Serializable:
data class Object (
var param1: Int? = null,
var param2: String? = null
) : Serializable
或
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
【讨论】:
【参考方案3】:找到了更好的方法:
在你的毕业典礼中:
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")
【讨论】:
这可行,但您必须在 build.gradle 中设置:应用插件:'org.jetbrains.kotlin.android.extensions' android androidExtensions experimental = true 【参考方案4】:
从 Kotlin 开始,Parcelize
不再是实验性的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)
在MyTargetActivity
:
val people: People = intent.getParcelableExtra("people_data")
如果您尚未启用扩展程序,请在应用程序的 build.gradle
中启用。这也启用了data binding 和other great advanced features
apply plugin: 'kotlin-android-extensions'
【讨论】:
解决方案更简洁。kotlin-android-extensions
现已弃用,您应该为Parcelable implementation generator 使用kotlin-parcelize
插件。【参考方案5】:
我找到了一种使用 Parcelable 将对象从一个活动传递到另一个活动的更好方法,它比序列化更快 Android: Difference between Parcelable and Serializable?
首先,在 build.gradle(app) 中添加这几行代码
apply plugin: 'kotlin-android-extensions' in app.grable
@Parcelize
class Model(val title: String, val amount: Int) : Parcelable
Intent 传递--->
val intent = Intent(this, DetailActivity::class.java)
intent.putExtra(DetailActivity.EXTRA, model)
startActivity(intent)
从意图中获取 --->
val model: Model = intent.getParcelableExtra(EXTRA)
【讨论】:
好消息!!它不再是实验性的 这是每个人都在说的话,但没有人确切知道)在小物体上你不会看到任何区别。另外,很高兴有这个 Kotlin 糖,但是好的旧 java 呢?但是,有一种方法可以使 Serializable 比 Parcelable 更快,有关更多信息,请参阅此线程中的 Farhana 答案:***.com/questions/3323074/…【参考方案6】:这篇文章可能对您打算做的事情有用:
Is there a convenient way to create Parcelable data classes in Android with Kotlin?
基本上,kotlin 提供了一些额外的功能:
@Parcelize
class User(val firstName: String, val lastName: String) : Parcelable
查看帖子了解更多信息。
【讨论】:
【参考方案7】:在 kotlin 中启动活动并传递一些数据,您可以尝试如下操作:
startActivity(intentFor<NameOfActivity>(STRING to data))
玩得开心
【讨论】:
另外一个类如何接收数据?【参考方案8】:你必须在里面添加类型 ...它对我有用
val people = intent.getParcelableExtraPeople>(EXTRA_PEOPLE) as People
在您的 PeopleDetailActivity 活动中,在 onCreate 中初始化 viewModel
viewModel = this@PeopleDetailActivity.viewModel.apply 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)
【讨论】:
如果自定义对象是可解析的,这将起作用。如果您提供一些示例代码会很棒。 用一个例子编辑了答案@MarcelHofgesang【参考方案9】:你的 People 类需要像这样实现 Parcelable:
class People(): Parcelable
// stuff
android studio 会显示一个错误。只需将光标移动到“人物”,然后按 alt+enter。它现在应该显示生成 Parcelable 实现的选项。
此生成的代码将包含类似
的内容parcel.writeString(member1)
parcel.writeInt(member2)
还有别的地方
member1=parcel.readString()
member2=parcel.readInt()
确保所有成员都包含在这些方法中,并且在修改它时,确保读取和写入以完全相同的顺序发生。
【讨论】:
以上是关于如何通过 kotlin 中的意图传递自定义对象的主要内容,如果未能解决你的问题,请参考以下文章
当我使用 Serializable 出错时,如何使用意图传递自定义对象列表