x86、armeabi、armeabi-v7a Application.mk NDK 相关

来源:互联网 发布:lol数据异常请规范游戏 编辑:程序博客网 时间:2024/05/16 01:34


很多朋友在开发Android JNI的的时候,会遇到findlibrary returned null的错误,因为某种原因,so没有打包到apk中。下面浅析下引起该错误的原因以及平台兼容性问题。

一、没有将so打包到apk中的原因。

当你发现到findlibrary returned null的错误时,其实最直接的解决办法就是解压apk,看看apk中的x86、armeabi、armeabi-v7a文件夹中是否有对应的so,此时你可能在对应的文件夹下发现少了so,然后再去查原因即可。

一般有两方面的原因:


1.apk中有对应平台的文件夹,但是文件夹里却没有对应的so。

举个例子,apk中lib下面一旦出现x86文件夹,程序运行的时候就会去加载x86对应的库,但是如果此时x86文件夹没有将so放进来,则会遇到报错。

2.第三方对平台的兼容策略与自己不一致。

可能第三方选择了只支持armeabi(假设某支付sdk),但是我们的游戏在Application.mk中配置了APP_ABI := all,如此,我们的游戏打包出 了所有平台的so,但是第三方却只有armeabi文件夹对应的so,造成程序运行异常,这种情况在开发期间最常见,一些小公司由于测试人员不足或者测试设备不足,上线后才发现这个问题也不奇怪。

二、对于平台的支持,我们应该如何选择。

armeabi-v7a确实是可以兼容armeabi的,而v7a的CPU支持硬件浮点运算,目前绝大对数设备已经是v7a了,所以为了性能上的更优,就不要为了兼容放到armeabi。x86是可以兼容armeabi平台运行的,无论是armeabi-v7a还是armeabi,同时带来的也是性能上的损耗,另外需要指出的是,打包出的x86的so,总会比armeabi平台的体积更小,对于性能有洁癖的童鞋们,还是建议在打包so的时候支持x86。具体会有怎样的性能损耗,作者还不能说的非常清楚,可以访问下intel官方在csdn的博客。 总结一下在项目中的表现就是:
如果项目只包含了 armeabi,那么在所有Android设备都可以运行; 如果项目只包含了 armeabi-v7a,除armeabi架构的设备外都可以运行; 如果项目只包含了x86,那么armeabi架构和armeabi-v7a的Android设备是无法运行的; 如果同时包含了 armeabi, armeabi-v7ax86,所有设备都可以运行,程序在运行的时候去加载不同平台对应的so,这是较为完美的一种解决方案,同时也会导致包变大。


Application.mk目的是描述在你的应用程序中所需要的模块(即静态库或动态库)。
Application.mk文件通常被放置在 $PROJECT/jni/Application.mk下,$PROJECT指的是您的项目


Android应用程序中需要的本地模块的Application.mk的语法使用。

1. APP_PROJECT_PATH  :这个变量是强制性的,并且会给出应用程序工程的根目录的一个绝对路径。

                                                  这是用来复制或者安装一个没有任何版本限制的JNI库,从而给APK生成工具一个详细的路径。

2.APP_MODULES  :   这个变量是可选的,如果没有定义,这个模块名字被定义在Android.mk文件中的 LOCAL_MODULE 中。

                                        NDK将由在Android.mk中声明的默认的模块编译,并且包含所有的子文件(makefile文), NDK会自动计算模块的依赖。

                                       如果APP_MODULES定义了,它必须是一个空格分隔的模块列表

                                        ( 注意:NDK在R4开始改变了这个变量的行为,在此之前: 在Application.mk中,该变量是强制的必须明确列出所有需要的模块)

 3.APP_OPTIM :   这个变量是可选的,用来定义“release”或"debug"。在编译您的应用程序模块的时候,可以用来改变优先级。
                                “release”模式是默认的,并且会生成高度优化的二进制代码。

                                  "debug"模式生成的是未优化的二进制代码,但可以检测出很多的BUG,可以用于调试。

                                  注意:如果你的应用程序是可调试的(即,如果你的清单文件在它的<application>标签中把android:debuggable属性设为true),

                                             默认将是debug而非release。把APP_OPTIM设置为release可以覆写它。

                                 注意:可以调试release和debug版二进制,但release版构建倾向于在调试会话中提供较少信息:一些变量被优化并且不能被检测,

                                              代码重新排序可能致使代码步进变得困难,堆栈跟踪可能不可靠,等等。

4. APP_CFLAGS : 一个C编译器开关集合,在编译任意模块的任意C或C++源代码时传递。

                                   它可以用于改变一个给定的应用程序需要依赖的模块的构建,而不是修改它自身的Android.mk文件

5. APP_BUILD_SCRIPT : 默认,NDK构建系统将在$(APP_PROJECT_PATH)/jni 下寻找一个名为 Android.mk 的文件。即,对于这个文件

                                                 $(APP_PROJECT_PATH)/jni/Android.mk

                                                 如果你想重载这个行为,你可以定义APP_BUILD_SCRIPT指向一个不同的构建脚本。

                                  

6. APP_ABI : 默认情况下,NDK的编译系统根据 "armeabi" ABI生成机器代码。可以使用APP_ABI 来选择一个不同的ABI。

                          比如:为了在ARMv7的设备上支持硬件FPU指令。可以使用  APP_ABI := armeabi-v7a

                                      或者为了支持IA-32指令集,可以使用      APP_ABI := x86

                                      或者为了同时支持这三种,可以使用       APP_ABI := armeabi armeabi-v7a x86               一个非绝对路径将总是被解析为相对于NDK顶级目录的路径。

7. APP_STL :默认,NDK构建系统提供由Android系统给出的最小C++运行时库(/system/lib/libstdc++.so)的C++头文件。
                         然而,NDK带有另一个C++实现,你可以在你自己的应用程序中使用或链接它。

                        定义APP_STL以选择它们其中的一个:  APP_STL := stlport_static       -->     static STLport library
                                                                                           APP_STL := stlport_shared    -->     shared STLport library
                                                                                           APP_STL := system               -->      default C++ runtime library


分析一个NDK环境下的 Application.mk


# The ARMv7 is significanly faster due to the use of the hardware FPU,and x86
APP_ABI := armeabi-v7a x86
# APP_ABI := armeabi
APP_PLATFORM := android-10
#STL
APP_STL := stlport_static
APP_CPPFLAGS += -Wno-error=format-security


APP_ABI := armeabi-v7a x86  //同时支持两种

APP_PLATFORM := android-10  对应android 机器的版本是2.3.3

APP_STL := stlport_static  //NDK附带的一个C++库,连接静态库

APP_CPPFLAGS += -Wno-error=format-security

android-ndk  版本与Eclipse的版本不兼容问题,添加标志禁用指定的Werror类型



引用:http://cache.baiducontent.com/c?m=9d78d513d99001f00ffa950e5e468c71182497634ac0d1653bd1c05f931511564616e9bf3365505adc9f3a2143b8482ff7ed7337721420c0c08e8b4edaac925f73df61292743d61644ce43e9941838c122935ceaad04e7bff23784aea589990b0d&p=8b2a97048e9711a05beb96221e50c6&newp=c2769a4787d91ffa0dbd9b7d0b149c231610db2151d7d0172ececd1dc6&user=baidu&fm=sc&query=armeabi%2Dv7a+x86&qid=d6653a1100005c93&p1=1


0 0