本地接口JNI的使用總結
1、簡介
JNI是Java Native Interface的簡寫,即為Java語言的本地接口,它允許我們在Java代碼中去使用其他語言的功能,比如:C、C++及匯編語言等。
一般,在Android當中,我們會把某些敏感或是核心的功能放在C/C++中實現,因為Java或Android的安全性不是很好,容易被反編譯或是破解,而用C/C++實現的話,安全性好,並且C/C++是運行在底層的,好處可想而知。
2、使用
對於JNI的使用比較簡單,分為以下幾步:
A、新建一個Android項目
B、創建本地接口
C、創建對應本地接口的頭文件和源文件
D、使用工具ndk-build編譯生成.so庫文件
E、將生成的.so文件放入到項目的libs/armeabi使用
下面就按照上面的步驟一步步進行,以在屏幕上顯示HelloJni來演示JNI的使用流程:
A、新建項目
我的項目目錄如下:
B、新建本地的接口文件(JNIService)
內容如下:
/*
* JNI的本地方法
*/
public class JNIService {
static {
System.loadLibrary(“hello_jni”);
}
public static native String getString();// 獲取字符串
}
C、創建本地接口對應的C/C++文件
頭文件:
我們可以使用jdk的命令工具javah來生成需要的頭文件,當然,也可以自行編寫頭文件(這需要你對C比較熟悉)。
具體如下:
首先,運行新建接口的項目,此時會在項目的bin目錄下生成對應的.class文件,我們隻需要對定義瞭本地接口的類進行編譯生成頭文件即可,具體如下:
切換到項目的目錄下,執行命令:javah -classpath bin/classes -d jni com.demo.hellojni.JNIService,這裡我們新建瞭一個目錄jni來存放生成的頭文件,我的目錄如下所示:
接下來,就是編寫源文件瞭,這裡我們使用Visual studio 來編寫C文件,上面的頭文件內容如下:
/* DO NOT EDIT THIS FILE – it is machine generated */
#include
/* Header for class com_demo_hellojni_JNIService */
#ifndef _Included_com_demo_hellojni_JNIService
#define _Included_com_demo_hellojni_JNIService
#ifdef __cplusplusvcD4KPHA+ZXh0ZXJuIA==”C” {
#endif
/*
* Class: com_demo_hellojni_JNIService
* Method: getString
* Signature: ()Ljava/lang/String;
*/
JNIEXPORT jstring JNICALL Java_com_demo_hellojni_JNIService_getString
(JNIEnv *, jclass);
#ifdef __cplusplus
}
#endif
#endif
下面我們編寫對應的源文件JNIService.c,這個文件的編寫需要參照頭文件的規范,具體如下:
#include
JNIEXPORT jstring JNICALL Java_com_demo_hellojni_JNIService_getString(JNIEnv * env, jobject obj)
{
return (*env)->NewStringUTF(env,”HELLO NDK!”);
}
好瞭,頭文件和源文件都編寫完成,接下來我們需要再編寫一個Android.mk文件來,內容如下:
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := hello_jni
LOCAL_SRC_FILES := JNIService.c
include $(BUILD_SHARED_LIBRARY)
接下來,我們將上面的頭文件、源文件及Android.mk文件放到JNI。
D、編譯生成的文件
這裡使用瞭ndk來編譯資源文件,所以需要先安裝和配置NDK,另外我們需要第三方軟件(這裡我使用Cygwin協助編譯),具體可參考博客:
https://blog.csdn.net/jiangwei0910410003/article/details/17710243
打開Cygin軟件,定位到上面的jni目錄,我的目錄:
執行命令:$NDK/ndk_build進行編譯,執行結果如下:
編譯成功後,會生成兩個文件目錄,分別為libs和obj,這裡我們隻需要關註libs即可。具體如下:
到這裡,我們需要已久的.so文件就可以使用瞭,將這個.so文件放到項目目錄的libs/armeabi(如果沒有 則新建這個目錄,隻有在這個目錄下的so文件才會被加載)。
最後,就是怎樣調用這個JNI瞭,具體如下:
public class HelloJNIActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_hello_jni);
}
public void helloJNIShow(View v) {
String helloJNI = JNIService.getString();
Toast.makeText(this, helloJNI, Toast.LENGTH_SHORT).show();
}
}
這樣就可以運行我們的項目,當我們點擊歡迎語的時候,就是顯示C/C++返回的信息提示瞭,效果圖如下:
/*
* Android技術交流群號:179914858
* 歡迎加入
*/