編輯:關於Android編程
Android中JNI的作用,就是讓Java能夠去調用由C/C++實現的代碼,為了實現這個功能,需要用到Anrdoid提供的NDK工具包,在這裡不講如何配置了,好麻煩,配置了好久。。。
本質上,Java去調用C/C++的代碼其實就是去調用C/C++提供的方法,所以,第一步,我們要創建一個類,並且定義一個Native方法,如下:
JniTest類:
public class JniTest { public native String getTestString(); }
接著,我們要在命令行中編譯這個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
接下來,在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"); }
在上面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控件,它的布局如下:
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()); } }
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類的方法。
結束。源代碼下載!
現在視頻應用越來越火,Periscope火起來後,國內也出現了不少跟風者,界面幾乎跟Periscope一模一樣.Periscope確實不錯,點贊的效果也讓人眼前一亮,很漂
創建一個新項目是很簡單的,只要你安裝了Eclipse插件,並且你的Eclipse軟件版本在3.2或3.3,你就可以開始開發了。 首先, 看一下要創建"Hell
首先弄懂怎麼設置adb wifi無線調試的功能,如下所示。1. 手機端開啟adb tcp連接端口:/$setprop service.adb.tcp.port 5555:
現在由於GWF,google基本和咱們說咱見了,就給現在在做Android&nbs