簡介
Java Jni--Java Native Interface(Java本地接口),Jni是為了方便Java調(diào)用C瘦棋、C++等本地代碼所封裝的一層接口。
NDK--Android提供的一個(gè)工具集合趟妥,通過Ndk可以在Android中更加方便的通過JNI來訪問本地代碼脱柱,比如C、C++酸舍。
在開發(fā)之前需要配置的地方
● 下載NDK工具帅韧,地址:http://www.androiddevtools.cn/,下載完成之后配置啃勉。
● gradle.properties文件末尾添加 android.useDeprecatedNdk=true
● 在build.gradle文件的defaultConfig內(nèi)添加
? ? ? ? ?ndk {? ? ?
? ? ? ? ? ? ? moduleName "encryptMD5"http://生成的so名字
? ? ? ? ? ? ? ?abiFilters "armeabi","armeabi-v7a","x86"http://輸出指定三種abi體系結(jié)構(gòu)下的so庫
? ? ? ? ? }
JNI開發(fā)流程(windows環(huán)境忽舟,Android studio NDK工具)
1、聲明native方法
? ? ? ?創(chuàng)建一個(gè)類JniUtils淮阐,實(shí)現(xiàn)native方法(加密流程:傳入String型參數(shù)通過C的md5算法獲取加密后的值)叮阅,代碼如下:
public class JniUtils{
? ? ? ? ? ?public static native String encryptMD5(String str);
}
2、編譯Java源文件得到class文件泣特,再通過javah命令到處JNI的頭文件
? ? ? ?在Android Studio中直接Clean Project或者Rebuild Project就可以獲取class文件了浩姥,Clean Project完成后,就可以看到class文件了状您。
? ? ? 然后再打開Android Studio Terminal輸入指令:
? ? ? ? cd app/build/intermediates/classes/debug
? ? ? 然后再輸入指令:
? ? ? ? javah -jni com.panda.ndkdemo.JniUtils ? ?
這時(shí)再打開classes/debug目錄時(shí)勒叠,這里生成了一個(gè)com_panda_ndkdemo_JniUtils.h的頭文件:
extern "C" {
#endif
/*
* Class:? ? com_panda_ndkdemo_JniUtils
* Method:? ? getInfoMD5
* Signature: (Ljava/lang/String;)Ljava/lang/String;
*/
JNIEXPORT jstring JNICALL Java_com_panda_ndkdemo_JniUtils_encryptMD5
(JNIEnv *, jclass, jstring);
#ifdef __cplusplus
}
#endif
#endif
3兜挨、代碼說明:
函數(shù)名的格式規(guī)則 : ? Java_包名_類名_方法名
例如? JNIEXPORT jstring JNICALL Java_com_panda_ndkdemo_JniUtils_encryptMD5(JNIEnv *, jclass, jstring);
com_panda_ndkdemo——包名;
JniUtils——類名眯分;
encryptMD5——方法名拌汇;
jstring——encryptMD5方法的String類型的參數(shù);
JNIEnv*——表示一個(gè)指向JNI環(huán)境的指針弊决,通過它來訪問JNI提供的接口方法噪舀;
JNIEXPORT和JNICALL——JNI中所定義的宏,可以在jni.h這個(gè)頭文件中找到飘诗;
4与倡、實(shí)現(xiàn)JNI方法:
jni方法是指Java中聲明的native方法,在生成com_panda_ndkdemo_JniUtils.h頭文件后疚察,通過c或者c++來實(shí)現(xiàn)jni方法。
在src/main下新建文件夾jni,把生成的.h文件剪切到j(luò)ni文件夾下面去仇奶,新建一個(gè)c類隨便取一個(gè)名字貌嫡,添加代碼如下
#include "com_panda_ndkdemo_JniUtils.h"
#include <stdio.h>
* Class:? ? Java_com_panda_ndkdemo_JniUtils
* Method:? ? encryptMD5
* Signature: ()Ljava/lang/String;
*/JNIEXPORT? jstring? JNICALL Java_com_panda_ndkdemo_JniUtils_encryptMD5(JNIEnv *env, jobject obj){
? ? ? ?//這里省略掉MD5的一些算法調(diào)用代碼
? ? ? //具體的c語言的 MD5算法網(wǎng)上有很多 這里就不貼出咯O(∩_∩)O!
? ? ? return(*env)->NewStringUTF(env," ? c返回的值 ? ");
}
然后編譯再重新build項(xiàng)目该溯,再去app->intermediates-ndk-debug發(fā)現(xiàn)生成了三個(gè)文件夾岛抄,并且對(duì)應(yīng)了之前在build.gradle配置的abiFilters,里面生成了對(duì)應(yīng)的so包狈茉。
在JniUtils類添加如下代碼
static{? ? ??
? ? ? System.loadLibrary("encryptMD5");//必須和在build.gradle里面設(shè)置的so名字一致
}
然后在最后調(diào)用的地方直接JniUtils.encryptMD5("");就行了
ps:如果so給其他工程調(diào)用 那么調(diào)用encryptMD5方法的包名路徑和類名必須和so庫一致