大家都知道想要在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")
@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.put
ParcelableArrayListExtra("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