Release模式下App崩溃求助(未用XML布局仍报Button加载错误)
首先咱们拆解崩溃日志里的核心线索:
崩溃栈最终指向了
Dialog.show()->Dialog.onCreate()中的布局Inflate操作,而且是在你的SplashActivity.onCreate执行过程中触发的。这说明你没手动引用XML,但有某个逻辑(大概率是第三方SDK、初始化代码)在Splash启动时自动弹出了带XML布局的Dialog,而Release模式下的ProGuard混淆破坏了这个Dialog依赖的类。
你提到两天前Release还正常,那问题大概率来自最近两天的两类变更:新增了第三方依赖,或者修改了ProGuard配置。
具体排查与解决步骤
第一步:定位自动弹出的Dialog来源
检查SplashActivity.onCreate里的所有初始化代码,比如统计SDK、推送SDK、隐私合规弹窗、广告SDK等——这类第三方库经常会在初始化时自动弹出Dialog。你可以临时注释掉这些SDK的初始化代码,打包Release版本测试,如果不再崩溃,就能确定是哪个SDK的问题。第二步:修复ProGuard混淆规则
崩溃日志显示android.support.v7.widget.AppCompatButton.setBackgroundDrawable时出现空指针,这是ProGuard混淆了AppCompat相关类或其内部依赖导致的。你需要在ProGuard配置文件中添加以下规则:# 如果你用的是support库 -keep class android.support.v7.widget.** { *; } -keep class android.support.v7.app.** { *; } -keepattributes *Annotation* -keep public class * extends android.support.v7.app.AppCompatActivity -keep public class * extends android.support.v7.widget.AppCompatButton # 如果已经迁移到AndroidX,替换成下面的规则 #-keep class androidx.appcompat.widget.** { *; } #-keep class androidx.appcompat.app.** { *; } #-keepattributes *Annotation* #-keep public class * extends androidx.appcompat.app.AppCompatActivity #-keep public class * extends androidx.appcompat.widget.AppCompatButton如果确定是某个第三方SDK导致的,一定要去查它的官方文档,添加专属的混淆规则——很多SDK会要求保留自身类不被混淆。
第三步:确保资源ID不被混淆
检查ProGuard是否误混淆了资源ID,虽然你用代码创建View,但自动弹出的Dialog用到的XML资源可能受影响。确保配置里有这条规则:-keep class **.R$* { *; } -keepclassmembers class **.R$* { public static <fields>; }
快速验证方法
你可以临时在Release模式下关闭ProGuard(把build.gradle里的minifyEnabled设为false)打包测试,如果不崩溃,就100%确认是混淆规则的问题,再针对性调整即可。
内容的提问来源于stack exchange,提问作者Vivek

