Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> Android中關於JNI 的學習(零)簡單的例子,簡單地入門

Android中關於JNI 的學習(零)簡單的例子,簡單地入門

編輯:關於Android編程

Android中JNI的作用,就是讓Java能夠去調用由C/C++實現的代碼,為了實現這個功能,需要用到Anrdoid提供的NDK工具包,在這裡不講如何配置了,好麻煩,配置了好久。。。

本質上,Java去調用C/C++的代碼其實就是去調用C/C++提供的方法,所以,第一步,我們要創建一個類,並且定義一個Native方法,如下:

JniTest類:

public class JniTest {

	public native String getTestString();
}

可以看到,在這個方法的前面,用到了native關鍵字。

接著,我們要在命令行中編譯這個java文件,得到一個class文件,如下:

\

然後我們可以利用javah命令文件,生成一個C的頭文件,其實javah這一步不是必需的,因為創建這個頭文件,只是為了方便我們復制這個Jni中對應的方法名稱,因為這些名稱實在太復雜了。

在這裡有一點要注意,javah命令要在包的根目錄下調用,對應的類文件,必須是完整的類名,如上圖所示,會先回到src目錄,再調用javah命令。<喎?/kf/ware/vc/" target="_blank" class="keylink">vcD4KPHA+1eLR+c7Sw8e+zbvh1NpzcmPOxLz+vNDPwtTasvrJ+tK7uPbNt87EvP6jrMjnz8LNvMv5yr6jujwvcD4KPHA+PGltZyBzcmM9"/uploadfile/Collfiles/20140507/20140507091155272.png" alt="\">

我們可以看到其名稱是com_lms_jni_JniTest.h,其實就是包名+類名,我們可以看看裡面的內容:

/* DO NOT EDIT THIS FILE - it is machine generated */
#include 
/* Header for class com_lms_jni_JniTest */

#ifndef _Included_com_lms_jni_JniTest
#define _Included_com_lms_jni_JniTest
#ifdef __cplusplus
extern "C" {
#endif
/*
 * Class:     com_lms_jni_JniTest
 * Method:    getTestString
 * Signature: ()Ljava/lang/String;
 */
JNIEXPORT jstring JNICALL Java_com_lms_jni_JniTest_getTestString
  (JNIEnv *, jobject);

#ifdef __cplusplus
}
#endif
#endif

我們可以看到,在這裡面有一個方法,名稱是Java_com_lms_jni_JniTest_getTestString,夠復雜吧,其實如果我們知道這個名稱規則,並且知道如何去實現這樣一個方法的話,我們是完全可以不生成這個頭文件的,我們可以直接寫出對應的C文件。

接下來,在jni文件中創建一個對應的C文件,名稱是值得並無所謂,但為了統一,我們就把它叫JniTest.c吧,如下:

\

在這裡,我們也把com_lms_jni_JniTest.h也放到這裡了,這個其實是沒關系的,只是為了內容的協調和統一而已,一般情況下,我們會把所以由C/C++實現的文件都放在項目目錄下一個叫 jni 的文件夾下面。

下面是在JniTest.c中實現native方法,getTestString,如下:

#include 
#include 
#include 

JNIEXPORT jstring JNICALL Java_com_lms_jni_JniTest_getTestString
  (JNIEnv *e, jobject obj){
	return (**e).NewStringUTF(e,"Hello from JniTest Function");
}

在這個c文件中,我們看到,並沒有引用頭文件com_lms_jni_JniTest.h,而只是引用了一般的C/C++庫文件,比如stido.h和stdlib.h文件等,在這裡注意到一點,我們還會引用jni.h文件,jni.h文件是JNI編程中很重要的一個頭文件,關於Java中的數據類型跟jni中的數據類型的對應全部是在這個文件中定義的,後續會來看一下這個jni.h文件。

在上面JniTest.c文件中實現了方法之後,關於C/C++這邊的實現其實也就實現了,那麼接下來就是要將這個C文件編譯成so文件由Android來調用。

為什麼是so文件呢,這是因為Android本質上就是一個linux系統,所以其調用的JNI庫文件,都是so形式。

Android提供的NDK庫提供了ndk-build的命令來實現這個編譯過程,但在此之前,我們要先創建一個Android.mk文件,這是一個簡單的小小的Make文件,其內容如下:

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)

LOCAL_MODULE := com_lms_jni_HwDemo
LOCAL_SRC_FILES := \
HwDemo.c \
JniTest.c \

include $(BUILD_SHARED_LIBRARY)

在這裡,我們會定義幾個變量:

LOCAL_PATH:其值是call my-dir,而my-dir是個宏函數,會返回Android.mk所在的路徑,在這裡,就是jni文件夾。

include $(CLEAR_VARS),這個命令會清除掉所有LOCAL開頭的變量,比如LOCAL_MODULE之類的,但有一個例外,就是其上面的LOCAL_PATH 。

LOCAL_MODULE:要生成的so包名,也是Android中Java代碼加載時的名稱。

LOCAL_SRC_FILES:要進行編譯的源文件,如在這裡,有HwDemo.c和JniTest.c等。

include $(BUILD_SHARED_LIBRARY):表明生成一個動態鏈接庫。

定義後這樣一個Android.mk文件之後,在命令行中調用ndk-build命令,如下:

\

命令實行之後,我們可以在項目目錄下看到libs中多了一個so庫,如下:

\

到這裡,關於Jni實現的就結束了,接下來就是如何在Android中使用這個本地方法了。

我們創建了一個Activity,在它裡面只放置一個TextView控件,它的布局如下:




    


然後在Activity中,我們要加載這個so庫,如下:

public class HwDemo extends Activity {

	static {
		System.loadLibrary("com_lms_jni_HwDemo");//加載so庫
	}
	
	public native String printHello();	

	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);		
		setContentView(R.layout.main);
		TextView tv = (TextView)findViewById(R.id.tvJni);
		JniTest jniTest = new JniTest();//調用JniTest文件的方法
		tv.setText(jniTest.getTestString());
	}

}

1)利用static靜態代碼塊,加載so庫文件,可以看到在這裡,這個名稱就是Anrdoid.mk中定義的LOCAL_MODULE值。

2)創建JniTest對象,調用其getTestString()方法,最終顯示結果如下:


到這裡,通過一個簡單的例子,我們明白了如何在Android中利用JNI來調用C/C++的方法了。

最後,我們總結一下這幾個步驟:

1)創建Java類文件,並定義Native方法,如JniTest類。

2)利用javac生成class文件,然後回到src目錄,利用javah生成C/C++頭文件,在這裡要注意,javah命令要在包的根目錄下調用,對應的類文件,必須是完整的類名,如下:

在Src目錄:javah com.lms.jni.JniTest,在上面的截圖,也可以看到javac之後,是回到src目錄,再調用javah。

3)編寫對應的C文件,如JniTest.c,在裡面實現C/C++的方法,記得要放在jni文件夾下面。

4)編寫Android.mk文件,利用ndk-build命令生成so文件。

5)在Android中利用static靜態代碼塊,調用system.loadLibrary方法來加載so庫文件。

6)在Java邏輯中調用之前定義的JniTest類的方法。

結束。源代碼下載!

  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved