Android报错Didn‘t find class “android.view.x“问题解决原理剖析

目录
  • 前言
  • shrinkResources
    • Safe
    • Strict
    • android.view.x
    • 自定义保留
  • 总结

前言

今天同事提到了一个问题,我们的一款App在debug包时没有问题,但是在release包时就是crash,报错如下:

可以看到问题是Didn‘t find class “android.view.x“,但是实际上我们代码中并没有这个类,由于是release包的问题,所以第一时间想到的是混淆问题,检查了一番后发现与混淆无关,经过上网查询发现有人提到说将build.gradle中的shrinkResources设置为false即可解决,经过尝试发现确实解决了问题,但是为什么呢?

shrinkResources

要弄明白问题,首先就要知道shrinkResources是如何工作的。

当我们启用了资源压缩(Resource Shrinking),当打包是会去检查每个资源是否被引用,如果没有被引用,则会进行优化,但是它有两种模式Safe和Strict。

Safe

在这种模式下,除了直接引用,使用动态代码引用的资源(比如使用Resources.getIdentifier()引用资源)也会被保留,这样就不会造成太大的问题。

Strict

在严苛模式下,只有直接引用的资源被保留,其他资源就会被压缩。注意这里是压缩而不是删除,具体表现就是如果是图片,则保留该图片文件,但是内容则为空,如下:

可以看到处理过的图片都是67b大小,且没有内容,这样大大减少了空间。

而如果是xml文件,则内容同样为空,如下:

可以看到内容变成了,大小都是47b,也是极大的减少了空间。

android.view.x

这样我们就知道Didn‘t find class “android.view.x“问题所在了,一定是我们使用的布局被压缩了,根据crash日志找到NavigateActivity的onCreate方法,这里有如下代码:

mLayoutId = ResourceUtils.getLayoutId(this, "activity_main");
...
View rootView = View.inflate(this, mLayoutId, null);
...
setContentView(rootView);

这个activity_main正是通过Resources.getIdentifier()动态引用的,在release包中查看这个布局发现已经是空的了,所以就会报上面的错误。

所以当我们将shrinkResources设置为false后,因为不会执行资源压缩,所以问题解决。

自定义保留

但是在默认情况下资源压缩(Resource Shrinking)的模式是Safe,不应该出现这样的问题,那么说明我们没有从根本上解决问题,我们继续来看。

怎么可以改变资源压缩(Resource Shrinking)的模式,答案是配置自定义保留文件,在res/raw下新建一个keep.xml文件,在其中就可以设置自定义保留策略,一个示例代码如下:

<?xml version="1.0" encoding="utf-8"?>
<resources xmlns:tools="http://schemas.android.com/tools"
           tools:discard="@color/selector_tint_color"
           tools:keep="@layout/activity_test1,@layout/activity_test2"
           tools:shrinkMode="strict"/>

其中:

  • discard:表示对文件做严格检查,逗号分隔
  • keep:表示保留文件,逗号分隔
  • shrinkMode:则可以设置资源压缩(Resource Shrinking)的模式,包括strict和safe两种

所以我们知道通过keep.xml可以改变资源压缩(Resource Shrinking)的模式,但是我们并没有这个文件,这时候想到是不是某些三方库在搞鬼,检查apk包我们在res/raw下果然看到一个keep.xml文件,如下:

<?xml version="1.0" encoding="utf-8"?>
<resources xmlns:tools="http://schemas.android.com/tools"
    tools:keep="@layout/hms_download_progress,@drawable/screen_off"
    tools:shrinkMode="strict"
    />

明显是华为hms库中的,经过一个个筛查发现如下

联想到我们刚刚升级了该库,所以一定是这个库开发者在新版本加入了这个东西,但是它影响很大,只能说相当的不负责任了。

总结

通过上面的剖析,我们了解了资源压缩(Resource Shrinking)到底是什么,同时也知道问题所在,所以其实我们可以不将shrinkResources设置为false,而是在项目中新建一个keep.xml文件,将shrinkMode改回safe就好,当然也可以在keep中添加出错的文件,但是这样只解决这一个问题,不保证后续没有其他动态引用,所以最好就是将模式改回safe即可。

