最近在了解公司历史的发展,发现了公司产品中几乎都要使用
so
文件,不禁好奇这个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 直接操作硬件 ”】](https://jason–liu.github.io/…
既然知道了 Android
系统中可以通过 JNI
和 硬件访问服务
去访问系统底层的硬件接口。
那么先来了解一下什么是 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
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
的功能。