Android JNI开发一:jni、ndk、so理论知识详解

静态库和动态库

静态库就是写代码时引入的lib,你在编写代码时会引用lib中的代码。你的代码编译时,会将lib中的代码一起编译成二进制文件。

动态库则是已经编译好的二进制文件,你在编写代码时无法引用动态库中的代码,因为它已经编译成二进制文件了,同理你的代码编译时也不会编译动态库。你的程序编译好、运行时才会调用动态库中的功能。

JNI

JNI是java native interface的简称,即java本地接口。

从Java1.1开始,JNI标准成为java平台的一部分,它允许Java代码和其他语言写的代码进行交互。

java与其它语言交互,为什么称为native呢,因为java代码不能直接调用其它语言,其它语言必须编译成本系统对应的二进制文件——即动态链接库,才能被java调用。而一旦编译成本系统对应的二进制文件,就只能在本系统使用,不能跨平台的,所以称为native。

JNI为java编写程序提供了很多好处,比如,可以使用一些其它语言编写库、可以与硬件驱动/操作系统进行交互、可以提高程序的性能。

NDK

NDK是native develop kit的缩写,即(Android)本地开发工具。

android开发基本都是使用java语言,使用非java语言编写的库,无法直接被调用,通过JNI特性,可以将这些库编译成动态库,以供java调用。

那么,如何编译成android平台动态库呢?

大部分时候我们都是要使用C/C++编写的库,我们想要编译这些C/C++代码,还需要掌握一定的GCC知识,还要学习很多编译中的配置命令。。。。

ndk这个工具,就是解决这些麻烦步骤的,只需要一行命令、一些简单的配置,就可以将各种语言编写的库编译成我们想要的so文件。

Android平台so库

ABI和CPU架构

ABI是Application Binary Interface,即应用程序二进制接口,定义了二进制文件(so文件)如何运行在相应的系统平台上,从使用的指令集,内存对齐到可用的系统函数库。

Android系统目前支持七种不同的CPU架构,每一种都对应一个相应的ABI,对应关系如下:
ARMv5 - armeabi
ARMv7 - armeabi-v7a
ARMv8 - arm64-v8a
X86 - x86
X86_64 - x86_64
MIPS - mips
MIPS64 - mips64

ABI兼容

虽然CPU架构和ABI有匹配关系,但是很多设备都可以兼容其它ABI的so库,兼容关系大致如下:
ARMv5设备只兼容armeabi
ARMv7设备兼容armeabi-v7a和armeabi
ARMv8设备兼容arm64-v8a、armeabi-v7a和armeabi
X86设备兼容x86和armeabi
X86_64设备兼容x86_64、x86和armeabi
MIPS设备只兼容mips
MIPS64设备兼容mips64和mips

app安装时,会根据当前设备的cpu架构,选择对应ABI目录下的so进行安装。首先会选择对应ABI目录下的so文件安装,如果没有对应的ABI目录,则会选择兼容的ABI目录。app安装后,so文件解压在data/app/com.example.test/lib/ABI/目录下,程序运行时,会去这个目录下找对应的so文件调用。

虽然x86和arm设备都支持armeabi,但在64位平台上运行32位版本的ART和Android组件,将丢失专为64位优化过的性能(ART,webview,media等等)。

减小apk大小方案

为了减小apk大小,有3种方式来减少so文件的大小:

1.多渠道打包,生成7种cpu架构的apk,这种方式在google play商店中是支持的,但是国内市场不支持;

2.先打包基本armeabi库,动态下载该设备匹配的so文件,放入app安装目录/lib/ABI/目录下;

3.只打包基本的armeabi库(放弃mips设备),找出其中性能差距大的so库,把该so库的其它ABI版本也放入armeabi目录下,取名区分下。在代码中,根据Build.SUPPORTED_ABIS属性,决定load哪个so库。

总结

Android JNI开发中很容易遇到各种各样的坑,而这些坑涉及到的面又广,往往一个问题浪费很长时间去找原因。这篇主要是介绍中遇到的一些理论知识,做个归纳总结,方便开发过程中定位问题,下篇是实战演练。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值