In its early days, the Android OS was pretty much supporting only one CPU architecture: ARMv5.
Do you know how many it does support now? … 7!

Seven distinct CPU-architectures are currently supported by the Android OS: ARMv5ARMv7 (since 2010), x86 (2011), MIPS (2012), ARMv8MIPS64 and x86_64 (2014). Each of them is associated with a respective ABI.

An Application Binary Interface is the definition of how binaries (esp. .so files) should be made in order to work on the platform, from the instruction set used and memory alignment, to the system libraries that are available. On Android there is one per CPU architecture:  armeabiarmeabi-v7ax86, mips, arm64-v8amips64x86_64.

Why should you care about .so files in the first place?

If you’re using the NDK, you’re generating .so files, so you obviously already care. If you’re dealing only with Java code, you could think you don’t need to, as it’s cross-platform… but in fact, even in this case, quite often, you may rely without knowing it on libraries and engines that make your app embed .so files and become ABI-dependent/

Using the RenderScript support Library? OpenCV? Unity? android-gif-drawable? SQLCipher? You’ve got .so files inside your APK, and you need to care about these.

The ABIs supported by your Android application are determined by the presence of .so files inside your APK, under the “lib/<ABI>” folders where ABI can be one or more of armeabiarmeabi-v7aarm64-v8amips, mips64x86x86_64 (the current seven ABIs).

Native Libs Monitor - screenshotNative Libs Monitor can help you understanding what .so files are embedded inside your APK and installed on your device, and which libraries and frameworks they’re coming from.

Most devices are compatible with more than one ABI. For example, ARM64 devices and x86 devices can run armeabi-v7a and armeabi binaries too! But it’s always better to provide libraries compiled for the preferred ABI of the device. This way, libraries can run without an emulation layer (in case of arm libs on x86 devices), and get more performance thanks to the recent architecture improvements (hardware fpu, more registers, better vectorization, etc).

You can get the list of supported ABIs, sorted by preference, from Build.SUPPORTED_ABIS. But you shouldn’t need to read it from your app, as Android’s package manager will automatically install the .so files compiled for your device preferred ABI that are present inside your APK, if they’re properly present under lib/<ABI>.

That’s where things may go wrong for your app!

There is a dead simple but not well-known important rule to follow when dealing with .so files.

You should provide libraries optimized for each ABIs if possible, but it’s all in or nothing: you shall not mix. You have to provide the full set of the libraries you’re using in each ABI folder.

When an application is installed on a device, only the .so files from one of its supported architectures are getting installed. On x86 devices, that can be the libs from the x86 folder if there is one, else from the armeabi-v7a, else armeabi folder (yes, x86 devices support these too).

But they may go wrong in many other ways too…

When you include a .so file, not only the architecture matters. Here is a list of really common mistakes I see from other developers, that are leading to “UnsatisfiedLinkError”, “dlopen: failed”, and other crashes or bad performance:

using a .so file that has been compiled against android-21+ platform version, to run it on android-15 device. Ouch.

When using the NDK, you may be tempted to “compile against the latest platform”, but it’s in fact quite wrong as ndk platforms aren’t backward compatible, they’re forward compatible! Use the same platform level than your app’s minSdkVersion.

That means that when you’re including a .so file that has already been compiled, you have to check the version it has been made to run on.

mixing .so files that are using different C++ runtimes

.so files can rely on various C++ runtimes, statically compiled or dynamically loaded. Mixing versions of C++ runtimes can lead to many weird crashes and should be avoided. As a rule of thumb, when having only one .so file, it’s ok to statically compile a C++ runtime, else you should have them all dynamically linking the same C++ runtime.

That means that when you’re including a .so file that has already been compiled and you already have some of them, you have to check the C++ runtime it’s using.

not providing all the libs for each of the supported platforms

This was already previously described, but you should really pay attention to this, as it may happen behind your back.

Example: You have an Android app with .so files for armeabi-v7a and x86 architectures. Then you add a dependency on another library that embeds .so files and supports more architectures, as android-gif-drawable: compile ‘pl.droidsonroids.gif:android-gif-drawable:1.1.+’.

Release your app, and then you’ll see it crashing on some devices, like the Galaxy S6, because only the .so files from the 64-bit directory got installed.

Solution: recompile your libs to support the missing ABIs, or set ndk.abiFilters to the one you support.

One more thing: If you’re a library provider, and you’re not supporting all the ABIs, you’re screwing up your customers, as they can’t support more ABIs than you do.

putting .so files in the wrong place

It’s easy to get confused on where .so files should be put or generated by default, here is a summary:

  • jniLibs/ABI inside an Android Studio project (can be changed using jniLibs.srcDir property)
  • libs/ABI inside an eclipse project (that’s where ndk-build generates libs by default too)
  • jni/ABI inside an AAR (the libs will get automatically included in the APK that references the AAR).
  • lib/ABI inside the final APK
  • inside the app’s nativeLibraryPath on a <5.0 device / nativeLibraryRootDir/CPU_ARCH on a >=5.0 device (done by PackageManager during app installation)

providing only armeabi libs and ignoring all the other ABIs

armeabi is supported by all the x86/x86_64/armeabi-v7a/arm64-v8a devices, so that may look like a good trick to remove all the other ABIs to generate a light APK. But it’s not: there is an impact on performance and compatibility, and not only for the library itself.

