在eclipse libs目录录下怎么放入对应不同cpu架构的so文件

关于Android的.so文件你所需要知道的 - 何林子 - 博客园
随笔 - 78, 文章 - 51, 评论 - 0, 引用 - 0
早期的Android系统几乎只支持ARMv5的CPU架构,你知道现在它支持多少种吗?7种!
Android系统目前支持以下七种不同的CPU架构:ARMv5,ARMv7 (从2010年起),x86 (从2011年起),MIPS (从2012年起),ARMv8,MIPS64和x86_64 (从2014年起),每一种都关联着一个相应的ABI。
应用程序二进制接口(Application Binary Interface)定义了二进制文件(尤其是.so文件)如何运行在相应的系统平台上,从使用的指令集,内存对齐到可用的系统函数库。在Android系统上,每一个CPU架构对应一个ABI:armeabi,armeabi-v7a,x86,mips,arm64-v8a,mips64,x86_64。
为什么你需要重点关注.so文件
如果项目中使用到了NDK,它将会生成.so文件,因此显然你已经在关注它了。如果只是使用Java语言进行编码,你可能在想不需要关注.so文件了吧,因为Java是跨平台的。但事实上,即使你在项目中只是使用Java语言,很多情况下,你可能并没有意识到项目中依赖的函数库或者引擎库里面已经嵌入了.so文件,并依赖于不同的ABI。
例如,项目中使用RenderScript支持库,OpenCV,Unity,android-gif-drawable,SQLCipher等,你都已经在生成的APK文件中包含.so文件了,而你需要关注.so文件。
Android应用支持的ABI取决于APK中位于lib/ABI目录中的.so文件,其中ABI可能是上面说过的七种ABI中的一种。
这个应用可以帮助我们理解手机上安装的APK用到了哪些.so文件,以及.so文件来源于哪些函数库或者框架。
当然,我们也可以自己对app反编译来获取这些信息,不过相对麻烦一些。
很多设备都支持多于一种的ABI。例如ARM64和x86设备也可以同时运行armeabi-v7a和armeabi的二进制包。但最好是针对特定平台提供相应平台的二进制包,这种情况下运行时就少了一个模拟层(例如x86设备上模拟arm的虚拟层),从而得到更好的性能(归功于最近的架构更新,例如硬件fpu,更多的寄存器,更好的向量化等)。
我们可以通过Build.SUPPORTED_ABIS得到根据偏好排序的设备支持的ABI列表。但你不应该从你的应用程序中读取它,因为Android包管理器安装APK时,会自动选择APK包中为对应系统ABI预编译好的.so文件,如果在对应的lib/ABI目录中存在.so文件的话。
App中可能出错的地方
处理.so文件时有一条简单却并不知名的重要法则。
你应该尽可能的提供专为每个ABI优化过的.so文件,但要么全部支持,要么都不支持:你不应该混合着使用。你应该为每个ABI目录提供对应的.so文件。
当一个应用安装在设备上,只有该设备支持的CPU架构对应的.so文件会被安装。在x86设备上,libs/x86目录中如果存在.so文件的话,会被安装,如果不存在,则会选择armeabi-v7a中的.so文件,如果也不存在,则选择armeabi目录中的.so文件(因为x86设备也支持armeabi-v7a和armeabi)。
其他地方也可能出错
当你引入一个.so文件时,不止影响到CPU架构。我从其他开发者那里可以看到一系列常见的错误,其中最多的是&UnsatisfiedLinkError&,&dlopen: failed&以及其他类型的crash或者低下的性能:
使用android-21平台版本编译的.so文件运行在android-15的设备上
使用NDK时,你可能会倾向于使用最新的编译平台,但事实上这是错误的,因为NDK平台不是后向兼容的,而是前向兼容的。推荐使用app的minSdkVersion对应的编译平台。
这也意味着当你引入一个预编译好的.so文件时,你需要检查它被编译所用的平台版本。
混合使用不同C++运行时编译的.so文件
.so文件可以依赖于不同的C++运行时,静态编译或者动态加载。混合使用不同版本的C++运行时可能导致很多奇怪的crash,是应该避免的。作为一个经验法则,当只有一个.so文件时,静态编译C++运行时是没问题的,否则当存在多个.so文件时,应该让所有的.so文件都动态链接相同的C++运行时。
这意味着当引入一个新的预编译.so文件,而且项目中还存在其他的.so文件时,我们需要首先确认新引入的.so文件使用的C++运行时是否和已经存在的.so文件一致。
没有为每个支持的CPU架构提供对应的.so文件
这一点在前文已经说到了,但你应该真的特别注意它,因为它可能发生在根本没有意识到的情况下。
例如:你的app支持armeabi-v7a和x86架构,然后使用Android Studio新增了一个函数库依赖,这个函数库包含.so文件并支持更多的CPU架构,例如新增android-gif-drawable函数库:
compile&&pl.droidsonroids.gif:android-gif-drawable:1.1.+&
发布我们的app后,会发现它在某些设备上会发生Crash,例如Galaxy S6,最终可以发现只有64位目录下的.so文件被安装进手机。
解决方案:重新编译我们的.so文件使其支持缺失的ABIs,或者设置
ndk.abiFilters
显示指定支持的ABIs。
最后一点:如果你是一个SDK提供者,但提供的函数库不支持所有的ABIs,那你将会搞砸你的用户,因为他们能支持的ABIs必将只能少于你提供的。
将.so文件放在错误的地方
我们往往很容易对.so文件应该放在或者生成到哪里感到困惑,下面是一个总结:
Android Studio工程放在jniLibs/ABI目录中(当然也可以通过在build.gradle文件中的设置jniLibs.srcDir属性自己指定)
Eclipse工程放在libs/ABI目录中(这也是ndk-build命令默认生成.so文件的目录)
AAR压缩包中位于jni/ABI目录中(.so文件会自动包含到引用AAR压缩包的APK中)
最终APK文件中的lib/ABI目录中
通过PackageManager安装后,在小于Android 5.0的系统中,.so文件位于app的nativeLibraryPath目录中;在大于等于Android 5.0的系统中,.so文件位于app的nativeLibraryRootDir/CPU_ARCH目录中。
只提供armeabi架构的.so文件而忽略其他ABIs的
所有的x86/x86_64/armeabi-v7a/arm64-v8a设备都支持armeabi架构的.so文件,因此似乎移除其他ABIs的.so文件是一个减少APK大小的好技巧。但事实上并不是:这不只影响到函数库的性能和兼容性。
x86设备能够很好的运行ARM类型函数库,但并不保证100%不发生crash,特别是对旧设备。64位设备(arm64-v8a, x86_64, mips64)能够运行32位的函数库,但是以32位模式运行,在64位平台上运行32位版本的ART和Android组件,将丢失专为64位优化过的性能(ART,webview,media等等)。
以减少APK包大小为由是一个错误的借口,因为你也可以选择在应用市场上传指定ABI版本的APK,生成不同ABI版本的APK可以在build.gradle中如下配置:
&&&&&splits {
&&&&&&&&&&abi {
&&&&&&&&&&&&&&&&enable&true
&&&&&&&&&&&&&&&&reset()
&&&&&&&&&&&&&&&&include&'x86',&'x86_64',&'armeabi-v7a',&'arm64-v8a'
&&&&&&&&&&&&&&&&universalApk&true
&&&&&&&&&}
&&&&project.ext.versionCodes = ['armeabi':&1,&'armeabi-v7a':&2,&'arm64-v8a':&3,&'mips':&5,&'mips64':&6,&'x86':&8,&'x86_64':&9]
&&&&android.applicationVariants.all { variant -&
&&&&variant.outputs.each { output -&
&&&&output.versionCodeOverride =&
&&&&project.ext.versionCodes.get(output.getFilter(com.android.build.OutputFile.ABI),&0) *&1000000 + android.defaultConfig.versionCode由于在原来的ADT的Eclipse环境中,用ndk_build工具生成了相应的各个.so库文件之后,eclipse工具就会自动把这些库导入到apk中。而Android Studio目前为止(0.86版本)还无法做到那么自动,但是我们可以通过以下方式进行。
首先在Android Studio工程的app目录下创建整个jni目录,jni目录里写Android.mk、Application.mk以及各类C/C++和汇编源文件。然后跟原来一样,用ndk_build工具去编,然后工具会自动生成libs目录,里面还有每个你在Application.mk里所指定处理器架构的so文件。
完成之后,编辑app目录下的build.gradle文件,为其添加以下代码:
sourceSets {
jniLibs.srcDirs = ['libs']
完整的build.gradle文件如下所示:
apply plugin: 'com.android.application'
compileSdkVersion 20
buildToolsVersion "20.0.0"
defaultConfig {
applicationId "com.adwo.gamecenter.civetcoffeegamecenter"
minSdkVersion 9
targetSdkVersion 20
versionCode 1
versionName "1.0"
buildTypes {
runProguard false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
sourceSets {
jniLibs.srcDirs = ['libs']
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
compile 'com.android.support:appcompat-v7:20.0.0'
Views(...) Comments()手机里libs是什么文件夹来自: lelesmiles 日分享至 :
andriod中libs是什么文件推荐回答:手机里的libs文件夹是存放安装文件的支持文件。提示:libs删除后可能会导致某个软件用不了。libs文件属于软件的执行子文件,属于随软件运行,必然生成的痕迹,所以删除后,依然会再次出现。不过,其实不占多少空间的。关于LIBS文件夹里的文件,由于整个LIBS里很多文件均为多个游戏共用的,因此,不建议把LIBS里的文件删除。android APK根目录下 libs文件夹的armeabi和armeabi-v7a的区别推荐回答:那armeabi-v7a 与 armeabi有什么区别,很高兴能帮助您在我们android APK的根目录有一个 libs文件夹,armeabi-v7a是针对有浮点运算或高级扩展功能的arm cpu,armeabi就是针对普通的或旧的arm cpu.mk里可配置以下宏?armeabi和armeabi-v7a是表示cpu的类型,我们知道一般的手机或平板都是用arm的cpu(mips的就悲催的被忽视了):= armeabiAPP_ABI .so)就会放在这两个文件夹其中的一个。在android,此文件夹下包含了armeabi 和armeabi-v7a两个文件夹,都是什么意思呢,请继续追问:TARGET_CPU_API ,我们的c代码编译成的本地库(各种:= armeabi如果我的回答没帮助到您,不同的cpu的特性不一样 您好libs是什么意思推荐回答:呜呜呜呜呜ucdownloads是什么文件夹能删吗推荐回答:UC浏览器的下载目录,可以删除,但是在下次下载的时候目录会自动重建!libs是什么文件夹可以删除吗推荐回答:暂无android中libs目录下armeabi和armeabi-v7a的区别推荐回答:armeabi默认选项,支持基于 ARM* v5TE 的设备支持软浮点运算(不支持硬件辅助的浮点计算)支持所有 ARM* 设备armeabi-v7a支持基于 ARM* v7 的设备支持硬件 FPU 指令支持硬件浮点运算不同手机由于cpu的不同,使用不同的驱动。ABI:指应用基于哪种指令集来进行编译,ABI总共有四种,分别是armeabi、armeabi-v7a、mips、x86,它们都是表示cpu的类型。三星手机中的yysec 是什么文件夹推荐回答:除了download android libs dcim system samsung autohomemain music和你的音乐盒文件,其它都可以删除。满意加分!安卓SD卡中这六个文件夹分别是什么意思?什么用途?是否可删除?推荐回答:underess文件夹,一个游戏的附属文件夹,Ringtones文件夹,存放音乐和铃声的文件夹。AutolnstallAPK文件夹,这个文件夹的作用是:当你把你需要安装的软件安装包apk放到里面,下次你刷完固件后,机器会默认一起安装此文件夹里的软件。libs文件夹该文件夹是存放安装文件的支持文件,如果删除可能导致某个软件用不了。documents文件夹存放我的文件用的。mobisage文件夹mobisage是存放一个移动广告平台的文件用的。是垃圾,可以删除。分享至 :
下一篇:上一篇:相关帖子相关文章---手机里libs是什么文件夹不同 cpu 平台对应的 so 文件问题怎么解决的 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
已注册用户请 &
不同 cpu 平台对应的 so 文件问题怎么解决的
· 256 天前用 iPhone 发布 · 1690 次点击
Android 手机 cpu 大部分是 arm ,但也有 x86 的等等。在使用优酷 SDK 时就遇到了这样子一个问题:
Android Studio 开发,使用 x86 的虚拟机调试出现如下错误
java.lang.UnsatisfiedLinkError: dlopen failed: &...*.so& has unexpected e_machine: 40
那个 so 文件是优酷 sdk 里的,我将它放在 x86 目录下了,没 x86 目录时直接报找不到 so 文件。
网上找了个支持 x86 的优酷应用,解压将里面的 x86 目录复制过来,还是出现此错误。真是怪了,在 PC 里用 arm 的虚拟机太慢了不实际。难道真的要买部真机来调试?但最好还是能兼容 x86 吧
9 回复 &| &直到
16:26:03 +08:00
& &256 天前 via Android
你得加安卓的 linker ,依赖库如 bionic 甚至 framework
& &256 天前
缺少很多必要的概念
so 文件是二进制文件,编译后和体系架构相关的,不同的体系架构下要有对应的 so 文件,用 file 或者 readelf 看下就知道了,你在 x86 上调试 android 的代码,最典型的的做法是 google 帮你做了 studio 里面用的 qemu ,将 x86 的汇编转换成 arm 的汇编进行执行的
qemu 使用了 qemu 的 binary translation 的机制导致你在 x86 上运行 arm 的的代码会很慢,现在看起来你是想在 x86 上直接运行针对 x86 的 android app ,也可以,但是因为指令差别,只能在 x86 的手机上跑,无法测试覆盖到 arm 架构的手机
再往上就是 java 里面的 jni 调用,使用 so 库里面的 c 或者 cpp 的 api ,但是执行 java 的环境是根据 android 里面环境构建的 jvm , bonic 这些,所以你需要把这个 runtime 做一些调整
从下到上,就是这样一个过程
也可以不买手机,你说的那个需求现在也是一门生意,有很多人在做云端的测试平台,可以到 AWS 上找一下 test farm ,可以满足你的需求
& &256 天前
尽量能 Java 解决的就 Java 吧,讲真原生的跨平台兼容性太差了
& &255 天前
&那个 so 文件是优酷 sdk 里的&
&网上找了个支持 x86 的优酷应用,解压将里面的 x86 目录复制过来&
所以你现在用的 so 到底是哪个? 讲道理 sdk 里有就用 sdk 的啊
& &255 天前 via iPhone
@ sdk 里没有 x86 目录,所以一开始是找不到 so 文件问题,后来,我先是把 sdk 里 armeabi-v7a 复制重命名为 x86 ,就出现了此问题,然后用了支持 x86 的优酷应用里的 so 文件还是一样的问题。
& &255 天前 via Android
直接不支持 x86 就 ok 了。 youku 官方都不支持,啥折腾是无用功
& &255 天前 via Android
x86 手机很多吗?
& &255 天前
那些 x86 cpu 的安卓系统,其实是 cpu 支持指令集转换,用的还是 arm 的 apk 啊
& &255 天前
@ 重命名, 肯定不行的, 错误提示说的很清楚了; 另外...sdk 里没有就别折腾了; 现在有很多模拟器是跑的 arm 指令集的啊
& · & 2119 人在线 & 最高记录 3541 & · &
创意工作者们的社区
World is powered by solitude
VERSION: 3.9.7.5 · 52ms · UTC 04:51 · PVG 12:51 · LAX 21:51 · JFK 00:51? Do have faith in what you're doing.转载-Android系统支持的CPU架构 - 喧嚣求静 - ITeye博客
博客分类:
早期的Android系统几乎只支持ARMv5的CPU架构,你知道现在它支持多少种吗?7种!
Android系统目前支持以下七种不同的CPU架构:ARMv5,ARMv7 (从2010年起),x86 (从2011年起),MIPS (从2012年起),ARMv8,MIPS64和x86_64 (从2014年起),每一种都关联着一个相应的ABI。
应用程序二进制接口(Application Binary Interface)定义了二进制文件(尤其是.so文件)如何运行在相应的系统平台上,从使用的指令集,内存对齐到可用的系统函数库。在Android 系统上,每一个CPU架构对应一个ABI:armeabi,armeabi-v7a,x86,mips,arm64- v8a,mips64,x86_64。
为什么你需要重点关注.so文件
如果项目中使用到了NDK,它将会生成.so文件,因此显然你已经在关注它了。如果只是使用Java语言进行编码,你可能在想不需要关注.so文 件了吧,因为Java是跨平台的。但事实上,即使你在项目中只是使用Java语言,很多情况下,你可能并没有意识到项目中依赖的函数库或者引擎库里面已经 嵌入了.so文件,并依赖于不同的ABI。
例如,项目中使用RenderScript支持库,OpenCV,Unity,android-gif-drawable,SQLCipher等,你都已经在生成的APK文件中包含.so文件了,而你需要关注.so文件。
Android应用支持的ABI取决于APK中位于lib/ABI目录中的.so文件,其中ABI可能是上面说过的七种ABI中的一种。
这个应用可以帮助我们理解手机上安装的APK用到了哪些.so文件,以及.so文件来源于哪些函数库或者框架。
当然,我们也可以自己对app反编译来获取这些信息,不过相对麻烦一些。
很多设备都支持多于一种的ABI。例如ARM64和x86设备也可以同时运行armeabi-v7a和armeabi的二进制包。但最好是针对特 定平台提供相应平台的二进制包,这种情况下运行时就少了一个模拟层(例如x86设备上模拟arm的虚拟层),从而得到更好的性能(归功于最近的架构更新, 例如硬件fpu,更多的寄存器,更好的向量化等)。
我们可以通过Build.SUPPORTED_ABIS得到根据偏好排序的设备支持的ABI列表。但你不应该从你的应用程序中读取它,因为 Android包管理器安装APK时,会自动选择APK包中为对应系统ABI预编译好的.so文件,如果在对应的lib/ABI目录中存在.so文件的 话。
App中可能出错的地方
处理.so文件时有一条简单却并不知名的重要法则。
你应该尽可能的提供专为每个ABI优化过的.so文件,但要么全部支持,要么都不支持:你不应该混合着使用。你应该为每个ABI目录提供对应的.so文件。
当一个应用安装在设备上,只有该设备支持的CPU架构对应的.so文件会被安装。在x86设备上,libs/x86目录中如果存在.so文件的 话,会被安装,如果不存在,则会选择armeabi-v7a中的.so文件,如果也不存在,则选择armeabi目录中的.so文件(因为x86设备也支 持armeabi-v7a和armeabi)。
其他地方也可能出错
当你引入一个.so文件时,不止影响到CPU架构。我从其他开发者那里可以看到一系列常见的错误,其中最多的是"UnsatisfiedLinkError","dlopen: failed"以及其他类型的crash或者低下的性能:
使用android-21平台版本编译的.so文件运行在android-15的设备上
使用NDK时,你可能会倾向于使用最新的编译平台,但事实上这是错误的,因为NDK平台不是后向兼容的,而是前向兼容的。推荐使用app的minSdkVersion对应的编译平台。
这也意味着当你引入一个预编译好的.so文件时,你需要检查它被编译所用的平台版本。
混合使用不同C++运行时编译的.so文件
.so文件可以依赖于不同的C++运行时,静态编译或者动态加载。混合使用不同版本的C++运行时可能导致很多奇怪的crash,是应该避免的。 作为一个经验法则,当只有一个.so文件时,静态编译C++运行时是没问题的,否则当存在多个.so文件时,应该让所有的.so文件都动态链接相同的 C++运行时。
这意味着当引入一个新的预编译.so文件,而且项目中还存在其他的.so文件时,我们需要首先确认新引入的.so文件使用的C++运行时是否和已经存在的.so文件一致。
没有为每个支持的CPU架构提供对应的.so文件
这一点在前文已经说到了,但你应该真的特别注意它,因为它可能发生在根本没有意识到的情况下。
例如:你的app支持armeabi-v7a和x86架构,然后使用Android Studio新增了一个函数库依赖,这个函数库包含.so文件并支持更多的CPU架构,例如新增android-gif-drawable函数库:
compile ‘pl.droidsonroids.gif:android-gif-drawable:1.1.+’
发布我们的app后,会发现它在某些设备上会发生Crash,例如Galaxy S6,最终可以发现只有64位目录下的.so文件被安装进手机。
解决方案:重新编译我们的.so文件使其支持缺失的ABIs,或者设置
ndk.abiFilters
显示指定支持的ABIs。
最后一点: 如果你是一个SDK提供者,但提供的函数库不支持所有的ABIs,那你将会搞砸你的用户,因为他们能支持的ABIs必将只能少于你提供的。
将.so文件放在错误的地方
我们往往很容易对.so文件应该放在或者生成到哪里感到困惑,下面是一个总结:
Android Studio工程放在jniLibs/ABI目录中(当然也可以通过在build.gradle文件中的设置jniLibs.srcDir属性自己指定)
Eclipse工程放在libs/ABI目录中(这也是ndk-build命令默认生成.so文件的目录)
AAR压缩包中位于jni/ABI目录中(.so文件会自动包含到引用AAR压缩包的APK中)
最终APK文件中的lib/ABI目录中
通过PackageManager安装后,在小于Android 5.0的系统中,.so文件位于app的nativeLibraryPath目录中;在大于等于Android 5.0的系统中,.so文件位于app的nativeLibraryRootDir/CPU_ARCH目录中。
只提供armeabi架构的.so文件而忽略其他ABIs的
所有的x86/x86_64/armeabi-v7a/arm64-v8a设备都支持armeabi架构的.so文件,因此似乎移除其他ABIs的.so文件是一个减少APK大小的好技巧。但事实上并不是:这不只影响到函数库的性能和兼容性。
x86设备能够很好的运行ARM类型函数库,但并不保证100%不发生crash,特别是对旧设备。64位设备(arm64-v8a, x86_64, mips64)能够运行32位的函数库,但是以32位模式运行,在64位平台上运行32位版本的ART和Android组件,将丢失专为64位优化过的性 能(ART,webview,media等等)。
以减少APK包大小为由是一个错误的借口,因为你也可以选择在应用市场上传指定ABI版本的APK,生成不同ABI版
本的APK可以在build.gradle中如下配置:
enable true
include 'x86', 'x86_64', 'armeabi-v7a', 'arm64-v8a' //select ABIs to build APKs for
universalApk true //generate an additional APK that contains all the ABIs
// map for the version code
project.ext.versionCodes = ['armeabi': 1, 'armeabi-v7a': 2, 'arm64-v8a': 3, 'mips': 5, 'mips64': 6, 'x86': 8, 'x86_64': 9]
android.applicationVariants.all { variant -&
// assign different version code for each output
variant.outputs.each { output -&
output.versionCodeOverride =
project.ext.versionCodes.get(output.getFilter(com.android.build.OutputFile.ABI), 0) * 1000000 + android.defaultConfig.versionCode
浏览: 285221 次
来自: 广州
按照楼主这样是可以页面是可以完成效果,但是后台依旧会报错打印出 ...
sunshaoqun 写道二次元 写道希望能分享下.so文件编 ...
二次元 写道希望能分享下.so文件编译源码!求.so源码。。。 ...
多谢,网上说的 “选择你要生成Build.xml文件的项目,右 ...
哥们,用你的demo。android 端录制的amr格式这边播 ...

我要回帖

更多关于 android libs 目录 的文章

 

随机推荐