Android JNI使用方法
經過幾天的努力終于搞定了android JNI部分,下面將我的這個小程序和大家分享一下。android JNI是連接android Java部分和C/C++部分的紐帶,完整使用JNI需要Java代碼和C/C++代碼。其中C/C++代碼用于生成庫文件,Java代碼用于引用C /C++庫文件以及調用C/C++方法。
android Java部分代碼:
jnitest.javapackage com.hello.jnitest;
import android.app.Activity;
import android.os.Bundle;
public class jnitest extends Activity {
/** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); Nadd test = new Nadd(); setTitle("The Native Add Result is "+String.valueOf(test.nadd(10, 20))); }
}
Nadd.java
package com.hello.jnitest;
public class Nadd {
static {
System.loadLibrary("hello_jni");
}
public native int nadd(int a, int b);
}</pre>
Java代碼說明:1)jnitest.java是一個activity的類對象,在該類對象中生成調用JNI函數的類對象,同時調用JNI方法,最后將JNI方法的結果顯示到標題欄上;2)Nadd.java是一個引用和聲明JNI庫和函數的類,其中System.loadLibrary();函數用來引用JNI庫,默認JNI庫放在 android系統的/system/lib/目錄下;public nadd int nadd(int a, int b);為聲明需要在java程序中使用的JNI庫中的函數;JNI中java部分的代碼到此就結束了,總結一下在java代碼中需要做兩件事:1)使用System.loadLibrary()函數來引用JNI庫;2)聲明調用JNI庫的函數且前面添加native關鍵字;
android C/C++部分代碼:#define LOG_TAG "hello-JNI"include <stdio.h>
include <stdlib.h>
include <unistd.h>
include <sys/types.h>
include <sys/stat.h>
include <fcntl.h>
include <assert.h>
include "jni.h"
include "JNIHelp.h"
include "android_runtime/AndroidRuntime.h"
static jint com_hello_jnitest_jnitest_nadd(JNIEnv env, jobject obj, jint a, jint b) { return (a b); } static JNINativeMethod gMethods[] = { {"nadd", "(II)I", (void )com_hello_jnitest_jnitest_nadd}, }; static int register_android_test_hello(JNIEnv env) { return android::AndroidRuntime::registerNativeMethods(env, "com/hello/jnitest/Nadd", gMethods, NELEM(gMethods)); } jint JNI_OnLoad(JavaVM vm, void reserved) { JNIEnv *env = NULL; if (vm->GetEnv((void **)&env, JNI_VERSION_1_4) != JNI_OK) { printf("Error GetEnv\n"); return -1; } assert(env != NULL); if (register_android_test_hello(env) < 0) { printf("register_android_test_hello error.\n"); return -1; } return JNI_VERSION_1_4; }</pre>
JNI C/C++代碼說明:1)JNI_OnLoad()函數。該函數在Java程序調用System.loadLibrary()時,被調用執行,用于向JavaVM注冊JNI函數等。在本例中首先通過參數JavaVM(Java虛擬機指針)獲取當前應用程序所在的線程,即:JNIEnv。再通過調用 android::AndroidRuntime::registerNativeMethods()注冊native實現的函數指針。2)JNI函數和Java調用函數的映射關系。使用JNINativeMethod將java調用的函數名與JNI實現的函數名聯系在一起;3)JNI函數實現;
Android.mk代碼:LOCAL_PATH := $(call my-dir) include $(CLEAR_VARS) LOCAL_PRELINK_MODULE := false LOCAL_SRC_FILES := \ com_hello_jnitest.cpp LOCAL_SHARED_LIBRARIES := \ libandroid_runtime LOCAL_MODULE := libhello_jni include $(BUILD_SHARED_LIBRARY)
需要注意的是:1)JNI C/C++部分的代碼需要在android源代碼樹上進行編譯,編譯完成后我的做法是直接將生成的.so通過adb push方法上傳到android虛擬機的/system/lib/目錄下;2)java代碼可以在eclipse下直接編譯且在虛擬機上執行;
編譯JNI C/C++部分代碼(在android內核源代碼根目錄下):#make libhello_jni
</div>
之后在out/target/product/generic/system/lib/目錄下生成libhello_jni.so
上傳libhello_jni.so到android虛擬機:#adb push out/target/product/generic/system/lib/libhello_jni.so /system/lib
</div>
注意:此時有可能出現Out of Memory的錯誤提示。當出現如上錯誤提示時,需要使用#adb remount重新加載一下就可以了。另外,也有可能直接使用eclipse啟動android虛擬機時出現上述錯誤且使用#adb remount也出現的情況,此時需要手動啟動android虛擬機,如:#emulator -avd xxx -partition-size 128,之后在使用#adb push就可以了。本文由用戶 jopen 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!相關資訊