最后大家在升级三方库后一定要仔细测试,以防被坑!

以上就是Android报错Didn‘t find class “android.view.x“问题解决原理剖析的详细内容,更多关于Android报错解决剖析的资料请关注我们其它相关文章!

(0)

相关推荐

  • Android TextView冷门实用方法技巧

    目录 介绍 自定义字体 AutoLink 对齐模式 介绍 TextView 是 Android 开发中最常用的小部件之一.它用于在屏幕上显示文本.但是,TextView 有几个较少为人知的功能,对开发人员非常有用.在本博客文章中,我们将探讨其中的一些功能. 自定义字体 默认情况下,TextView 使用系统字体显示文本.但其实我们也可以导入我们自己的字体文件在 TextView 中使用自定义字体.这可以通过将字体文件添加到资源文件夹(res/font 或者 assets)并在 TextView

  • Android 自定义View实现计时文字详解

    目录 前言 一.XML样式 二.构造方法 三.API方法 四.使用 五.源码 前言   在Android开发中,常常会有计时的一些操作,例如收验证码的时候倒计时,秒表的计时等等,于是我就有了一个写自定义View的想法,本文效果图.   那么现在我们将想法换成现实,这个自定义View比较简单,我们来看怎么写的,首先我们还是在EasyView中进行添加. 一.XML样式   根据上面的效果图,我们首先来确定XML中的属性样式,在attrs.xml中增加如下代码: <!--计时文字--> <d

  • Android 自定义开源库 EasyView实现详解

    目录 配置EasyView 1. 工程build.gradle 或 settings.gradle配置 2. 使用模块的build.gradle配置 使用EasyView 一.MacAddressEditText 1. xml中使用 2. 属性介绍 3. 代码中使用 二.CircularProgressBar 1. xml中使用 2. 属性介绍 3. 代码中使用 三.TimingTextView 1. xml中使用 2. 属性介绍 3. 代码中使用 配置EasyView 这是一个简单方便的And

  • Android源码解析onResume方法中获取不到View宽高

    目录 前言 问题1.为什么onCreate和onResume中获取不到view的宽高? 问题2.为什么View.post为什么可以获取View宽高? 结论 前言 有一个经典的问题,我们在Activity的onCreate中可以获取View的宽高吗?onResume中呢? 对于这类八股问题,只要看过都能很容易得出答案:不能. 紧跟着追问一个,那为什么View.post为什么可以获取View宽高? 今天来看看这些问题,到底为何? 今日份问题: 为什么onCreate和onResume中获取不到vie

  • Android ViewGroup事件分发和处理源码分析

    目录 正文 处理ACTION_DOWN事件 检测是否截断事件 不截断ACTION_DOWN事件 寻找处理事件的子View 事件分发给子View ViewGroup自己处理ACTION_DOWN事件 处理ACTION_DOWN总结 处理ACTION_MOVE事件 检测是否截断ACTION_MOVE事件 不截断ACTION_MOVE 事件分发给mFirstTouchTarget.child 截断ACTION_MOVE 处理 ACTION_UP 和 ACTION_CANCEL 事件 正确地使用requ

  • Android ViewModel创建不受横竖屏切换影响原理详解

    目录 ViewModel的创建方式 参数 1 ViewModelStoreOwner: 参数 2 Factory: ViewModel 为什么不受 Activity 横竖屏生命周期的影响 1.在 Activity 走到 onDestroy 方法时,做了判断 isChangingConfigurations 2.在 Activity 获取 getViewModelStore 时, 3.onRetainNonConfigurationInstance 调用 总结 1.介绍了ViewModel的创建

  • 解决android报错:Intel HAXM is required to run this AVD

    今天,简单讲解Android 启动模拟器时,提示错误: Intel HAXM is required to run this AVD. VT-x is disabled in BIOS. Enable VT-x in your BIOS security settings (refer to documentation for your computer)的问题. 这个问题其实是Android studio是否下载了Download Intel x86 Emulator Accelerator

  • Android报错Error:Could not find com.android.tools.build:gradle:4.1解决办法

    看字面意思,这个问题是Gradle没有对应版本.在搜索引擎没有找到方法之后,尝试自己解决. 有一点很重要,先保证自己的Android Studio是最新的稳定版本! 因为版本更新会修复很多bug,说不定遇到报错就是某个bug引起的. Could not find com.android.tools.build:gradle:3.0.0. 首先,看报错,大概是长这样的: Error:Could not find com.android.tools.build:gradle:4.1. Searche

  • Vue插件报错:Vue.js is detected on this page.问题解决

    Vue插件报错:Vue.js is detected on this pag 下载Vue插件 下载地址:https://chrome.pictureknow.com/ 将下载好的crx文件拖进拓展程序 首先去https://www.bilibili.com/  验证一下Vue.js.devtools是否安装好(看插件的颜色).因为B站是基于Vue开发的. 解决:Vue.js not detected 打开"允许访问文件网址","收集各项错误". 解决:Vue.js

  • maven install报错中程序包xxx不存在的问题解决

    目录 问题 解决 1.依赖未声明或者未下载成功 2.引用的是本地模块,但是未打包到本地maven仓库 3.父子项目包名不一致 注意事项 4.maven仓库路径不对 5.重启idea 6.清空target目录 问题 项目是springcloud项目,在maven install某一个项目时报错: 程序包com.example.commons.application不存在 解决 1.依赖未声明或者未下载成功 首先出现这个问题最常见的原因是jar包未引入,需要在pom中引入对应的jar包,其次检查这个

  • cocos2d-2.0-x-2.0.3 交叉编译到android报错解决

    我用的是cocos2d-2.0-x-2.0.3 之前弄了一天也没成功 今天来了下载了最新的ndk8 更新了sdk 又重新是了一遍 居然成功了,不知道是工具的版本问题还是哪一步出错误了,在这里整理一下: 首先各个工具都下下来配置好,然后将cygwin中的.bash_profile这个文件打开 在最后加上ndk的路径 NDK_ROOT=/cygdrive/c/android-ndk-r8d export NDK_ROOT 2.找到cocos2dx中的create-android-project.ba

  • Android程序报错程序包org.apache.http不存在问题的解决方法

    Android Studio 2.1中使用 Android SDK 6.0(API 23),加载融云Demo时,报错: 解决办法: Android 6.0(api 23)已经不支持HttpClient了,在build.gradle中 加入 useLibrary 'org.apache.http.legacy'就可以了,如图: 以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们.

  • Android Studio 报错“app:processDebugResources"解决方法

    Android Studio 报错"app:processDebugResources"解决方法 Android Studio项目Build的时候报了这么一个错误: Error:Execution failed for task ':app:processDebugResources'. > com.android.ide.common.process.ProcessException: org.gradle.process.internal.ExecException: Pro

  • 关于Android Studio安装完后activity_main.xml前几行报错的解决建议

    当你安装完Android Studio之后,开始了一个新项目,然后你发现: activity_main.xml前几行报错,比如http://schemas.android.com/apk/res/android "URI is not registered". move refactoring is not available while indexing is in progress. apply script build.gradle有问题. activity_main.xml下的

  • Eclipse新建Android项目报错解决方案详细汇总

    本文记录刚接触Android开发搭建环境后新建工程各种可能的报错,并亲身经历漫长的解决过程(╥╯^╰╥),寻找各种偏方,避免大家采坑,希望能帮助到大家. 出错一:The import android.support cannot be resolved类型解决 如图,如果报The import android.support cannot be resolved或者android.support.v7.app.ActionBarActivity类似的错误. 解决方案一 :缺少相关依赖包,这里提供

  • Android Studio 报错“app:processDebugResources"解决方法

    Android Studio 报错"app:processDebugResources"解决方法 Android Studio项目Build的时候报了这么一个错误: Error:Execution failed for task ':app:processDebugResources'. > com.android.ide.common.process.ProcessException: org.gradle.process.internal.ExecException: Pro

随机推荐