前言
在接入360 Android SDK时遇到在有些机型的Android机器上报错,具体错误提示为:
Failure to initialize! Your hardware does not support this application
Unity生成的原生包可以正常运行,那问题很明显出在360 SDK身上。遇到问题时,我的习惯首先是去想自己哪里有问题,排除掉自身原因,在找其他问题。翻看了360 SDK接入文档,怀疑是签名不对,因为360 SDK只支持V1签名,我编译Android project 使用的是Gradle 2.2版本。检查build.gradle文件内容如下:
android {
...
defaultConfig { ... }
signingConfigs {
release {
storeFile file("myreleasekey.keystore")
storePassword "password"
keyAlias "MyReleaseKey"
keyPassword "password"
v2SigningEnabled false
}
}
}
是按照官方设置做的,那这里就没啥问题。排除完自己的问题,就去问360SDK的同学了。
沟通问题
在我连续加了十几次对方包打听的QQ后,终于接受了我的请求。在这里不得不感叹以前公司和360有合作关系时,都是运营同学拉个群,任何问题都是及时解答。现在只能通过这种无限骚扰的方式才能沟通。沟通过后,让我自己查明我所用的引擎支持哪些动态库,不用的就删除。真是无语啊,你提供的动态库,文档里也不说明一下,而让开发者自己去研究你提供的库,是否适配游戏。
后面又找之前的同事,专业接入SDK的同学问了下是否遇到此类问题,说没遇到过这个问题。提供了思路,让我挨个添加,使用二分法定位那个库不支持。跑去提供的文件看了下目录结构,大概明白了啥情况。目录结构如下:
- arm64-v8a
- liblegend.so
- libonlywechat_plugin.so
- libqhsdk.so
- armeabi
- liblegend.so
- libonlywechat_plugin.so
- libqhsdk.so
- armeabi-v7a
- liblegend.so
- libonlywechat_plugin.so
- libqhsdk.so
- mips
- liblegend.so
- libonlywechat_plugin.so
- libqhsdk.so
- mips64
- liblegend.so
- libonlywechat_plugin.so
- libqhsdk.so
- x86
- liblegend.so
- libonlywechat_plugin.so
- libqhsdk.so
- x86_64
- liblegend.so
- libonlywechat_plugin.so
- libqhsdk.so
看了一下Unity官方文档,说明如下:
Android: OS 4.1 or later; ARMv7 CPU with NEON support or Atom CPU
Unity设置里: File->BuildSetting->Android->PlayerSetting->Device Filter,这里只有Armv7,x86的选项。删除掉多余的so文件,问题解决。
动态库和静态库
动态库和静态库都是程序代码编译后导出不同类型的库文件。
静态库特性如下:
- 在程序链接时,静态库将被写入可执行文件
- 程序在启动时,静态库将被加载到代码区
- 每个进程的静态库是独立的
动态库特征如下:
- 程序在链接时,只写入动态库的路径
- 程序在需要时加载动态库
- 所有进程共享一份动态库
首先搞清楚动态库,也就是so文件后。我就更加不明白了,既然so文件是自己需要时加载,为啥360SDK自带的so文件会导致Unity报错?
ABI简介
不同的CPU对应不同的指令集,为了兼容不同的CPU,在生成动态文件时,可以指定不同的CPU生成对应的文件。文件对应的类型就是API(Application binary interface)。具体文档参考这里。
为不同类型CPU设备生成对应的动态文件,如果不指定生成对应CPU架构的APP,所有动态文件将包含在APP中。
程序运行时如何找到对应的动态库?
- 默认路径加载
- 指定的路径加载
Android APP在安装时会生成如下目录:
/data/data/<package_name>/lib/lib<name>.so
list 我们应用,目录如下:
libil2cpp.so
liblegend.so
libmain.so
libonlywechat_plugin.so
libqhsdk.so
libunity.so
libxlua.so
程序在安装时,安装程序将扫描:
1. lib/<primary-abi>/lib<name>.so // 设备主ABI,设备对应cpu支持的ABI
2. lib/<secondary-abi>/lib<name>.so // 设备辅助ABI,如果主ABI没有,使用辅助ABI
刨根问底
测试使用的一加5手机,小米5,都有问题,骁龙825和骁龙820肯定是支持arm64-v8a。如果是360 SDK自己使用这些库那肯定没有问题。为啥Unity会报错?只能说Unity在启动时加载了所有放在lib目录下的库。由于so文件带有cpu使用信息,Unity只支持armabi-v7a,x86。这样整个问题算是清楚了。