【Android】使用 Intent 传递对象的两种序列化方式
【Android】使用 Intent 传递对象的两种序列化方式
Android 中我们经常使用 Intent
在不同的组件之间传递数据,比如从一个 Activity
跳转到另一个 Activity
时传递参数。对于简单的数据(如 int
、String
等),使用 putExtra
非常方便。但如果我们要传递 自定义对象,就需要使用更复杂的方式。
方式一:Serializable
1. 定义对象类
import java.io.Serializable;public class User implements Serializable {private String name;private int age;public User(String name, int age) {this.name = name;this.age = age;}// Getter / Setter 省略
}
2. 发送方 Activity
Intent intent = new Intent(this, SecondActivity.class);
User user = new User("张三", 20);
intent.putExtra("user", user);
startActivity(intent);
3. 接收方 Activity
User user = (User) getIntent().getSerializableExtra("user");
这里调用了 getSerializableExtra() 方法来获取通过参数传递过来的序列化对象,接着再将它向下转型成 Person 对象,这样我们就成功实现了使用 Intent 来传递对象的功能了。
原理:通过 Java 的 ObjectOutputStream
将对象转为字节流,反序列化时用 ObjectInputStream
重建对象。
优点:
- 实现简单,只需实现
Serializable
接口。
缺点:
- 性能较差。
- 不适合频繁传输或大对象。
- 不能控制序列化过程,不安全。
方式二:Parcelable
Android 官方推荐使用 Parcelable
,因为它序列化/反序列化速度更快,内存使用更高效。
1. 定义对象类
import android.os.Parcel;
import android.os.Parcelable;public class User implements Parcelable {private String name;private int age;public User(String name, int age) {this.name = name;this.age = age;}protected User(Parcel in) {name = in.readString();age = in.readInt();}public static final Creator<User> CREATOR = new Creator<User>() {@Overridepublic User createFromParcel(Parcel in) {return new User(in);}@Overridepublic User[] newArray(int size) {return new User[size];}};@Overridepublic void writeToParcel(Parcel dest, int flags) {dest.writeString(name);dest.writeInt(age);}@Overridepublic int describeContents() {return 0;}// Getter / Setter 可选
}
Parcelable 的实现方式要复杂一些,首先让 User 类实现了 Parcelable 接口,这样就必须重写
describeContents()
和writeToParcel()
这两个方法,其中describeContents()
方法直接返回0就可以了,而writeToParcel()
方法中我们需要调用 Parcel 的writeXxx()
方法,将 Person 类中的字段一一写出。注意,字符串型数据就调用writestring()
方法,整型数据就调用writeInt()
方法,以此类推。关键注意事项:
在
createFromParcel()
方法中,字段读取顺序(readString()
、readInt()
)必须严格匹配writeToParcel()
方法中的字段写入顺序。
newArray()
方法只需简单创建对应大小的数组。
2. 发送方 Activity
Intent intent = new Intent(this, SecondActivity.class);
User user = new User("李四", 25);
intent.putExtra("user", user);
startActivity(intent);
3. 接收方 Activity
User user = getIntent().getParcelableExtra("user");
原理:通过 Parcel
内存容器直接操作二进制数据,避免反射开销。
优点:
- 性能优于
Serializable
,可自定义序列化过程。
缺点:
- 编写代码繁琐,对于嵌套对象或集合,需要额外实现嵌套类的
Parcelable
两种方式对比
Serializable | Parcelable | |
---|---|---|
实现复杂度 | 简单(只需 implements) | 较高(手动写入字段) |
序列化速度 | 慢 | 快(无反射) |
GC/内存开销 | 大(使用反射) | 小(结构紧凑) |
是否可控 | 不可控 | 精确控制 |
嵌套支持 | 自动递归序列化 | 手动嵌套写入/读取 |
集合支持 | 支持所有实现 Serializable 的集合 | 需使用专门 API,如 writeTypedList |
虽然 Serializable
使用简单,但在 Android 中,Parcelable
是更推荐的选择,尤其是在性能敏感或大对象频繁传输的场景。对于有嵌套对象或集合的类:
Serializable
可以省心地一键传输;Parcelable
则更灵活、更高效,但需要写更多代码。