Android加载动态库规则笔记
2016年06月05日 Android

Android菜鸟,距离上次长时间调试Android平台下的游戏是一年前了,最近几乎都没调试过Android上的东西,特别还是这种需要跨平台的游戏,各种JNI调用,各种动态库齐上,各种渠道各种接。尤其是类似那种AnySDK的一站式的接入SDK的,不出问题皆大欢喜,只要出了一个问题就够排查上半天,因为游戏和渠道SDK的中间又多了一层中间层代码,这样问题排查起来更麻烦。非常菜的问题,长时间不用就会忘记,这里记录一下,都是零碎的小知识。

涉及到JNI调用肯定就有第三方的动态库(.so文件),在游戏里也就是C++代码的封的动态库。因为到现在为止Android下台支持的CPU架构已经达到7种(ARMv5,ARMv7, ARMv8,x86,x86_64,mips),不同CPU架构上的不同的ABI(Application Binary Interface),其定义了二进制文件如何在对应的架构的系统平台上运行,如指令集,可用的系统库函数等。在Android系统上,上面7种不同的CPU架构对应的ABI分别是armeabi,armeabi-v7a,arm64-v8,x86,x86_64,mips。而这些平台ABI就体现在C++(或者C代码)生成的so文件打包到apk里面时所在libs的具体目录,Eclipse生成的Android工程都会有libs目录,可以看到对应的libs文件夹下有如armeabi这样的文件夹,这就是相应平台的二进制包,当然最好就是为支持的每一种平台都提供对应的二进制包,这样Android的包管理器在安装apk的时候就会把相应平台的二进制包拷贝到相应程序的私有目录的lib目录里(并不会拷贝所有的二进制包,apk里有因为apk可能会安到种被支持的设备上),问题就是apk包体会变得特别大,如果一个游戏的C++的so库到了十几M,这样给每个平台都提供一个,无形就多了近百M的apk包大小。

这次遇到的问题就是游戏只提供了一个armeabi的so库,这样就能兼容大部分机型(ARM向前兼容,x86兼容armeabi和armeabi-v7a,当然mips就略过了),为了兼顾包体大小与机型兼容。游戏本身只提供了armeabi的so,上文说接通用型的渠道SDK,由通用SDK提供工具进行游戏的apk进行再解包打包,问题来了,某些渠道直接打开游戏就闪退,中间排查原因过程不多说了,接了Eclipse看log直接是报UnsatisfiedLinkError错,也就是调用loadLibrary的时候没找到对应的so库,直接解包apk看libs文件夹下,果不其然多了一个armeabi-v7a文件夹,也就是渠道提供了不同平台下的自己的二进制包,解包把对应的armeabi-v7a文件夹删除,再封包,再打开游戏,不再崩溃了。

记录End