x86 devices can run ARM libraries quite well, but it’s not 100% crash proof, particularly on the older devices. 64-bit devices (arm64-v8a, x86_64, mips64) can all run 32-bit libraries, but they do so in 32-bit mode, running a 32-bit version of ART and Android components, loosing the 64-bit performance improvements that have been made on the 64-bit version of ART, webview, media…

Reducing APK’s weight is in any case a false excuse, as you can upload distinct ABI-dependent APKs to the Play Store (for the same app entry, of course). You only have to switch to advanced mode and upload your APKs with different ABI support and versionCodes. Generating these APKs is as simple as adding this to your build.gradle:

Using private system libraries

The libraries you can use are the ones which are part of the NDK ones. Any other lib isn’t guaranteed to work across devices and may trigger crashes starting with Android N: https://developer.android.com/preview/behavior-changes.html#ndk

TL;DR:

One does not simply include random libs and .so files inside an android app.meme

转载于:https://www.cnblogs.com/yuanxiaoping_21cn_com/p/6720404.html

What you should know about .so files相关推荐

  1. 批处理 bat cmd 命令大全

    net use \\ip\ipc$ " " /user:" " 建立IPC空链接 net use \\ip\ipc$ "密码" /user: ...

  2. CCAH-CCA-500-4题:Where are Hadoop task log files stored?

    4.Where are Hadoop task log files stored? For each YARN job, the Hadoop framework generates task log ...

  3. 基于Picture Library创建的图片文档库中的上传多个文件功能(upload multiple files)报错怎么解决?...

    复现过程 首先,我创建了一个基于Picture Library的图片文档库,名字是 Pic Lib 创建完毕后,我点击它的Upload 下拉菜单,点击Upload Picture按钮 在弹出的对话框中 ...

  4. 读django文档——Managing static files (e.g. images, JavaScript, CSS)

    在上一篇读django文档--nginx + uwsgi 部署django项目_苦行僧的妖孽日常-CSDN博客  部署django项目后,发现在runserver时都能正常部署的 static 文件都 ...

  5. spark-submit --files 动态加载外部资源文件

    在做spark时,有些时候需要加载资源文件,需要在driver或者worker端访问.在client模式下可以使用IO流直接读取,但是在cluster模式下却不能直接读取,需要如下代码: val is ...

  6. IOS沙盒Files目录说明和常用操作

    - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launc ...

  7. _catboost.CatBoostError: C:/Program Files (x86)/Go Agent/pipelines/BuildMaster/catboost.git/catboost

    _catboost.CatBoostError: C:/Program Files (x86)/Go Agent/pipelines/BuildMaster/catboost.git/catboost ...

  8. R语言list.files函数获取文件列表实战

    R语言list.files函数获取文件列表实战 目录 R语言list.files函数获取文件列表实战 #仿真数据 #基本语法

  9. pyinstaller打包之后运行出现:Could not find the matplotlib data files

    pyinstaller 打包之后Could not find the matplotlib data files 目录 pyinstaller 打包之后Could not find the matpl ...

  10. Extjs 打包 failed to find any files

    版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.csdn.net/inforstack/article/details/50898641 在编译的时候,classic是 ...

最新文章

  1. linux服务器安装mysql并配置外网访问
  2. 006_Topic消息模式发送对象消息
  3. 云痕大数据 家长登录_云痕家长app
  4. [Leetcode] Binary Tree Maximum Path Sum
  5. Linuxmint 美化之路
  6. 在ThinkPHP框架(5.0.24)下引入Ueditor并实现向七牛云对象存储上传图片同时将图片信息保存到MySQL数据库,同时实现lazyload懒加载...
  7. R语言与机器学习学习笔记(分类算法)
  8. solidity event是什么
  9. 计算机组成原理白中英知识点总结,计算机组成原理重点整理(白中英版)
  10. 最新JS验证手机号码(2021)
  11. 如何在IDEA上创建一个JSP项目【亲测有效】
  12. 关于单片机(MCU)最强科普(万字总结,先马后看)
  13. traceroute和tracert原理
  14. 计算机出现函数不正确的是,小编教你快速修复无法访问函数不正确的方法
  15. H: Yet Another Crosses Problem
  16. 【BZOJ3831】[Poi2014]Little Bird 单调队列
  17. iOS-脚本打包出现的问题最后居然这么解决了
  18. 论文写作学习之引言章节撰写(学习深度之眼课程笔记,侵删)
  19. aws,bitnami建站过程
  20. sql 2008 数据库每天增量备份,每周完整备份

热门文章

  1. python多进程优化_『Python』多进程处理
  2. java调用天气预报api_java调用中国天气网api获得天气预报信息
  3. 网站付费免费推广你更中意哪一个?
  4. 科大奥锐思考题_科大奥锐光电效应测普朗克常数
  5. python 作用域 前缀_TENSORFLOW变量作用域(VARIABLE SCOPE)
  6. 网元——就是网络中的元素,网络中的设备。总之,网元是网络管理中可以监视和管理的最小单位...
  7. ES JVM使用如果超过75%就会GC较多,导致ES索引性能下降
  8. pandas dataframe 做机器学习训练数据=》直接使用iloc或者as_matrix即可
  9. 量子计算的基本原理——本质上是在操作薛定谔的猫(同时去运算和操作死+不死两种状态)...
  10. mysql 查询 插入