Android Studio打包Release APK启动崩溃问题求助
java.lang.AssertionError: impossible 排查方案 先给你梳理下这个问题的核心:从崩溃堆栈来看,问题出在Facebook SDK的SmartLoginOption枚举类初始化时,Enum的缓存机制抛出了断言错误,这几乎都是ProGuard混淆破坏了枚举类的关键结构导致的——毕竟你之前的Release包正常,改了小改动后才出现,大概率是混淆规则没跟上或者误改了配置。
先贴出你遇到的崩溃日志方便参考:
Fatal Exception: java.lang.AssertionError: impossible at java.lang.Enum$1.create(Enum.java:45) at java.lang.Enum$1.create(Enum.java:35) at libcore.util.BasicLruCache.get(BasicLruCache.java:54) at java.lang.Enum.getSharedConstants(Enum.java:211) at java.util.EnumSet.noneOf(EnumSet.java:48) at java.util.EnumSet.allOf(EnumSet.java:66) at com.facebook.internal.SmartLoginOption.<clinit>(SmartLoginOption.java:29) at com.facebook.internal.FetchedAppSettingsManager.parseAppSettingsFromJSON(FetchedAppSettingsManager.java:225) at com.facebook.internal.FetchedAppSettingsManager.access$000(FetchedAppSettingsManager.java:53) at com.facebook.internal.FetchedAppSettingsManager$1.run(FetchedAppSettingsManager.java:143) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1113) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:588) at java.lang.Thread.run(Thread.java:818)
你已经尝试了清理缓存、重装AS这些通用操作,那接下来针对这个问题的针对性排查步骤:
1. 优先修复ProGuard混淆规则
枚举类的初始化依赖values()和valueOf()方法,ProGuard的优化可能会把这些方法移除,或者混淆枚举类的字段,导致EnumSet.allOf无法正常获取枚举实例。你需要在proguard-rules.pro里添加以下规则:
通用枚举保护规则(必须加)
-keepclassmembers enum * { public static **[] values(); public static ** valueOf(java.lang.String); }
Facebook SDK专属保护规则
针对堆栈里的Facebook类,直接保留整个枚举类不被混淆:
-keep class com.facebook.internal.SmartLoginOption { *; } -keep enum com.facebook.internal.SmartLoginOption { *; }
如果怕遗漏其他Facebook SDK的枚举类,可以直接保留整个Facebook包的相关结构:
-keep class com.facebook.** { *; } -keep enum com.facebook.** { *; } -keepattributes Signature
2. 检查你的小改动是否影响了依赖或配置
你提到只做了一处小改动,仔细回忆下:
- 是否升级了Facebook SDK的版本?新版本可能需要更新混淆规则
- 是否修改了build.gradle里的混淆相关配置?比如误删了某些规则
- 是否新增了和Facebook登录/分享相关的代码?导致之前没触发的枚举初始化现在被触发了
3. 验证混淆是否是问题根源
临时把release构建类型的minifyEnabled改成false,打包一个Release版本测试:
release { minifyEnabled false proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' }
如果这个包能正常启动,那就100%确认是混淆的问题,回到步骤1调整规则即可;如果还是崩溃,那就要排查代码改动本身或者依赖冲突了。
4. 检查ProGuard文件是否真的生效
你之前在proguard-android.txt加随机语句能运行,可能说明这个文件没被正确加载?试试把自定义规则都放到proguard-rules.pro里,或者直接指定绝对路径测试,另外可以查看构建日志里的ProGuard输出,确认规则是否被应用。
内容的提问来源于stack exchange,提问作者Swapnil

