2025-04-30

本地接口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

* 歡迎加入

*/

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *