大家都知道想要在Activity之间传递对象数据时可以通过实现Parcelable,在java代码中,我们一般用Android Studio插件(Android Parcelable code generator)来生成Parcelable需要的代码,但是在kotlin代码中不需要使用第三方插件,Android Studio自带编辑器就可以自动生成kotlin代码的Parcelable实现,之前的插件也在kotlin里无法使用,在windows上,我们定位到类名,按ALT+Enter组合键就可以出现一个菜单如下:
在这里插入图片描述
选择第一个就会自动帮我们生成Parcelable需要的代码如下图所示:

class DemoBean() :Parcelable{
    var name: String? = null
    var images: ArrayList<String>? = null
    constructor(parcel: Parcel) : this() {
        name = parcel.readString()
    override fun writeToParcel(parcel: Parcel, flags: Int) {
        parcel.writeString(name)
    override fun describeContents(): Int {
        return 0
    companion object CREATOR : Parcelable.Creator<DemoBean> {
        override fun createFromParcel(parcel: Parcel): DemoBean {
            return DemoBean(parcel)
        override fun newArray(size: Int): Array<DemoBean?> {
            return arrayOfNulls(size)

回到上面标题遇到的问题:

kotlin 实现了Parcelable但是Activity之间传递时ArrayList的值为什么还是为null?

从上面生成的Parcelable代码可以看到,它并没有为我们的images这个变量生成Parcelable代码实现,这就是为什么在跳转Activity后这个对象的ArrayList对应的变量值都为null的原因。

那么Android Studio为什么不帮我们生成ArrayList的Parcelable代码呢?是不是在kotlin里面ArrayList不能被Parcelable?

于是带着问题,又试了将images类型分别改为:List、MutableList,结果发现只有当定义成List类型的时候,才会自动生成images变量的Parcelable代码,如下:

class DemoBean() : Parcelable { var name: String? = null var images: List<String>? = null constructor(parcel: Parcel) : this() { name = parcel.readString() images = parcel.createStringArrayList()//看这里!!!! override fun writeToParcel(parcel: Parcel, flags: Int) { parcel.writeString(name) parcel.writeStringList(images)//看这里!!!! override fun describeContents(): Int { return 0 companion object CREATOR : Parcelable.Creator<DemoBean> { override fun createFromParcel(parcel: Parcel): DemoBean { return DemoBean(parcel) override fun newArray(size: Int): Array<DemoBean?> { return arrayOfNulls(size)

虽然说在kotlin里,这里定义成List类型也是可以的,因为ArrayList是继承自MutableList,而MutableList是继承自List,但是List里却没有常用的clear、addAll等方法,在使用到这个List的时候需要强制类型转换,不是很方便。

如果定义成ArrayList不会自动生成Parcelable代码,那手动加上行不行呢?于是带着疑问将images类型改为最开始的ArrayList,上面images变量生成的Parcelable代码保持不变,完整代码如下:

class DemoBean() : Parcelable { var name: String? = null var images: ArrayList<String>? = null//看这里!!!! constructor(parcel: Parcel) : this() { name = parcel.readString() images = parcel.createStringArrayList()//看这里!!!! override fun writeToParcel(parcel: Parcel, flags: Int) { parcel.writeString(name) parcel.writeStringList(images)//看这里!!!! override fun describeContents(): Int { return 0 companion object CREATOR : Parcelable.Creator<DemoBean> { override fun createFromParcel(parcel: Parcel): DemoBean { return DemoBean(parcel) override fun newArray(size: Int): Array<DemoBean?> { return arrayOfNulls(size)

试了一下发现ArrayList手动实现Parcelable完全没问题,跳转Activity后数据也能够恢复,所以总结下来那就只能是Android Studio的bug了。
如果手写Parcelable代码实现,则需要注意:
1、如果ArrayList里的对象是String类型的:

class DemoBean() : Parcelable {
    var images: ArrayList<String>? = null
    constructor(parcel: Parcel) : this() {
        images = parcel.createStringArrayList()
    override fun writeToParcel(parcel: Parcel, flags: Int) {
        parcel.writeStringList(images)

2、如果ArrayList里的对象是自定义,则该对象也要实现Parcelable:

class DemoBean() : Parcelable { var images: ArrayList<OtherDataBean>? = null constructor(parcel: Parcel) : this() { images = parcel.createTypedArrayList(OtherDataBean.CREATOR) override fun writeToParcel(parcel: Parcel, flags: Int) { parcel.writeTypedList(images)

3、还要注意各个变量的顺序问题,比如变量a和b,在writeToParcel方法里,a在b的前面write,而constructor里b却在a的前面恢复就不行,数据不能被正确恢复

当然还有更简便的方法,但目前只是实验性的功能,纯Kotlin开发还可以,混合开发可能会出现编译不通过找不到CREATOR问题

app的build.gradle里添加如下配置,开启kotlin实验性功能

android{ androidExtensions { experimental = true

然后在类名上面添加@Parcelize注解就可以了,如果出现Link提示则再在上面加上@SuppressLint(“ParcelCreator”)忽略警告

@SuppressLint("ParcelCreator")//这句视情况而定,我这个AS版本没有报错
@Parcelize
class DemoBean() : Parcelable {
    var images: ArrayList<OtherDataBean>? = null
 

我的Android Studio版本号是:3.4.2
kotlin版本号是:1.3.41

大家都知道想要在Activity之间传递对象数据时可以通过实现Parcelable,在java代码中,我们一般用Android Studio插件(Android Parcelable code generator)来生成Parcelable需要的代码,但是在kotlin代码中不需要使用第三方插件,Android Studio自带编辑器就可以自动生成kotlin代码的Parcelable实现,之前的...
开发中,序列化是常见操作,在java中,我们一般会用到Serializable或者Parcelable,优缺点就不赘述了,今天来看看kotlin中的序列化。 1.添加配置 app目录下的build.gradle文件 android { androidExtensions { experimental = true 2.添加注解并实现Parc...
这篇文章接着上一篇的AIDL实现跨进程通讯而来,说一下Android的序列化机制。 Parcelable接口相当于Android提供的一种自定义序列化机制,和Java本来就有的实现Serializable的序列化机制相比属于轻量级的。 在使用AIDL传递复杂对象,我们必须保证要传递的对象经过了序列化,我们要传递一个Person对象,先要AIDL来定义Person类,这很简单:
最初的写法如下,intent.putParcelableArrayListExtra("LIST", list);中的list报错,Wrong 2nd argument type. Found:'java.util.List',required: 'java.util.ArrayList' public void getSchoolMajorSuccess(List list) {
今天在项目中用到了Parcelable实现序列化,至于如何实现Parcelable,网上例子很多,在这里就不做介绍了。今天主要记录下在使用过程中遇到的两个坑。 1.在实现Parcelable过程中,我们要在class中创建一个Parcelable.Creator 的实例,需要注意的是,改实例的名字 必须是“CREATOR”,不然程序会报 Parcelable protocol requires
记录使用Parcelable进行类序列化的方式(还可以使用Serialize接口,本文不作介绍),以及如何使用intent传递自定义对象类的数组(ArrayList<Object>) 本文的前提是,使用Kotlin语言进行安卓开发 1.使用@Parcelize注解自动生成Parcelize实现 需要添加对Parcelable的支持,需要将以下的Gradle插件添加到应用的build.gradle文件中: plugins { id 'kotlin-parcelize' 当使用@P.
Android的不同Activity之间传输数据并不像传输参数那样简单。我们需要做的就是把需要传输的数据绑定到intent对象上。如果我们需要传输的对象是一些简单的Object,比如String类型或者Integer类型,那事情就好做了: String strinParam = "String Parameter"; Integer intParam = 5; Intent i = n
2.定义在kotlin中的对象所包含的字段没有进行判空处理; 3.parcelable传递多属性对象,传失效问题(可能是parcelable的一个坑); 那怎么解决呢: The exception was not handled due to missing onError handler in the subscribe() method call 10787 DSL element 'useProguard' is obsolete and will be removed soon. Use 'android.enableR8' in gradle.pro