项目开发过程中一切正常,但是打release包后却发生异常崩溃,捕获到错误日志如下:

the xxxActivity is null: android.view.InflateException: Binary XML file line #1 in [package]:layout/activity_xxx:Binary XML file line #1 in [package]:layout/activity_xxx: Error inflating class x

关键词:Binary XML file line #1Error inflating class x

经过排查发现是因为release包开启资源缩减导致布局文件被移除了,花了点时间看了下关于资源缩减相关的内容。

资源缩减

资源缩减需要与代码缩减配合使用才能发挥缩减资源的作用。因为只有在代码缩减器移除所有不使用的代码后,资源缩减器才能真正的确定资源有没有被应用使用,从而确定出哪些是要保留的资源,哪些是要缩减的资源,当您添加包含资源的代码库时尤其需要如此。

注:资源缩减不会移除value文件下的资源(比如:strings, dimensions, styles, and colors)

开启资源缩减

在项目build.gradle文件中添加shrinkResources trueminifyEnabled true配置开启资源压缩。

android {buildTypes {release {shrinkResources trueminifyEnabled trueproguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'}}
}

自定义要保留的资源

在项目中的res/raw目录下添加keep.xml文件,来声明资源缩减的规则。

<?xml version="1.0" encoding="utf-8"?>
<resources xmlns:tools="http://schemas.android.com/tools"tools:shrinkMode="safe"tools:keep="@layout/activity_*,@drawable/shape_*,@anim/anim_*"tools:discard="@drawable/xxxx_*_xxxx"/>
keep 和 discard

keep 属性中指定每个要保留的资源。discard 属性中指定每个要舍弃的资源。像上面例子中的值一样,这两个属性都接受以逗号分隔的资源名称列表,还可以将星号字符用作通配符。

shrinkMode

shrinkMode 属性有两个枚举值, strict表示严格引用检查,safe表示安全引用检查(防患于未然)。这个属性决定了资源缩减器判定资源是否被使用时的检查严格程度,默认值为safe

比如,我们的代码中根据动态生成的字符串查询资源名称,如下:

String name = String.format("img_%1d", angle + 1);
res = getResources().getIdentifier(name, "drawable", getPackageName());

shrinkModesafe时,我们使用getIdentifier()获取的资源标记为已使用,那么资源就会被保留下来不会被缩减。而shrinkModestrict时,上述方式使用的资源则会判定为未使用,就会被缩减。

⭐⭐⭐所以如果您确实启用了严格缩减模式,并且您的代码也通过动态生成的字符串引用资源(如上所示),那么您必须使用 tools:keep 属性中手动保留这些资源。

我们项目中资源被移除就是因为一个三方库keep.xml文件中设置了shrinkModestrict,而动态生成的字符串引用资源没有配置在keep中,导致资源被缩减了。

缩减后的资源

缩减后的资源文件并不会删除,而是内容被移除了,xml文件里面只剩个<x />了。

这也正是我们项目里面为什么会报错Binary XML file line #1Error inflating class x的原因。

检查被缩减的资源

如何判断是否有必要资源被缩减呢?

build\outputs\mapping目录中找到对应的resources.txt 文件,里面记录了资源文件处理情况。

被缩减的资源都会记录在文件底部,Skipped unused被标记,如下图:

移除未使用的资源

Gradle 资源缩减器只会移除未由应用代码引用的资源,这意味着,它不会移除用于不同设备配置的备用资源。如有必要,您可以使用 Android Gradle 插件的 resConfigs 属性移除应用不需要的备用资源文件。

设置只保留英语和法语的语言资源:

android {defaultConfig {...resConfigs "en", "fr"}
}

合并重复资源

默认情况下,Gradle 还会合并同名的资源,如可能位于不同资源文件夹中的同名可绘制对象。这一行为不受 shrinkResources 属性控制,也无法停用,因为当多个资源与代码查询的名称匹配时,有必要利用这一行为避免错误。

只有在两个或更多个文件具有完全相同的资源名称、类型和限定符时,才会进行资源合并。

Gradle 会在以下位置查找重复资源:

  • 与主源代码集关联的主资源,一般位于 src/main/res/ 中。
  • 变体叠加,来自构建类型和构建变种。
  • 库项目依赖项。

Gradle 会按以下级联优先顺序合并重复资源:

依赖项 → 主资源 → 构建变种 → 构建类型

Android Release包异常之Error inflating class x相关推荐

  1. Android中使用fragment出现异常,Error inflating class fragment

    异常: 在xml文件中静态引用fragment,出现了以下异常: Caused by: android.view.InflateException: Binary XML file line #9 i ...

  2. Android Studio 使用Spinner组件 Error inflating class Spinner问题解决

    使用spinner组件做到下拉菜单选择的功能,在打开Spinner所在的界面时却出现了Error inflating class Spinner的报错并闪退.具体的报错内容如下: E/AndroidR ...

  3. Android布局设计时报错Error inflating class Button

    写在前面的话 在进行android布局设计时,给button按钮添加背景图片,运行时直接停止运行了,赶紧去看运行时log,发现报错 Error inflating class Button,难道是我图 ...

  4. Android 运行时异常 Binary XML file line # : Error inflating class

    今天在做一个二维码扫描的项目的时候出现了一个错误: android.view.InflateException: Binary XML file line #12: Error inflating c ...

  5. Android 异常 “Binary XML file line # : Error inflating class”

    自己的项目在Pad上一直运行正常,可是当运行在手机上时在一个Inflater.inflater()解析布局时出现了运行时异常" Binary XML file line # : Error ...

  6. android error inflating 自定义控件,解决Android 异常 “Binary XML file line # : Error inflating class”...

    自己的项目在5.0及以上的手机山一直运行正常,可是当运行在低版本手机上时在一个Inflater.inflater()解析布局时出现了运行时异常" Binary XML file line # ...

  7. Android编程:解决异常“android.view.InflateException: Binary XML file line # : Error inflating class”

    我一般都是在1和4 遇到,记录一下. 今天写程序发现一个问题,就是XML中报出Android.view.InflateException异常,可能的原因有: 1.XML中使用到得组件名称是否书写正确( ...

  8. android Binary XML file line #1: Binary XML file line #1: Error inflating class x 问题详解

    话不多少,上错误堆栈: Process: com.mci.smagazine, PID: 25065java.lang.RuntimeException: Unable to start activi ...

  9. Error inflating class android.support.v17.leanback.widget.PlaybackControlsRowView

    遇到一个坑货问题: 使用 leanback V17 的包,添加控件到页面上,结果出现了crash, crash信息如下: android.view.InflateException: Binary X ...

最新文章

  1. php获取数据库不同,php – 从master数据库获取数据库凭据,然后连接到不同的数据库...
  2. Emgucv粗略抠取车牌
  3. 【反爬】某网站雪碧图反爬
  4. 在MySQL数据库建立多对多的数据表关系
  5. [Silverlight入门系列]用TransformToVisual和Transform取得元素绝对位置(Location)
  6. prinect pdf toolbox 2021中文版
  7. c语言如何输出数组最大值和最小值,C语言输出数组中最大和次大的数
  8. iAntares OSx86 10.6.5 v3.2 繁简英整合版 安装过程【安装过程问题说明】
  9. 做正确的事永远都不迟
  10. 人工智能之不确定推理方法
  11. 什么是实体-联系图(ER图)
  12. 调整bandizip压缩参数获得最大压缩效果
  13. Win11 22H2四个你不知道的隐藏功能
  14. 强烈安利:小顽简报,一款高效实用的PPT新插件
  15. Java Web项目开发流程
  16. kettle学习教程
  17. iPhone微信浏览器某些元素点击无效
  18. 进击的Android注入术
  19. 硬盘插到群晖上使用之后再插回Windows就不识别了,记录一次解决过程
  20. C语言入门 - 什么是递归?

热门文章

  1. 双11系列 | 智能应用全面升级 重构“人货场”
  2. 不需要pygame的摸鱼游戏大集合
  3. 专访爱数智慧CEO张晴晴:数据服务刚性需求,获客难度不大
  4. 统计二叉树中叶子结点数数据结构C语言,统计二叉树中叶子结点个数的问题,
  5. eclipse全屏豆沙绿设置步骤
  6. 苹果系统VMware tool安装,实现虚拟系统全屏化
  7. C++与Java共同点
  8. python 自定义进制转换_[python]从零开始学python——颜色的16进制于RGB之间的转换...
  9. Kotlin by 关键字
  10. 永久禁止windows10更新方法