Android jni程式碼註冊本地方法
阿新 • • 發佈:2019-01-27
Android 開發中有時需要呼叫本地方法,這就需要註冊本地方法,而註冊的方法有兩種:
- RegisterNatives註冊
- 使用javah生成規範的標頭檔案,然後編寫對應的原始檔。
先看一下java檔案 Hello.java,這裡面有一個native方法、一個平常方法。
package cn.vn.jniregisternative; public class Hello { static{ System.loadLibrary("Hello"); } private native String natvie_hello(); public String hello(){ return natvie_hello(); } }
1 使用RegisterNatives。
使用RegisterNatives註冊,就需要寫JNI_OnLoad方法。檔名為Hello.cpp(不限制檔名)。
#include <jni.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <assert.h> static jstring jni_hello(JNIEnv *env, jobject thiz){ jstring str = env->NewStringUTF("hello jni RegisterNatives"); return str; } static JNINativeMethod gMethods[] = { { "natvie_hello", "()Ljava/lang/String;", (jstring *)jni_hello }, }; jint JNI_OnLoad(JavaVM* vm, void* reserved){ JNIEnv* env = NULL; jint result = -1; jclass clazz; if ((*vm).GetEnv((void**) &env, JNI_VERSION_1_4) != JNI_OK) { return result; } assert(env != null); clazz = (*env).FindClass("cn/vn/jniregisternative/Hello"); if (clazz == NULL) { return result; } // 註冊native方法到java中 if ((*env).RegisterNatives(clazz, gMethods, sizeof(gMethods)/sizeof(gMethods[0])) < 0) { return result; } // 返回jni的版本 return JNI_VERSION_1_4; }
Android.mk如下
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := Hello
LOCAL_SRC_FILES := Hello.cpp
include $(BUILD_SHARED_LIBRARY)
2 使用javah。
使用javah方式,對方法名有一定的要求。
命令列進入該工程的\bin\classes目錄下面,確保已經生成了Hello.java對應的Hello.class檔案。如果沒有就在eclipse 上點選工程 build project。
在此目錄下面輸入:
如下圖所示javah -jni cn.vn.jniregisternative.Hello
然後會在該目錄下生成 標頭檔案。
將該檔案拷貝到jni目錄下面。
cn_vn_jniregisternative_Hello.h
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class cn_vn_jniregisternative_Hello */
#ifndef _Included_cn_vn_jniregisternative_Hello
#define _Included_cn_vn_jniregisternative_Hello
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: cn_vn_jniregisternative_Hello
* Method: natvie_hello
* Signature: ()Ljava/lang/String;
*/
JNIEXPORT jstring JNICALL Java_cn_vn_jniregisternative_Hello_natvie_1hello
(JNIEnv *, jobject);
#ifdef __cplusplus
}
#endif
#endif
編寫對應的cpp檔案。
cn_vn_jniregisternative_Hello.cpp
#include "cn_vn_jniregisternative_Hello.h"
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: cn_vn_jniregisternative_Hello
* Method: natvie_hello
* Signature: ()Ljava/lang/String;
*/
JNIEXPORT jstring JNICALL Java_cn_vn_jniregisternative_Hello_natvie_1hello
(JNIEnv *env, jobject thiz){
jstring str = env->NewStringUTF("hello jni hello");
return str;
}
#ifdef __cplusplus
}
#endif
該方式不需要呼叫RegisterNatives方法。
Android.mk
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := Hello
LOCAL_SRC_FILES := cn_vn_jniregisternative_Hello.cpp
include $(BUILD_SHARED_LIBRARY)
編譯過程
09:44:22 **** Build of configuration Default for project JniRegisterNative ****
"G:\\tools\\Android\\android-ndk-r10e\\ndk-build.cmd" all
Android NDK: WARNING: APP_PLATFORM android-21 is larger than android:minSdkVersion 8 in ./AndroidManifest.xml
[armeabi] Install : libHello.so => libs/armeabi/libHello.so
09:44:22 Build Finished (took 345ms)