一、什么是NDK
NDK官網介紹
ndk官網.png
NDK 是Native Develop Kit的縮寫,含義是:本地開發。
作用:是Google為了提供給開發者一個在Java中調用C/C++代碼的一個工作。
NDK本身其實就是一個交叉工作鏈,包含了Android上的一些庫文件,然后,NDK為了方便使用,提供了一些腳本,使得更容易的編譯C/C++代碼。
簡單的來說:
Android NDK 就是一套工具集合,允許你使用C/C++語言來實現應用程序的部分功能。
二、為什么使用NDK
原因:
1.使用第三方庫,現在許多第三方庫都是由C/C++庫編寫的,比如ffmpeg。
2.在某些情況下提性能,特別是像游戲這種計算密集型應用。
3.重復使用現在庫,或者提供其自己的庫重復使用。
4.在平臺之間移植其應用。
5.不依賴于Dalvik Java虛擬機的設計。
6.代碼的保護。由于APK的Java層代碼很容易被反編譯,而C/C++庫反編譯難度大。
三、NDK到so的演變
圖片.png
從圖中可知:我們上層通過JNI來調用NDK層,使用這個工具可以很方便的編寫和調試JNI的代碼。
由于c語言的不跨平臺,在Mac系統的下使用NDK編譯在Linux下能執行的函數庫——so文件。其本質就是一堆C、C++的頭文件和實現文件打包成一個庫。
目前Android系統支持以下七種不用的CPU架構,每一種對應著各自的應用程序二進制接口ABI:(Application Binary Interface)定義了二進制文件(尤其是.so文件)如何運行在相應的系統平臺上,從使用的指令集,內存對齊到可用的系統函數庫。對應關系如下:
ARMv5——armeabi
ARMv7 ——armeabi-v7a
ARMv8——arm64- v8a
x86——x86
MIPS ——mips
MIPS64——mips64
x86_64——x86_64
四、JNI
(一)JNI定義
JNI,全稱為Java Native Interface,即Java本地接口,JNI是Java調用Native 語言的一種特性。通過JNI可以使得Java與C/C++機型交互。即可以在Java代碼中調用C/C++等語言的代碼或者在C/C++代碼中調用Java代碼。由于JNI是JVM規范的一部分,因此可以將我們寫的JNI的程序在任何實現了JNI規范的Java虛擬機中運行。同時,這個特性使我們可以復用以前用C/C++寫的大量代碼JNI是一種在Java虛擬機機制下的執行代碼的標準機制。代碼被編寫成匯編程序或者C/C++程序,并組裝為動態庫。也就允許非靜態綁定用法。這提供了一個在Java平臺上調用C/C++的一種途徑,反之亦然。
注:
Java調用C/C++在Java語言里面本來就有的,并非Android自創的,即JNI。
JNI就是Java調用C++的規范。當然,一般的Java程序使用的JNI標準可能和android不一樣,Android的JNI更簡單。
(二)JNI流程
圖片.png
(三)實現步驟
第1步:在Java中先聲明一個native方法
第2步:編譯Java源文件javac得到.class文件
第3步:通過javah -jni命令導出JNI的.h頭文件
第4步:使用Java需要交互的本地代碼,實現在Java中聲明的Native方法(如果Java需要與C++交互,那么 就用C++實現Java的Native方法。)
第5步:將本地代碼編譯成動態庫(Windows系統下是.dll文件,如果是Linux系統下是.so文件,如果是Mac系統下是.jnilib)
第6步:通過Java命令執行Java程序,最終實現Java調用本地代碼。
五、JNI實戰之 “hello world”
(一)環境配置
Android studio 版本
圖片.png
Android studio NDK環境配置
圖片.png
簡單的實現方式一;
1.創建新的工程
2.勾選Include C++ Support復選框
3.Customize C++ Support的自定義項目
圖片.png
C++ Standard:即C++標準,使用下拉列表選擇你希望使用的C++的標準,選擇Toolchain Default 會使用 默認的CMake設置。
Exceptions Support:如果你希望啟用對C++異常處理的支持,請選擇此復選框。如果啟動此復選
框,Android Studio 會將-fexceptions標志添加到模塊級build.gradle文件的cppFlags中,Gradle會
將其傳 遞到 CMake。
Runtime Type Information Support:如果開發者希望支持RTTI,請選中此復選框。如果啟用此復選
框,Android Studio 會將-frtti標志添加到模塊級build.gradle文件的cppFlags中,Gradle會將其傳遞
到CMake。
最后點擊 finish ;
4.Android 目錄
圖片.png
圖片.png
在 cpp 文件夾中:可以找到屬于項目的所有原生源文件等構建庫。對于新項目,Android Studio會創
建一個示例C++源文件 native-lib.cpp,并將其置于應用模塊src/main/cpp/目錄中。這個示例代
碼提供了一個簡單的C++函數stringFromJNI(),此函數可以返回字符串“Hello from C++”。
在 External Build Files 文件夾中:可以找到CMake或 ndk-build 的構建腳本。與build.gradle文件指示
Gradle構建應用一樣,CMake和ndk-build需要一個構建腳本來了解如何構原生庫。對于新項
目,Android Studio 會創建一個CMake 構建腳本CMakeLists.txt,并將其置于模塊根目錄中。
5. 直接運行項目
我們來直接 run一下這個項目,看下結果
圖片.png