第1步:在Java中先聲明一個native方法
第2步:編譯Java源文件javac得到.class文件
第3步:通過javah -jni命令導(dǎo)出JNI的.h頭文件
第4步:使用Java需要交互的本地代碼,實現(xiàn)在Java中聲明的Native方法(如果Java需要與C++交互病附,那么就用C++實現(xiàn)Java的Native方法窜觉。)
第5步:將本地代碼編譯成動態(tài)庫(Windows系統(tǒng)下是.dll文件,如果是Linux系統(tǒng)下是.so文件楞艾,如果是Mac系統(tǒng)下是.jnilib)
第6步:通過Java命令執(zhí)行Java程序,最終實現(xiàn)Java調(diào)用本地代碼。
1蔓榄、 在Java中先聲明一個native方法阿浓,以HelloWorld.java類為例 如圖:
2他嚷、編譯Java源文件javac得到.class文件
1> 打開Android studio的Terminal 窗口
2> cd 到HelloWorld類的路徑下。如圖:
3>輸入javac HelloWorld.java 然后回車:會生成一個HelloWorld類的class文件芭毙。(注:如果Android studio的是UTF-8,這個地方會報錯筋蓖,CMD命令行運行java程序的時候,系統(tǒng)默認的編碼格式是gbk退敦,所以需要 用-encoding指令來為文件指定編碼格式粘咖, javac -encoding UTF-8 HelloWorld.java)
3、通過javah -jni命令導(dǎo)出JNI的.h頭文件
1>通過Terminal 命令行 cd 到 Java文件夾的路徑下苛聘。 如圖:
2> 輸入 javah com.santint.demojnitest.HelloWorld(Java文件夾下的包名.類名)回車后 會出現(xiàn)一個.h的文件 如圖:
打開.h文件 內(nèi)容如圖:
3>打開切換到項目的project的模式 涂炎,在main 文件夾下新建一個jin 的文件夾,把上一步生成的.h 文件放到 jni的文件夾下 如圖:
4>在jni文件夾下 新建.c 文件设哗,選中jni文件夾 右鍵-->New-->C/C++ Source File 會彈出窗口 name :填入HelloWorld唱捣。 type:選擇.c 默認是.cpp
5>把代碼復(fù)制到 .c 文件中
#include "com_santint_demojnitest_HelloWorld.h"
#ifdef __cplusplus
extern "C"
{
#endif
/*
* Class: com_santint_demojnitest_HelloWorld
* Method: sayHello
* Signature: (Ljava/lang/String;)Ljava/lang/String;
*/
JNIEXPORT jstring JNICALL Java_com_santint_demojnitest_HelloWorld_sayHello(
JNIEnv *env, jclass cls, jstring j_str)
{
const char *c_str = NULL;
char buff[128] = { 0 };
c_str = (*env)->GetStringUTFChars(env, j_str, NULL);
if (c_str == NULL)
{
printf("out of memory.\n");
return NULL;
}
printf("Java Str:%s\n", c_str);
sprintf(buff, "hello %s", c_str);
(*env)->ReleaseStringUTFChars(env, j_str, c_str);
return (*env)->NewStringUTF(env, buff);
}
#ifdef __cplusplus
}
#endif
注意:
6>創(chuàng)建.mk 文件 如圖:
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := HelloWorld
LOCAL_SRC_FILES := HelloWorld.c //.c文件
include $(BUILD_SHARED_LIBRARY)
第4步:使用Java需要交互的本地代碼,實現(xiàn)在Java中聲明的Native方法(如果Java需要與C++交互网梢,那么就用C++實現(xiàn)Java的Native方法震缭。)
1>在HelloWorld類中添加 加載.so 的方法 例如:
static {
System.loadLibrary("HelloWorld");
}
第5步:將本地代碼編譯成動態(tài)庫(Windows系統(tǒng)下是.dll文件,如果是Linux系統(tǒng)下是.so文件战虏,如果是Mac系統(tǒng)下是.jnilib)
1>在build.gradle文件下添加如下配置
android {
compileSdkVersion 30
buildToolsVersion "30.0.0"
defaultConfig {
...
ndk{
moduleName 'HelloWorld'
abiFilters "armeabi-v7a", "arm64-v8a", "x86","x86_64"
}
}
buildTypes {
...
externalNativeBuild {
ndkBuild {
path 'F:\\AndroidProject\\DemoJniTest\\app\\src\\main\\jin\\Android.mk'
}
}
sourceSets.main {
jni.srcDirs = []
jniLibs.srcDirs = ['src/main/jniLibs']
}
}
}
2> 配置完成后 Sync Now 一下拣宰,然后在Rebuild Project一下就可以了 .so 文件會在F:\AndroidProject\DemoJniTest\app\build\intermediates\ndkBuild\debug\obj\local 文件夾下出現(xiàn) 如圖:
7党涕、運行結(jié)果 如下:
為什么會多了個hello 呢,那是因為我們在寫.c文件里的代碼時拼接了一個hello .c文件的代碼如下:
第二中方式是Android studio 自動幫我們創(chuàng)建 需要下載CMake
下載方法如圖:找到 SDK manger——>SDK Tools——>CMake 點擊ok 下載
然后我們創(chuàng)建項目時 選擇 C++ 的模板 例如:
完成后 Android studio 會制動幫我們配置所需要的文件巡社。 .so 文件也已經(jīng)生成好了 如圖:
另外一種方式生成.so 文件
1> 首先在系統(tǒng)變量 的path 路徑下配置一下自己的ndk-build的路徑
下圖 是我的ndk-build 的路徑配置
2>Win+R 打開cmd的命令行窗口 cd到創(chuàng)建的Jni文件夾的全路徑
例如:F:\AndroidProject\JNIProject\app\src\main\jni
回車后 就會在jni文件夾在生成一個libs的文件夾 和obj文件夾以及.so 文件