終於建了一個自己個人小站:https://huangtianyu.gitee.io,以後優先更新小站博客,歡迎進站,O(∩_∩)O~~
JNI全稱 Java Native Interface , java本地化接口。即JNI是定義了一系列接口,所有實現該接口的JVM虛擬機都可以通過該接口實現Java和C/C++的混合編程。java和C/C++不同 , 它不會直接編譯成平臺機器碼,而是編譯成虛擬機可以運行的java字節碼的.class文件,通過JIT技術即時編譯成本地機器碼,所以有效率就比不上C/C++代碼,JNI技術就解決了這一痛點,實現Java調用C/C++代碼。
1. Eclipse NDK開發環境搭建
在開發NDK之前,Java的SDK,Android的NDK,以及Eclipse的ADT工具都需要大家先安裝好,在SDK早期版本中沒有ndk相關文件,當最近的AndroidSDK中包含了ndk相關文件,所以下載NDK工具的麻煩事這裏就沒有了。唯一要注意的是需要配置下NDK的環境變量。這樣可以方便進行編譯。AndroidSDK主要文件夾參考如下:
這裏講Eclipse的配置就將下如何添加External Tool來快速生成.h文件以及快速進行ndk_build編譯。
1.1 配置快速生成.h頭文件的命令
- 點擊Eclipse上面的圖標,打開External Tool Configurations。
- 然後打開如下界面,在如下界面中雙擊Program,在底下會生成一個New_configuration。
然後按照圖片上面的格式填寫相應的參數。
Location填寫javah.exe的位置:C:\Program Files\Java\jdk1.8.0_91\bin\javah.exe
Working Directory填寫當前的工作目錄:${workspace_loc:/MyTest/src}
Arguments填寫相應的參數:
-classpath ${workspace_loc:/MyTest/src/bin/classes} -d ${workspace_loc:/MyTest/jni} -jni com.scu.MyNDK
之後在External Tool的地方就會生成一個JavaH的命令工具,點擊即可生成對應的.h頭文件了。這裏要注意的是生成都文件前要先編譯出.class文件。
其實這個和用javah.exe命令是一樣的,具體命令如下:
2. Android Studio的配置
AS太強大了,所有你想要的只需要簡單的添加一個依賴,AS就會自動幫你下載,完全不用你去下載。最新的Android Studio在新建工程的時候,選中Include C++ Support後,即可進行NDK開發,這裏注意下在AS中的編譯換成了CMake工具,這個工具配置上稍微和Android.mk有些許不同。其配置文件在新建工程的CMakeLists.txt裏面配置。
在build.gradle裏面也會自動配置cmake工具,配置如下:
externalNativeBuild {
cmake {
path "CMakeLists.txt"
}
}
3. 基本代碼結構
利用AS創建工程後,工程會自動生成如下代碼:
package zqc.com.example;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
// Used to load the 'native-lib' library on application startup.
static {
System.loadLibrary("native-lib");
}
/**
* A native method that is implemented by the 'native-lib' native library,
* which is packaged with this application.
*/
public native String stringFromJNI();
}
其中在static靜態代碼塊中會加載動態鏈接庫。在一個方法前加上native關鍵字即表明該方法是一個jni方法,因而只有聲明,沒有實現,其具體實現在c/c++代碼中。
找到cpp文件,打開後內容如下:
#include <jni.h>
#include <string>
extern "C"
JNIEXPORT jstring
JNICALL
Java_zqc_com_example_MainActivity_stringFromJNI(
JNIEnv *env, jobject /* this */) {
std::string hello = "Hello from C++";
return env->NewStringUTF(hello.c_str());
}
其中extern “C”表示在編譯的時候導出爲c語言的格式,JNIEXPORT表示該函數是可以導出的,可以由外部方法進行調用,這和dll類似,jstring表示返回值,JNICALL關鍵字表示這是一個jni方法,Java_zqc_com_example_MainActivity_stringFromJNI其中Java是固定格式,zqc_com_example_MainActivity是全類名,stringFromJNI是具體的方法名,具體參數:JNIEnv env爲env指針,調用jni的很多方法都需要該指針,jobject / this */這個表示當前類的this指針,這裏因爲沒用到就沒有命名。
在以往開發中可能是把.h和.cpp分開了,這個是AS自動生成的,這裏並沒有單獨生成.h文件。c/c++開發也有自己的結構,這裏除了需要對外暴露接口的需要按照上面格式編寫外,其他的都可以用古老的c/c++進行編寫並遵循古老的結構。你可以先定義.h文件,然後在.cpp裏面具體實現。
點擊Build->Make Project(快捷鍵Ctrl+F9)即可生成動態鏈接庫文件.so,其路徑在:
AS自動生成了Debug版和Release版,並且在各個版本中又生成了不同平臺的.so文件。只能說這個AS太牛叉了~
之後運行工程,安裝到手機上時就把對應的so也拷貝到了手機中了。
總結
目前應該是絕大多數人都採用AndroidStudio進行開發,谷歌官方已經不再對Eclipse的ADT進行維護了。而AS是絕對強大的工具,當你選擇Include C++ Support的時候,AS會將NDK開發的一切都下載下來。所以如果採用AS開發,那麼你學NDK開發的話,只需要把Android開發需要安裝的JDK,SDK,AS等工具安裝好後,即可進行開發。這個系列教程我也採用AS進行講解。