Serializable/Parcelable是“让对象可以被传递”的方式;
Bundle是“装数据的盒子”;
CharSequence是“一类文本数据的接口”。
1. Serializable:Java 自带的序列化方式
1.1 它是什么?
Serializable 是 Java 提供的接口,用来把对象转换成可以存储或传输的形式。
比如你有一个对象:
data class User(
val name: String,
val age: Int
)
正常情况下,这个对象不能直接放进 Intent 里传给另一个 Activity。
如果你让它实现 Serializable:
import java.io.Serializable
data class User(
val name: String,
val age: Int
) : Serializable
它就可以被传递了。
1.2 常见用法:Activity 之间传对象
发送数据
val user = User("张三", 18)
val intent = Intent(this, DetailActivity::class.java)
intent.putExtra("user", user)
startActivity(intent)
接收数据
val user = intent.getSerializableExtra("user") as? User
Android 13 之后推荐这样写:
val user = intent.getSerializableExtra("user", User::class.java)
1.3 什么时候适合用 Serializable?
适合:
简单对象
数据量不大
不频繁传递
对性能要求不高
比如:
data class Book(
val id: Int,
val title: String
) : Serializable
1.4 Serializable 的特点
优点:
写起来简单
只要实现 Serializable 接口即可
缺点:
性能比 Parcelable 差
序列化过程使用反射,开销相对大
Android 中不如 Parcelable 高效
2. CharSequence:文本数据接口
2.1 它是什么?
CharSequence 不是专门用来序列化对象的,它是一个表示“字符序列”的接口。
常见的实现类有:
String
StringBuilder
SpannableString
Editable
所以:
val text: CharSequence = "你好"
是可以的,因为 String 实现了 CharSequence。
2.2 String 和 CharSequence 有什么区别?
String 是具体的字符串类型。
CharSequence 是更大的范围。
String 是 CharSequence 的一种
比如:
fun setText(text: CharSequence) {
textView.text = text
}
这样这个方法不仅能接收普通字符串:
setText("普通文本")
也能接收带样式的文本:
val spannable = SpannableString("红色文字")
setText(spannable)
2.3 常见用法:TextView 设置文本
Android 中很多文本相关 API 都使用 CharSequence:
textView.text = "Hello"
实际 TextView.setText() 接收的就是:
setText(text: CharSequence)
因为它不仅要支持普通文本,还要支持富文本。
2.4 常见用法:传递文本
Intent 中也可以传递 CharSequence:
val intent = Intent(this, DetailActivity::class.java)
intent.putExtra("title", "标题内容")
startActivity(intent)
接收:
val title = intent.getCharSequenceExtra("title")
不过如果只是普通字符串,大多数时候直接用 String 更常见:
val title = intent.getStringExtra("title")
2.5 CharSequence 适合什么场景?
适合:
文本内容
TextView 显示
带样式的文本
Editable 输入框内容
Spannable 富文本
例如带颜色的文本:
val text = SpannableString("重要提示")
text.setSpan(
ForegroundColorSpan(Color.RED),
0,
4,
Spanned.SPAN_EXCLUSIVE_EXCLUSIVE
)
textView.text = text
这里 SpannableString 就是 CharSequence 的一种。
3. Parcelable:Android 推荐的高效对象传递方式
3.1 它是什么?
Parcelable 是 Android 专门设计的一套序列化机制。
它的主要用途是:
在 Android 组件之间高效传递对象
比如:
Activity → Activity
Activity → Fragment
Service → Activity
3.2 和 Serializable 有什么区别?
简单对比:
| 对比项 | Serializable | Parcelable |
|---|---|---|
| 来源 | Java 标准 | Android 专用 |
| 使用难度 | 简单 | 稍复杂 |
| 性能 | 较低 | 较高 |
| 适合场景 | 简单对象、低频传递 | Android 组件间高频对象传递 |
| 是否推荐 | 可用 | Android 中更推荐 |
一句话:
Serializable写起来简单,Parcelable性能更好。
3.3 Kotlin 中使用 Parcelable
以前写 Parcelable 比较麻烦,但 Kotlin 可以用 @Parcelize 简化。
首先在 build.gradle 中启用插件:
plugins {
id("kotlin-parcelize")
}
然后写类:
import android.os.Parcelable
import kotlinx.parcelize.Parcelize
@Parcelize
data class User(
val name: String,
val age: Int
) : Parcelable
3.4 Activity 之间传 Parcelable
发送
val user = User("李四", 20)
val intent = Intent(this, DetailActivity::class.java)
intent.putExtra("user", user)
startActivity(intent)
接收
Android 13 之前:
val user = intent.getParcelableExtra<User>("user")
Android 13 之后推荐:
val user = intent.getParcelableExtra("user", User::class.java)
3.5 Fragment 传 Parcelable
创建 Fragment
val fragment = DetailFragment().apply {
arguments = Bundle().apply {
putParcelable("user", user)
}
}
Fragment 中接收
val user = arguments?.getParcelable<User>("user")
Android 13 之后:
val user = arguments?.getParcelable("user", User::class.java)
3.6 Parcelable 适合什么场景?
适合:
Android 组件之间传递对象
对象字段比较多
传递比较频繁
希望性能更好
例如:
@Parcelize
data class Product(
val id: Long,
val name: String,
val price: Double,
val coverUrl: String
) : Parcelable
4. Bundle:Android 的数据包/数据盒子
4.1 它是什么?
Bundle 可以理解为一个 键值对容器。
类似:
Map<String, Any>
它用来装各种数据:
String
Int
Boolean
Float
Parcelable
Serializable
StringArrayList
Bundle
4.2 Bundle 的典型用法
Activity 之间传数据
其实 Intent.putExtra() 底层就会把数据放进类似 Bundle 的结构里。
你可以直接用:
val intent = Intent(this, DetailActivity::class.java)
intent.putExtra("name", "王五")
intent.putExtra("age", 22)
startActivity(intent)
接收:
val name = intent.getStringExtra("name")
val age = intent.getIntExtra("age", 0)
也可以自己创建 Bundle:
val bundle = Bundle().apply {
putString("name", "王五")
putInt("age", 22)
}
val intent = Intent(this, DetailActivity::class.java)
intent.putExtras(bundle)
startActivity(intent)
接收:
val bundle = intent.extras
val name = bundle?.getString("name")
val age = bundle?.getInt("age")
4.3 Fragment 传参数
这是 Bundle 最常见的场景之一。
推荐写法
class DetailFragment : Fragment() {
companion object {
fun newInstance(userId: Long): DetailFragment {
return DetailFragment().apply {
arguments = Bundle().apply {
putLong("user_id", userId)
}
}
}
}
}
接收:
class DetailFragment : Fragment() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val userId = arguments?.getLong("user_id") ?: 0L
}
}
使用:
val fragment = DetailFragment.newInstance(1001L)
4.4 保存页面状态
Bundle 还经常用于保存 Activity 或 Fragment 的状态。
比如屏幕旋转时保存数据:
override fun onSaveInstanceState(outState: Bundle) {
super.onSaveInstanceState(outState)
outState.putString("input_text", editText.text.toString())
}
恢复:
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val inputText = savedInstanceState?.getString("input_text")
}
4.5 Bundle 可以装 Parcelable
val bundle = Bundle().apply {
putParcelable("user", user)
}
接收:
val user = bundle.getParcelable<User>("user")
4.6 Bundle 可以装 Serializable
val bundle = Bundle().apply {
putSerializable("user", user)
}
接收:
val user = bundle.getSerializable("user") as? User
5. 它们之间的关系
可以这样理解:
Bundle 是盒子
Serializable 和 Parcelable 是让对象可以放进盒子的方式
CharSequence 是一种常见的文本数据类型
比如:
val bundle = Bundle()
bundle.putString("title", "标题")
bundle.putInt("age", 18)
bundle.putParcelable("user", user)
bundle.putSerializable("book", book)
bundle.putCharSequence("content", spannableText)
这里:
Bundle 负责装数据
Parcelable 负责让 user 可以被装进去
Serializable 负责让 book 可以被装进去
CharSequence 负责表示 content 这种文本
6. 常见选择建议
6.1 传普通字符串
用 String:
intent.putExtra("title", "商品详情")
接收:
val title = intent.getStringExtra("title")
6.2 传普通数字、布尔值
直接用基本类型:
intent.putExtra("id", 1001L)
intent.putExtra("isVip", true)
接收:
val id = intent.getLongExtra("id", 0L)
val isVip = intent.getBooleanExtra("isVip", false)
6.3 传简单对象,不在意性能
可以用 Serializable:
data class User(
val name: String,
val age: Int
) : Serializable
intent.putExtra("user", user)
6.4 传 Android 组件间对象,推荐用 Parcelable
推荐:
@Parcelize
data class User(
val name: String,
val age: Int
) : Parcelable
intent.putExtra("user", user)
6.5 Fragment 传参
推荐用 Bundle:
val fragment = DetailFragment().apply {
arguments = Bundle().apply {
putLong("id", 1001L)
putString("title", "详情页")
}
}
6.6 保存临时状态
用 Bundle:
override fun onSaveInstanceState(outState: Bundle) {
outState.putString("keyword", searchEditText.text.toString())
}
7. 一个完整例子
假设要从 UserListActivity 跳转到 UserDetailActivity,传一个用户对象。
方式一:Parcelable 推荐
User 类
@Parcelize
data class User(
val id: Long,
val name: String,
val age: Int
) : Parcelable
发送
val user = User(1L, "张三", 18)
val intent = Intent(this, UserDetailActivity::class.java).apply {
putExtra("user", user)
}
startActivity(intent)
接收
val user = intent.getParcelableExtra<User>("user")
textView.text = user?.name
方式二:Serializable 简单但性能差一点
User 类
data class User(
val id: Long,
val name: String,
val age: Int
) : Serializable
发送
val intent = Intent(this, UserDetailActivity::class.java)
intent.putExtra("user", user)
startActivity(intent)
接收
val user = intent.getSerializableExtra("user") as? User
8. 最后总结
| 类型 | 作用 | 常见场景 |
|---|---|---|
Serializable |
Java 序列化对象 | 简单对象传递 |
Parcelable |
Android 高性能对象传递 | Activity/Fragment 传对象 |
Bundle |
键值对数据容器 | Intent 参数、Fragment 参数、状态保存 |
CharSequence |
文本数据接口 | TextView、富文本、Spannable |
最实用的记忆方式:
传字符串、数字:直接 putExtra
传对象:优先 Parcelable,简单场景可用 Serializable
Fragment 参数:用 Bundle
文本显示:CharSequence / String
富文本显示:SpannableString,它也是 CharSequence
如果只记一个原则:
Android 组件之间传复杂对象,优先用
Parcelable;
传参容器用Bundle;
普通文本用String,富文本用CharSequence。