最近在了解公司历史的发展, 发现了公司产品中几乎都要使用 so 文件, 不禁好奇这个 so 到底是何方神圣.
so 文件
so 是 shared object 的缩写, 见名思义就是共享的对象, 机器可以直接运行的二进制代码. so 主要存在于 Unix 和 Linux 系统中.[参考: 安卓 so 文件是什么, 又是如何开发出来的呢? ] https://www.imooc.com/article/72564
它是 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/2017/12/23/hal-jni/
既然知道了 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 基础] https://www.jianshu.com/p/87ce6f565d37
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 入门指南] https://developer.android.google.cn/ndk/guides
通过 Android Studio 编译之后就可以生成 .so 文件, 之后就可以愉快的将 .so 文件集成到项目中了.
总结
我们首要目的就是要了解. so 文件的作用是用来访问系统底层的硬件接口, 而 Android 应用基本都是 Java 开发, 而 Java 不支持直接访问硬件, 但是 Android 提供了两种方式去访问硬件接口: JNI 和硬件访问服务. JNI 的方式编译后会产生. so 文件. 同时 Android 还给开发者提供了 NDK 这个开发工具包, 开发者可以使用 NDK 快速实现 JNI 的功能.
来源: https://www.cnblogs.com/gdragon/p/11746732.html