【问题标题】:How to Pass custom object via intent in kotlin如何通过 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 类的实例,但出现错误。 我做错了什么?

【问题讨论】:

  • 您遇到的具体错误是什么?

标签: android android-intent kotlin kotlin-android-extensions


【解决方案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 答案:stackoverflow.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 bindingother great advanced features

    apply plugin: 'kotlin-android-extensions'
    

    【讨论】:

    【解决方案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 答案:stackoverflow.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()
      

      确保所有成员都包含在这些方法中,并且在修改它时,确保读取和写入以完全相同的顺序发生。

      【讨论】:

        猜你喜欢
        • 2020-07-29
        • 1970-01-01
        • 2011-06-22
        • 2015-05-30
        • 1970-01-01
        • 1970-01-01
        • 2018-01-05
        • 1970-01-01
        • 2022-06-11
        相关资源
        最近更新 更多