AGP 8升级后getParcelable()因ifTable为空崩溃求助
崩溃原因及修复方案
崩溃原因
AGP 8默认启用R8 Full Mode,该模式下代码优化逻辑更激进,会移除未被显式引用的类或类元数据。LinearLayoutManager的onSaveInstanceState()返回的SavedState内部类(属于RecyclerView体系)被R8判定为无直接引用,导致其类信息被剥离。在恢复状态读取Parcelable时,系统尝试通过类信息进行类型校验,触发Class.ifTable空指针异常。
修复方案
方案1:保留RecyclerView相关SavedState类不被混淆
在项目的proguard-rules.pro文件中添加以下规则,强制保留布局管理器的SavedState类:
# 保留LinearLayoutManager的SavedState类 -keep class androidx.recyclerview.widget.LinearLayoutManager$SavedState { *; } # 可选:保留RecyclerView基础SavedState类,覆盖其他布局管理器场景 -keep class androidx.recyclerview.widget.RecyclerView$SavedState { *; }
这是最优方案,既保留R8 Full Mode的优化收益,又避免核心类被误删。
方案2:临时禁用R8 Full Mode(不推荐长期使用)
若需快速验证问题,可在gradle.properties中添加配置关闭Full Mode:
android.enableR8.fullMode=false
该方案会降低代码优化程度,仅作为临时排查手段,不建议长期保留。
方案3:优化Parcelable读取的类加载逻辑
检查并修复getParcelableCompat扩展函数,确保读取Parcelable时传入正确的类加载器,避免类加载异常:
import android.os.Build import android.os.Bundle import android.os.Parcelable inline fun <reified T : Parcelable> Bundle.getParcelableCompat(key: String, classLoader: ClassLoader): T? { return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) { getParcelable(key, T::class.java, classLoader) } else { @Suppress("DEPRECATION") getParcelable(key, classLoader) as T? } }
调用时传入当前上下文的类加载器:
oldRecyclerLayoutState = savedInstanceState.getParcelableCompat( SIS_RECYCLER_LAYOUT_STATE, requireContext().classLoader )
内容的提问来源于stack exchange,提问作者idunnololz
相关产品推荐
相关产品推荐

