You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

R8开启minifyEnabled时发布构建报ExceptionInInitializerError求助

问题描述

构建Release版本时触发ExceptionInInitializerError错误,Debug版本或添加-dontobfuscate标记后问题消失。错误堆栈如下:

java.lang.ExceptionInInitializerError
    at androidx.fragment.app.FragmentHostCallback.<init>(SourceFile:4)
    at androidx.fragment.app.FragmentHostCallback.<init>(SourceFile:2)
    at androidx.fragment.app.FragmentActivity$HostCallbacks.<init>(SourceFile:2)
    at androidx.fragment.app.FragmentActivity.<init>(SourceFile:2)
    at androidx.appcompat.app.AppCompatActivity.<init>(SourceFile:1)
    at main.MainActivity.<init>(SourceFile:1)
 Caused by: java.lang.RuntimeException: Shaking error: Missing method in androidx.fragment.app.FragmentManager: void <clinit>()
    at androidx.fragment.app.FragmentManager.<clinit>(Unknown Source:9)
    at androidx.fragment.app.FragmentHostCallback.<init>(SourceFile:4) 
    at androidx.fragment.app.FragmentHostCallback.<init>(SourceFile:2) 
    at androidx.fragment.app.FragmentActivity$HostCallbacks.<init>(SourceFile:2) 
    at androidx.fragment.app.FragmentActivity.<init>(SourceFile:2) 
    at androidx.appcompat.app.AppCompatActivity.<init>(SourceFile:1) 
    at main.MainActivity.<init>(SourceFile:1) 

当前配置

Proguard规则(proguard-rules.pro)

-optimizations !code/simplification/arithmetic,!field/*,!class/merging/*,!code/allocation/variable
-keepattributes *Annotation*
-keepattributes RuntimeVisibleAnnotations,AnnotationDefault
-keepattributes SourceFile,LineNumberTable

-renamesourcefileattribute SourceFile

-if @kotlinx.serialization.Serializable class **
-keepclassmembers class <1> {
   static <1>$Companion Companion;
}

-if @kotlinx.serialization.Serializable class ** {
   static **$* *;
}
-keepclassmembers class <2>$<3> {
   kotlinx.serialization.KSerializer serializer(...);
}

-if @kotlinx.serialization.Serializable class ** {
   public static ** INSTANCE;
}
-keepclassmembers class <1> {
   public static <1> INSTANCE;
   kotlinx.serialization.KSerializer serializer(...);
}

-keep @kotlinx.android.parcel.Parcelize public class *
-keep @kotlinx.parcelize.Parcelize public class *

 -keep class retrofit2.** { *; }
 -keepclasseswithmembers class * {
     @retrofit2.http.* <methods>;
 }

 -keep class okhttp3.** { *; }
 -keep interface okhttp3.** { *; }

Gradle构建配置

defaultConfig {
    minSdk 24
    targetSdk 32
}

buildTypes {
    release {
        minifyEnabled true
        proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
    }
}

核心疑问

如何确定哪些类/方法被Proguard剥离了?


解决方案与排查步骤

一、先修复当前的FragmentManager错误

从错误日志看,androidx.fragment.app.FragmentManager的静态初始化方法(<clinit>)被Proguard的优化规则移除了。这是因为你使用了proguard-android-optimize.txt,其中的优化规则会主动移除它认为“无用”的静态初始化逻辑,但FragmentManager的<clinit>是框架初始化必需的。

直接在Proguard规则里添加以下配置即可修复:

-keep class androidx.fragment.app.FragmentManager {
    static <clinit>();
}

或者更稳妥的方式,添加AndroidX Fragment库的官方Proguard规则:

-keep class androidx.fragment.app.** { *; }
-keep interface androidx.fragment.app.** { *; }

二、排查被剥离的类/方法的具体步骤

1. 查看Proguard自动生成的映射文件

构建Release版本后,在app/build/outputs/mapping/release/目录下会生成几个关键文件:

  • mapping.txt:记录原始类/方法名与混淆后名称的映射
  • usage.txt:最关键,明确标注了Proguard移除的所有类、方法、字段,被移除的内容会标记为[removed]
  • seeds.txt:记录被Proguard保留的类/方法/字段

直接打开usage.txt,搜索目标类名(比如FragmentManager),就能看到它的哪些成员被标记为移除。

2. 启用Proguard详细日志

在proguard-rules.pro开头添加以下规则,生成更详细的移除记录:

-verbose
-printusage build/outputs/mapping/release/custom_usage.txt

构建后打开custom_usage.txt,可以看到更细致的代码移除逻辑,方便精准定位问题。

3. 反编译APK验证

用APK反编译工具(比如jadx)打开Release版本的APK,查看目标类的代码结构,确认是否存在被怀疑移除的方法或字段。如果不存在,说明确实被Proguard移除了。

三、额外建议

  • 对于AndroidX库,尽量不要手动编写Proguard规则,大部分主流库会在aar包中自带proguard.txt,Gradle会自动导入这些规则
  • proguard-android-optimize.txt的优化强度比默认的proguard-android.txt更高,容易误删框架必需的代码,建议先测试默认规则是否能正常工作

内容的提问来源于stack exchange,提问作者arshcaptano

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.26 05:36:22