返回

R8 运行时 AdMob 23.4.0 缺失类错误? 快速解决指南

Android

R8 运行时 AdMob 23.4.0 缺失类错误

升级 AdMob SDK 到 23.4.0 版本后,开发者在进行 Release 构建时,可能会遇到 “Missing classes detected while running R8.” 的错误。 这通常伴随着类似 android.media.LoudnessCodecController 相关类缺失的提示。 此错误会阻止应用构建,必须妥善解决。

问题分析

该问题源于 AdMob 23.4.0 版本中引入了对 Android 系统 android.media.LoudnessCodecController 类的依赖。 R8 代码混淆器(Android 构建过程中用于缩小和优化代码的工具),默认情况下会将应用中未直接引用的代码移除。由于该类并非应用直接使用,R8 会错误地认为其为未使用,进而导致构建时报错。

解决方案

存在多种方式来应对这一错误,以下列出一些实践中有效的方法。

方案一:使用 Keep 规则

R8 可以通过 keep 规则指示其保留特定的类或成员,即使它们没有直接引用。可以通过修改项目的 R8 配置来添加缺失类的 keep 规则。

  1. 定位 missing_rules.txt : 在构建失败的提示信息中,可以找到 R8 提示缺失规则生成的 missing_rules.txt 文件。 其路径类似 [My project folder]/build/outputs/mapping/release/missing_rules.txt

  2. 复制 Keep 规则 : 打开 missing_rules.txt 文件, 找到需要 keep 的类,它们通常看起来像:

    -keep class android.media.LoudnessCodecController {
        <fields>;
        <methods>;
    }
    -keep class android.media.LoudnessCodecController$OnLoudnessCodecUpdateListener {
       <fields>;
       <methods>;
    }
    
  3. 配置 Proguard 规则 : 在模块的 proguard-rules.pro 文件中, 或者在 build.gradle 文件配置 proguardFiles 参数指定的 R8 规则文件中(通常叫 proguard-rules.pro),添加上一步复制的 keep 规则:

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

将下面的 keep 规则添加到 proguard-rules.pro文件中:

-keep class android.media.LoudnessCodecController {
    <fields>;
    <methods>;
}
-keep class android.media.LoudnessCodecController$OnLoudnessCodecUpdateListener {
   <fields>;
   <methods>;
}
  1. 重新构建应用 :添加规则后,再次执行 Release 构建。

原理: 此方案直接指示 R8 保留 android.media.LoudnessCodecControllerLoudnessCodecController$OnLoudnessCodecUpdateListener 类及其所有成员,避免在构建时被移除。

方案二:依赖更全面的库

另一种解决方法是包含包含缺少的类的相关 Android 库,以隐式保留。虽然直接包含此类库对于所有项目未必理想,但是此方法值得理解,以作为参考方案:

  1. 添加相关依赖 : 如果分析显示此缺失类来源于 android.media 或者其他 Android 标准库,则尝试添加包含此类的库,通常Android系统SDK已经包含了这些,可以尝试用androidx对应的替代。示例代码如下,添加到应用模块的build.gradle.ktsdependencies下。

    dependencies {
         // Android 标准库的依赖,版本根据需要选择
        implementation("androidx.media:media:1.6.0")
         ...
    }
    

    (注:这里的androidx.media:media是一个示例,请替换为符合你需要的Android组件库)

  2. 同步 Gradle 项目 : 修改 build.gradle.kts 后,需要同步 Gradle 项目来使更改生效。

  3. 重新构建应用 : 同步完成后,再次执行 Release 构建。

原理: 添加了相关 Android 标准库的依赖后,这些库中包含的缺失类,就会被 R8 视为应用依赖的必要部分,避免在代码缩减过程中被删除。此方法通常比手动添加 keep 规则更加自动化,更不容易出现疏漏。

安全建议

  • 理解规则作用 : keep 规则的使用需要谨慎,不要盲目添加,特别是通配符规则。规则过度宽松可能会增大应用的 APK 体积,增加应用漏洞风险,反而会降低优化的效果。
  • 谨慎选择依赖 : 不必要的库依赖会增加应用大小和构建时间,引入额外的依赖必须经过仔细评估,确认引入的库的功能正是你所需要的。
  • 定期更新 : 始终保持 R8, Gradle 和相关库处于最新状态,这不仅可以修复已知的错误,也带来新功能,从而更好地解决问题。
  • R8 映射文件分析 :构建失败后,可以详细检查 R8 生成的 mapping.txt 文件,分析代码缩减的具体行为。有助于理解R8的优化策略,精准地找到并解决问题。

总结来说,处理 “Missing classes detected while running R8.” 问题时,首先理解问题的根本原因,即代码缩减误判,然后根据实际情况,采取合适的 keep 规则或者依赖添加方案。持续地分析与学习有助于高效地解决此类构建问题。