Android JNI程式設計(七)——使用AndroidStudio編寫第一個JNI程式
阿新 • • 發佈:2019-02-10
1.簡單介紹一下NDK和JNI
- NDK:NDK是Native Development Kit的縮寫,是Google提供的一套工具集,可以讓你其他語言(C、C++或彙編)開發 Android的 JNI。NDK可以編譯多平臺的so,開發人員只需要簡單修改 mk 檔案說明需要的平臺,不需要改動任何程式碼,NDK就可以幫你編譯出所需的so庫。
- JNI:JNI是Java Native Interface的縮寫,它提供了若干的API實現了Java和其他語言的通訊(主要是C&C++)
NDK網盤下載地址
2.開啟Android Studio配置ndk路徑(或者下載ndk)
3.建立一個類並定義兩個native
方法如下圖:
4.使用javac命令將HelloWorld.java
進行編譯,然後使用javah -jni命令編譯獲取jni所需要的標頭檔案
進入到檔案所在的位置,執行javac。
這裡需要注意的是,我們需要退後到如下圖目錄執行javah -jni
命令。,命令javah -jni 包名.類名
這裡獲取標頭檔案會有很多坑,如果提示錯誤: 找不到'com.zsy.hellojni.HelloWorld' 的類檔案
。
可以試下這個命令 javah -classpath . -jni 包名.類名。編譯成功沒有遇到坑的話,你就可以在···\src\main\java
目錄下看到一個.h檔案
5.接下來在專案中建立一個jni目錄,並將剛生成的.h檔案剪下至這個目錄
6.我們先來檢視一下這個.h檔案的內容。這裡面用java的概念來說就相當於介面內的抽象方法,需要我們建立.c檔案來實現這些方法同時也就將我們的定義的native方法實現了
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class com_zsy_hellojni_HelloWord */
#ifndef _Included_com_zsy_hellojni_HelloWord
#define _Included_com_zsy_hellojni_HelloWord
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: com_zsy_hellojni_HelloWorld
* Method: helloWorld
* Signature: ()Ljava/lang/String;
* TODO: 返回一個字串
*/
//相當於Interface裡的抽象方法
JNIEXPORT jstring JNICALL Java_com_zsy_hellojni_HelloWorld_helloWorld
(JNIEnv * env, jclass);
/*
* Class: com_zsy_hellojni_HelloWorld
* Method: add
* Signature: (II)I
* TODO: 做一個加法
*/
JNIEXPORT jint JNICALL Java_com_zsy_hellojni_HelloWorld_add
(JNIEnv * env,jclass , jint , jint);
#ifdef __cplusplus
}
#endif
#endif
7.我們在jni目錄下建立一個hello_jni.c
檔案來實現.h檔案中的抽象方法
//自己建立一個c檔案,實現自己定義的native方法,也就是.h檔案中的方法
//引入自己生成的.h標頭檔案
#include <com_zsy_hellojni_HelloWord.h>
//返回一個字串
JNIEXPORT jstring JNICALL Java_com_zsy_hellojni_HelloWorld_helloWorld
(JNIEnv *env, jclass jobj) {
return (*env)->NewStringUTF(env,"HelloWorld 我是用jni調用出來的字串");
}
//返回 a+b的結果
JNIEXPORT jint JNICALL Java_com_zsy_hellojni_HelloWorld_add
(JNIEnv *env, jclass jobj, jint a, jint b){
return a+b;
}
8.接下來我們在build.gradle
中新增ndk配置
defaultConfig {
//...
ndk {
moduleName "Hello"//指定生成的so檔名
abiFilters "armeabi", "armeabi-v7a", "x86"//cpu的型別
}
}
9.將專案rebuild過後我們在./build就能看到生成的so檔案了
10.現在我們就可以在MainActivity中呼叫那兩個native方法了
static {
//名字必須和build.gradle中的moduleName一致
System.loadLibrary("hello");
}
TextView textView = (TextView) findViewById(R.id.tv);
String s = HelloWorld.helloWorld();
int add = HelloWorld.add(3, 66);
textView.setText(s+"\n"+"我是一個加法: "+add);