將 so|JNI|NDK 之間的關係說明白

最近在瞭解公司歷史的發展,發現了公司產品中幾乎都要使用 so 文件,不禁好奇這個 so 到底是何方神聖。

so 文件

soshared object 的縮寫,見名思義就是共享的對象,機器可以直接運行的二進制代碼。so 主要存在於 UnixLinux 系統中。【參考:安卓so文件是什麼,又是如何開發出來的呢? 】
它是 c/c++ 實現的功能函數集合,並對外提供標準的接口,外層可以通過這個接口調用c/c++的代碼。在 Android 系統上普遍用於調用系統的硬件接口。

那麼,Android 系統爲什麼要使用.so文件呢?

Android 系統應用基本都是基於 Java 語言開發,而Java語言是不能直接訪問Android系統底層的硬件接口。而Android系統中可以通過 JNI硬件訪問服務去訪問系統底層的硬件接口。比如:開啓藍牙、關閉藍牙等

這裏還有一個問題:爲什麼 Java不能直接訪問Android系統底層的硬件呢?

  1. Java語言是跨平臺的。【個人想法】:跨平臺就會導致最後使用的平臺是不確定的,因此要訪問的底層硬件接口也是不確定的。
  2. Android 是基於 Linux 系統,而有些Linux系統調用是不支持Java的,比如ioctl,只能C/C++才能調用。【參考:Android硬件訪問服務(一)
    “使用JNI直接操作硬件”】

既然知道了Android系統中可以通過 JNI硬件訪問服務去訪問系統底層的硬件接口。
那麼先來了解一下什麼是JNI

JNI

定義:Java Native Interface,即 Java本地接口
作用: 使得Java 與 本地其他類型語言(如C、C++)交互
即在 Java代碼 裏調用 C、C++等語言的代碼 或 C、C++代碼調用 Java 代碼

特別注意:

  • JNIJava 調用 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的功能。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章