引言
最近APP上线,遇到一个比较诡异的问题。最后竟然和dex文件有关,也是醉了,看来还得深入底层学习啊。
问题描述
在集成阿里推送SDK时,需要在Application中进行初始化,大多数Android手机都是OK的。唯独红米/小米手机在初始化的的时候报错。。。截图如下:
在截图中我们看到,代码在initCloudChannel中发生了异常,异常是NoClassDefFoundError:com.ut.device.UTDevice。看到这些,本能的去看一下jar包有没有引入,发现jar包是引入的,如图:
那这问题就。。。在尝试了各种clean,refresh无效后,只能暂时放一下了。
转机
晚上回去看书,看到Android工程中方法数目65K的限制,详细介绍如下:
Android的所有可执行文件都存在dex文件中,其中包含已编译的代码来运行你的应用程序。Dalvik虚拟机对可执行dex文件的规格是有方法限制的,即一个单一的dex文件的方法总数最多为65536,包括:
引用的Android Framework方法、library的方法及编程中写入代码的方法等。
如果方法数量大于65K,那么编译工程是会生成两个dex文件。APP启动时会依次加载class.dex和class1.dex。Application对象被创建以后,会在attachBaseContent方法中通过MultiDex.install方法来加载其他dex文件,这个时候如果MultiDex相关的类不在主dex中,很显然该类是无法加载的。同时由于Application中的成员和代码块会先于attachBaseContent方法而初始化,这个时候其他dex文件还没有被加载,因此不能在Application的成员和代码块中访问其他dex中的类。
后来我看到了一个例子,发现也是出现NoClassDefFoundError。这不禁让我想起了这个问题。我抱着试一下的心态验证是不是这个问题(MIUI可能容易出现这种问题)。我把阿里移动推送的SDK移到了2,3个月前的版本,这个版本当时没有上2.0,代码规模比较小,方法数小于65K。我在小米手机上运行后,居然没有问题!!!
解决
当前代码规模较大,方法数>80K。没版本只能精简一些SDK库和代码库,逐步缩减。后来各种机型都可以正常运行了。。。
Android底层博大精深,要好好学习啊!