自动化零件服务商 - 供应SMC,FESTO,CKD全新正品气动元件
自动化零件服务商 - 供应SMC,FESTO,CKD全新正品气动元件
自动化零件服务商 - 供应SMC,FESTO,CKD全新正品气动元件

前言

之前JNI一直用C语言写,但发现Android Framework中大都用C++写,为了阅读方便,改为C++。其实C++跟C语言写法一样的,只不过C++更简洁些。

正文

修改点,举个例子

不同点

hello.c文件后缀改为hello.cpp,还有就是C++传入的参数更少,看起来更简洁。

hello.c
  1. JNIEXPORT jstring JNICALL Java_com_biumall_jni_one_Hello_hello
  2. (JNIEnv * env , jclass jclazz){
  3.   return (*env)->NewStringUTF(env, "Hello World !---from JNI");
  4. };
复制
hello.cpp
  1. JNIEXPORT jstring JNICALL Java_com_biumall_jni_one_Hello_hello
  2. (JNIEnv * env , jclass jclazz){
  3.   return env->NewStringUTF("Hello World !---from JNI");
  4. };
复制
Android.mk

下面有注释不同点

  1. LOCAL_PATH := $(call my-dir)
  2. include $(CLEAR_VARS)
  3. LOCAL_LDLIBS := -llog
  4. LOCAL_MODULE   := Hello
  5. # C语言
  6. LOCAL_SRC_FILES := Hello.c
  7. # C++
  8. LOCAL_SRC_FILES := Hello.cpp
  9. include $(BUILD_SHARED_LIBRARY)
复制

C++版

代码跟《JNI动态注册封装C语言版》一样。只不过这里是C++版的。

PS :这里只是代码,具体动态注册流程请看《JNI动态注册

Hello.java
  1. public class Hello {
  2.   private final String TAG = "from_dynamic_java_";
  3.   //1. load Hello.so
  4.   static {
  5.       System.loadLibrary("Hello");
  6.   }
  7.   // 2. define native computer()
  8.   public static native int computer(String type, int a, int b);
  9.    
  10.   public int add(int x, int y) {
  11.       return x + y;
  12.   }
  13.   public int sub(int x, int y) {
  14.       return x - y;
  15.   }
  16. }
复制
Log.h
  1. #include <android/log.h>
  2. //定义TAG日志打印
  3. #define LOG_TAG "from_dynamic_jni_"
  4. #define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, __VA_ARGS__)
  5. #define LOGI(...) __android_log_print(ANDROID_LOG_INFO, LOG_TAG, __VA_ARGS__)
  6. #define LOGE(...) __android_log_print(ANDROID_LOG_ERROR, LOG_TAG, __VA_ARGS__)
复制
JNICommon.h
  1. #include <jni.h>
  2. //获取数组大小
  3. #define ARRAY_LENGTH(x) ((int)(sizeof(x) / sizeof((x)[0])))
  4. //注册本地方法
  5. int registerNativeMethods(JNIEnv *env, const char *className, JNINativeMethod *methods,
  6.                         int methods_size) {
  7.   jclass clazz = env->FindClass(className);
  8.   if (!clazz) {
  9.       return JNI_ERR;
  10.   }
  11.   int result = env->RegisterNatives(clazz, methods, methods_size);
  12.   if (result < 0) {
  13.       return JNI_ERR;
  14.   }
  15.   return JNI_OK;
  16. }
复制
Hello.cpp
  1. #include "JNICommon.h"
  2. #include "Log.h"
  3. #include<string.h>
  4. /**
  5. * ---------------------------第一步 start ---------------------------
  6. * 定义Hello.java类路径[包名+类名,只不过.换成了/]
  7. * 包名+类名:com.biumall.dynamic.one.Hello
  8. */
  9. #define DYNAMIC_CLASS "com/biumall/dynamic/one/Hello"
  10. /**
  11. * ---------------------------第一步 end ---------------------------
  12. */
  13. /**
  14. * ---------------------------第二步 start ---------------------------
  15. * c_add()用于调用Java方法
  16. * @param env env
  17. * @param jclazz jclazz
  18. * @param x x
  19. * @param y y
  20. * @return
  21. */
  22. int c_add(JNIEnv *env, jclass jclazz, int x, int y) {
  23.   jmethodID methodID = env->GetMethodID(jclazz, "add", "(II)I");
  24.   jobject object = env->AllocObject(jclazz);
  25.   return env->CallIntMethod(object, methodID, x, y);
  26. }
  27. /**
  28. * c_sub()用于调用Java方法
  29. * @param env env
  30. * @param jclazz jclazz
  31. * @param x x
  32. * @param y y
  33. * @return
  34. */
  35. int c_sub(JNIEnv *env, jclass jclazz, int x, int y) {
  36.   jmethodID methodID = env->GetMethodID(jclazz, "sub", "(II)I");
  37.   jobject object = env->AllocObject(jclazz);
  38.   return env->CallIntMethod(object, methodID, x, y);
  39. }
  40. /**
  41. * 本地方法computer实现
  42. */
  43. JNIEXPORT jint JNICALL native_computer(JNIEnv *env, jclass jclazz, jstring type, jint a, jint b) {
  44.   const char *charType = env->GetStringUTFChars(type, 0);
  45.   LOGD("native_computer : %s ", charType);
  46.   int count;
  47.   if (!strcmp(charType, "-")) {
  48.       count = c_sub(env, jclazz, a, b);
  49.   } else if (!strcmp(charType, "+")) {
  50.       count = c_add(env, jclazz, a, b);
  51.   }
  52.   env->ReleaseStringUTFChars(type, charType);
  53.   return count;
  54. }
  55. /**
  56. * ---------------------------第二步 end ---------------------------
  57. */
  58. /**
  59. * ---------------------------第三步 start ---------------------------
  60. * 定义Java和JNI函数的绑定表
  61. * 方法数组,分别为:(native方法 , 方法签名 , 函数指针[JNI中需要实现的方法名])
  62. * 通过javac和javap 获取 方法签名
  63. */
  64. JNINativeMethod method_table[] = {
  65.       {"computer", "(Ljava/lang/String;II)I", (void *) native_computer},
  66. };
  67. /**
  68. * ---------------------------第三步 end ---------------------------
  69. */
  70. /**
  71. * ---------------------------第四步 start ---------------------------
  72. * 注册本地方法
  73. */
  74. JNIEXPORT jint JNI_OnLoad(JavaVM *vm, void *reserved ){
  75.   JNIEnv *env = NULL;
  76.   int result = vm->GetEnv((void **) &env, JNI_VERSION_1_6);
  77.   LOGD("JNI_OnLoad 1 result : %d", result);
  78.   if(result != JNI_OK){
  79.       return JNI_ERR;
  80.   }
  81.   result = registerNativeMethods(env, DYNAMIC_CLASS, method_table, ARRAY_LENGTH(method_table));
  82.   LOGD("JNI_OnLoad 2 result : %d", result);
  83.   if(result != JNI_OK){
  84.       return JNI_ERR;
  85.   }
  86.   return JNI_VERSION_1_6;
  87. }
  88. /**
  89. * ---------------------------第四步 end ---------------------------
  90. */
复制
Application.mk
  1. APP_ABI := arm64-v8a
复制
Android.mk
  1. LOCAL_PATH := $(call my-dir)
  2. include $(CLEAR_VARS)
  3. LOCAL_LDLIBS := -llog
  4. LOCAL_MODULE := Hello
  5. LOCAL_SRC_FILES := Hello.cpp
  6. include $(BUILD_SHARED_LIBRARY)
复制

参考文章

  1. JNI动态注册封装C语言版

  2. JNI动态注册

自动化零件服务商 - 供应SMC,FESTO,CKD全新正品气动元件

相关文章

自动化零件服务商 - 供应SMC,FESTO,CKD全新正品气动元件

暂无评论

none
暂无评论...