最近在了解公司历史的发展,发现了公司产品中几乎都要使用 so
文件,不禁好奇这个 so
到底是何方神圣。
so
是 shared object
的缩写,见名思义就是共享的对象,机器可以直接运行的二进制代码。 so
主要存在于 Unix
和 Linux
系统中。 【参考:安卓so文件是什么,又是如何开发出来的呢? 】
它是 c/c++
实现的功能函数集合,并对外提供标准的接口,外层可以通过这个接口调用 c/c++
的代码。在 Android
系统上普遍用于调用系统的硬件接口。
那么, Android
系统为什么要使用 .so
文件呢?
Android
系统应用基本都是基于 Java
语言开发,而 Java
语言是不能直接访问 Android
系统底层的硬件接口。而 Android
系统中可以通过 JNI
和 硬件访问服务
去访问系统底层的硬件接口。比如:开启蓝牙、关闭蓝牙等
这里还有一个问题:为什么 Java
不能直接访问 Android
系统底层的硬件呢?
Java
语言是跨平台的。【个人想法】:跨平台就会导致最后使用的平台是不确定的,因此要访问的底层硬件接口也是不确定的。 Android
是基于 Linux
系统,而有些 Linux
系统调用是不支持 Java
的,比如 ioctl
,只能 C/C++
才能调用。 【参考:Android硬件访问服务(一)
"使用JNI直接操作硬件"】
既然知道了 Android
系统中可以通过 JNI
和 硬件访问服务
去访问系统底层的硬件接口。
那么先来了解一下什么是 JNI
吧
定义: Java Native Interface
,即 Java
本地接口
作用: 使得Java 与 本地其他类型语言(如 C、C++
)交互
即在 Java
代码 里调用 C、C++
等语言的代码 或 C、C++
代码调用 Java
代码
特别注意:
JNI
是 Java
调用 Native
语言的一种特性 JNI
是属于 Java
的,与 Android
无直接关系 【以上内容参考:Android JNI】
JNI
代码经过编译之后在 Unix/Linux
系统上就会生成 .so
文件,通过调用 Java
代码调用 .so
中的接口方法即可实现硬件的访问。
JNI
相关的内容还是比较复杂的,可以自行搜索了解,这里只是简单介绍。
可以参考这两篇系列 【JNI详解---从不懂到理解 】 , 【Android JNI(一)——NDK与JNI基础】
JNI
方式去访问硬件有一个弊端,就是只能一个应用调用一个硬件接口,而多个应用去调用该硬件接口就会出现冲突,那么 硬件访问服务
的方式就是解决 JNI
的弊端。
硬件访问服务
的定义如下:
访问硬件资源的程序只能并且只有一个,我们称之为 System Server
, 其它要访问这个硬件资源的 APP
必须要给 Server
发请求,由 Server
间接的操作硬件,从而实现资源的访问。这个就称之为硬件访问服务。 【参考:Android访问硬件的方法】
更多 硬件访问服务的资料
:
【Android硬件访问服务-Service】
【Android驱动(一)硬件访问服务学习之(二)Android通过硬件访问服务访问硬件】 在 Android
系统下 JNI
可以通过 NDK
快速实现。那么 NDK
又是什么呢?
NDK
全称: Native Develop Kit
,是 Android
的一个工具开发包 NDK
是属于 Android
的,与 Java
并无直接关系.
使用教程 【NDK 入门指南】
通过 Android Studio
编译之后就可以生成 .so
文件,之后就可以愉快的将 .so
文件集成到项目中了。
我们首要目的就是要了解 .so
文件的作用是用来访问系统底层的硬件接口,而 Android
应用基本都是 Java
开发,而 Java
不支持直接访问硬件,但是 Android
提供了两种方式去访问硬件接口: JNI
和 硬件访问服务
。 JNI
的方式编译后会产生 .so
文件。同时 Android
还给开发者提供了 NDK
这个开发工具包,开发者可以使用 NDK
快速实现 JNI
的功能。