开启R8 FullMode的Debug构建出现Transition非法参数异常求助
问题描述
当Debug构建同时开启android.enableR8.fullMode=true与minifyEnabled true时,多设备及模拟器均出现运行时错误:抛出java.lang.IllegalArgumentException,错误提示为:
Transition Slide@b15f5f5: dur(400) for fragment MyFragment is not a valid framework Transition or AndroidX Transition
但存在两种例外情况:
- 开启R8 FullMode的Release构建无此问题
- 关闭R8 FullMode后,Debug构建也无错误
相关代码及配置如下:
基类Fragment代码
import androidx.transition.TransitionInflater abstract class MyBaseFragment : Fragment() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) enterTransition = TransitionInflater.from(requireContext()).inflateTransition(R.transition.slide_right) } }
过渡动画XML(slide_right.xml)
<slide xmlns:android="http://schemas.android.com/apk/res/android" android:duration="@android:integer/config_mediumAnimTime" android:slideEdge="right" />
ProGuard规则片段(proguard-rules.pro)
-keep class **.R -keep class **.R$* { <fields>; } -keepclassmembers class **.R$* { public static <fields>; }
原因分析
R8 FullMode的代码优化逻辑在Debug和Release构建中存在差异:
- Debug构建开启FullMode时,会对AndroidX Transition类执行更严格的混淆与压缩,导致通过XML inflate生成的
Slide实例的类信息被篡改(比如类名被混淆)。 - Fragment的Transition校验逻辑会检查实例是否属于
android.transition.*(原生)或androidx.transition.*(AndroidX)包下的类,混淆后的类名无法通过该校验,因此抛出非法参数异常。 - Release构建中,可能因默认的ProGuard补充规则或优化策略,自动保留了AndroidX Transition类的完整类名;而关闭FullMode后,Debug构建的混淆强度降低,不会破坏Transition类的标识信息。
解决方案
需要添加额外的ProGuard规则,确保AndroidX Transition相关类的完整类名与结构不被混淆,具体规则如下:
# 保留AndroidX Transition所有类的完整结构,避免校验失败 -keep class androidx.transition.** { *; }
如果希望更精准,可以只保留用到的具体Transition类:
# 保留Slide过渡类及父类的完整信息 -keep class androidx.transition.Slide { *; } -keep class androidx.transition.Transition { *; }
现有ProGuard规则仅保留了资源R类的信息,无法覆盖Transition类的混淆防护,因此必须补充上述规则。
内容的提问来源于stack exchange,提问作者jt-gilkeson
相关产品推荐
相关产品推荐

