歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
Linux教程網 >> Linux編程 >> Linux編程 >> Android NDK :編寫清晰的代碼結構

Android NDK :編寫清晰的代碼結構

日期:2017/3/1 10:15:44   编辑:Linux編程
Android NDK 的具體開發步驟可以參考這裡:http://www.linuxidc.com/Linux/2012-07/66104.htm

使用Android NDK 在底層開發時,有可能會導致代碼結構的混亂,因為C 和C++的代碼明顯沒有Java那樣工整,再加上代

碼層調用中往往需要進行數據類型的轉化,所以,搭建一個條理清晰的代碼框架顯得非常重要,昨天看到一個老外的文章,就

說到這個問題,現在根據個人經驗稍微總結一下:

本Demo中用到的三個代碼文件為 JNI.java(負責Java層的native方法), native_glue.c(負責Java與C 語言間的類型轉化,

java與C語言函數的調用),native.c (負責實現具體的C語言函數);

第一、在Java層,建議專門寫一個類來進行C和Java代碼間的調用,比如 JNI.java,在這個 類中只寫上 native方法和 加載

動態庫的代碼,如下:

  1. package ndk.demo;
  2. public class JNI {
  3. static {
  4. //調用 ndk 編譯生成的庫
  5. System.loadLibrary("ndkDemo");
  6. }
  7. private static native int test(byte[] data, int size);
  8. private static native int getResult();
  9. }

現在生成.h頭文件,具體生成方法請參考文章開頭的連接,生成的.h內容如下:

  1. /*
  2. * Class: ndk_demo_JNI
  3. * Method: test
  4. * Signature: ([BI)I
  5. */
  6. JNIEXPORT jint JNICALL Java_ndk_demo_JNI_test
  7. (JNIEnv *, jclass, jbyteArray, jint);
  8. /*
  9. * Class: ndk_demo_JNI
  10. * Method: getResult
  11. * Signature: ()I
  12. */
  13. JNIEXPORT jint JNICALL Java_ndk_demo_JNI_getResult
  14. (JNIEnv *, jclass);

注意方法的名稱,其和你所寫的 JNI.java的包名對應一致;

第二、這一步是關鍵,在程序的目錄下新建一個文件夾,命名為 jni ,在裡面寫一個 native_glue.c的C 文件,我把這個 .c 文

件命名為glue(膠水),意為用它來將Java代碼和C 代碼粘和起來,就像一個接口一樣,負責Java層和C/C++層的相互調用,

在這個文件中寫上上面生成的 .h 文件中的,除此之外,可以在這個文件文件中寫上Java和 C語言數據類型轉換的代碼,而真正

的 native.c 代碼只負責函數功能的實現,屬於純C語言代碼,不涉及任何與Java有關的操作,現 native_glue.c的完整代碼如下:

  1. #include<stdlib.h>
  2. #include <stdio.h>
  3. #include <string.h>
  4. #include <jni.h>
  5. #include <android/log.h>
  6. #include"native.c"
  7. JNIEXPORT jint JNICALL Java_ndk_demo_JNI_test(JNIEnv *env, jclass thiz,
  8. jbyteArray jdata, jint size) {
  9. //數據類型轉換:jbyteArray---> jbyte*
  10. jbyte*data = (jbyte*) (*env)->GetByteArrayElements(env, jdata, 0);
  11. //調用 native.c 中的方法
  12. int len = native_test(data, size);
  13. //釋放類型轉換中的資源
  14. (*env)->ReleaseByteArrayElements(env, jdata, data, 0);
  15. return len;
  16. }
  17. JNIEXPORT jint JNICALL Java_ndk_demo_JNI_getResult(JNIEnv * env, jclass thiz) {
  18. return native_getResult();
  19. }
第三、native.c的代碼如下:
  1. #include<stdlib.h>
  2. #include <stdio.h>
  3. #include <string.h>
  4. /*代碼只是做個演示,沒有寫任何功能,*/
  5. int native_test(jbyte*data, int size) {
  6. return size;
  7. }
  8. int native_getResult() {
  9. return 0;
  10. }

如上所示,native_glue.c 作為接口,對數據進行預處理,再調用 native.c中的函數,使得 native.c集中負責具體實現,不會牽

扯任何多余操作,代碼結構清晰,以後修改代碼時也會更加方便,你只需更改native_glue.c 的函數名稱就行,不用對整個文件

修改。

第四、經過上述三個步驟,一個完整的Android NDK 代碼框架就寫好了,再在 .c 文件的目錄下編寫 Android.mk,在該文件目

錄下運行 ndk-build 命令,生成動態庫,Android.mk文件如下:

  1. LOCAL_PATH := $(call my-dir)
  2. include $(CLEAR_VARS)
  3. LOCAL_MODULE := ndkDemo #要生成的動態庫的名字
  4. LOCAL_SRC_FILES := native_glue.c
  5. LOCAL_LDLIBS+= -lz -lgcc
  6. include $(BUILD_SHARED_LIBRARY)

編譯如下圖所示:

這樣,就會自動在程序根目錄下生成一個 libs 文件夾,裡面有一個 libndkDemo.so 文件(NDK 規定編譯生成的庫文件名稱必須以

lib 開頭,比如你在Android.mk中寫的庫名稱為 ndkDemo,那麼真正生成的庫名稱是 libndkDemo.so),這就是你所需要的動態

庫文件了。這個Demo的代碼結構如下:

源代碼下載地址:

免費下載地址在 http://linux.linuxidc.com/

用戶名與密碼都是www.linuxidc.com

具體下載目錄在 /2012年資料/7月/23日/Android NDK :編寫清晰的代碼結構/

Copyright © Linux教程網 All Rights Reserved