Android主dex分包无效问题

项目场景:

接入了性能监控SDK,当用户端发生异常时可以将异常信息上传到后台统计平台。


问题描述

后台异常信息中出现了 ClassNotFoundException 和 NoClassDefFoundError
首先看到了这篇文章,但是没有完全理解 ClassNotFoundException&NoClassDefFoundError


原因分析:

根据关键字 NoClassDefFoundError 查到了官方文档

官方文档 https://developer.android.com/studio/build/multidex?hl=zh-cn#keep

使用官方文档修改配置模块的build.gradle,发现主dex分包配置无效。生成的apk可以在AndroidStudio中直接查看(把APK拖到AndroidStudio中或者去编译后的目录app/build/outputs/apk/*.apk双击进行查看)


主dex分包无效时,根据 minSdkVersion 参考不同的文档
minSdkVersion < 21 可以参考文章
https://blog.csdn.net/BingShuShu/article/details/79447964

minSdkVersion >= 21 可以参考issue和文章
https://github.com/Tencent/tinker/issues/1084
发现>=21时,AGP会忽略分包配置,因为这种配置下默认开启了分包逻辑,所以忽略了分包相关的配置。

下面是个人的一些理解
Android5.0之前的手机系统是Dalvik运行环境,只支持一个class.dex。当有多个dex文件时(打包时需要分包也是历史遗留的坑,方法数不能超过2的10次方)
这个时候就需要使用官方提供的依赖 MultiDex ,它会集成在class.dex也可以叫主dex中,通过它来管理 class2.dex,class3.dex ... 也可以叫辅助dex
附带一篇文章 https://www.cnblogs.com/tonybright/p/8907220.html 可以看到 MultiDex 的install方法在Android5.0之后的系统上其实只是打印了日志
System.getProperty("java.vm.version") 2.0.0或更高,参考https://developer.android.com/guide/practices/verifying-apps-art.html?hl=zh-cn

Android5.0及之后的手机系统是ART运行环境,它默认支持多个dex文件的解析,在安装阶段就会将所有的dex文件进行解析生成一个oat文件。(安装慢但启动快)
既然已经不需要主dex去管理辅助dex,那么Android5.0及之后的手机上,是不需要关注官方文档中提到的{声明主要 DEX 文件中必需的类}

最终排除掉MultiDex配置相关的排查方向

异常是加固组件上传的,是否是加固流程解析Dex文件异常导致

加固过程
读取初始的AndroidManifest文件,读取并保存初始的Application节点的类路径,如com.test.OriginApplication
修改AndroidManifest文件,替换Application节点的类路径,如jiagu.test.JiaguApplication
对原有的所有dex文件进行加密并存储到apk文件中
解加固相关的所有文件生成一个class.dex文件,作为加固后的apk的唯一dex文件

解加固过程
打开应用时,系统默认会加载新生成的dex文件以及新的AndroidManifest文件
此时相当于打开了另一个apk->jiagu.test.JiaguApplication,在新apk的Application初始化时,进行解加固操作
将原有的dex文件解压缩以及解密
使用类加载器加载原有的dex文件,将原有的类加载到内存中
此时com.test.OriginApplication因为原有的dex文件经过了类加载,原有的Application可以被加载和创建
使用原有的Application->com.test.OriginApplication替换ActivityThread中的Application->jiagu.test.JiaguApplication
应用生命周期回到正常的轨道

从以上流程可以知道,解加固过程存在加载dex文件的流程,如果该流程出现异常,就会导致类加载异常


解决方案:

加固组件需要丰富日志,当出现以上异常时,尝试手动加载相关类,观察是否会发生同一种异常。

该问题使用同种机型未能复现线上问题,待日志丰富后继续排查。

PS:近期发现类似报错,提示信息是ClassNotFound,但实际是低版本手机缺少了某个so库导致。当发生这种异常时,很难直接定位到相关问题。因为后台的异常报错中不会将异常信息和缺少so库做关联。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值