Android 33 getSerializableExtra/getParcelableExtra替代用法
Android 13(API 33)Intent 废弃取数方法适配方案
从API 33开始,Intent 类中无类型参数的 getSerializableExtra(name)、getParcelableExtra(name) 方法被正式标记为废弃,官方新增的重载方法通过传入Class参数实现编译期类型校验,避免手动强转导致的类型转换异常,各场景具体写法如下:
基础场景:获取普通序列化/Parcelable对象
旧写法(触发废弃警告)
// Kotlin val userData = intent.getSerializableExtra("user_key") as User val bookData = intent.getParcelableExtra("book_key") as Book
// Java User userData = (User) getIntent().getSerializableExtra("user_key"); Book bookData = (Book) getIntent().getParcelableExtra("book_key");
新写法(API 33 原生支持)
// Kotlin val userData = intent.getSerializableExtra("user_key", User::class.java) val bookData = intent.getParcelableExtra("book_key", Book::class.java)
// Java User userData = getIntent().getSerializableExtra("user_key", User.class); Book bookData = getIntent().getParcelableExtra("book_key", Book.class);
复杂场景:获取List/ArrayList类型数据
由于Java泛型存在运行时擦除机制,无法直接获取List<T>类型的Class对象,按存入数据的类型分两种处理方式:
- 如果存入时使用的是
putParcelableArrayListExtra传递Parcelable元素的列表,直接调用对应ArrayList重载方法即可,无需额外强转:// 存入逻辑:intent.putParcelableArrayListExtra("user_list", arrayListOf(user1, user2)) val userList = intent.getParcelableArrayListExtra("user_list", User::class.java) - 如果存入的是Serializable类型的列表(比如String列表、自定义序列化对象列表),传入ArrayList的Class后做对应泛型强转即可:
// 存入逻辑:intent.putExtra("tag_list", arrayListOf("android", "adaptation")) val tagList = intent.getSerializableExtra("tag_list", ArrayList::class.java) as? ArrayList<String>
注意:不建议向Intent中传入非ArrayList实现的List子类,存入前手动转成ArrayList可以避免绝大多数类型转换异常;没有实现Serializable/Parcelable接口的普通Object无论在哪个API版本都不允许放入Intent,会直接触发运行时崩溃。
低版本兼容方案(minSdk < 33)
如果项目最低支持版本低于33,可以通过扩展函数封装版本差异,统一调用入口,避免重复写版本判断逻辑:
import android.content.Intent import android.os.Build import android.os.Parcelable import java.io.Serializable @Suppress("DEPRECATION") inline fun <reified T : Parcelable> Intent.getParcelableCompat(key: String): T? { return when { Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU -> getParcelableExtra(key, T::class.java) else -> getParcelableExtra(key) } } @Suppress("DEPRECATION") inline fun <reified T : Serializable> Intent.getSerializableCompat(key: String): T? { return when { Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU -> getSerializableExtra(key, T::class.java) else -> getSerializableExtra(key) as? T } } @Suppress("DEPRECATION") inline fun <reified T : Parcelable> Intent.getParcelableListCompat(key: String): ArrayList<T>? { return when { Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU -> getParcelableArrayListExtra(key, T::class.java) else -> getParcelableArrayListExtra(key) } }
封装后直接调用对应兼容方法即可,无需关心版本差异:
val user = intent.getParcelableCompat<User>("user_key") val userList = intent.getParcelableListCompat<User>("user_list")
内容的提问来源于stack exchange,提问作者Rumit Patel
相关产品推荐
相关产品推荐

