Android 平台JNI编程方法

本文详细介绍了如何使用JNI(Java Native Interface)来实现Java代码与C/C++代码的交互。包括JNI的基本概念、如何声明和加载JNI方法、C/C++实现共享库的具体步骤、以及通过实例演示了如何在Java中调用C/C++的函数。

<!-- @page { margin: 2cm } P { margin-bottom: 0.21cm } -->

 

  1. 声明JNI 方法

    声明如 private native String printStr();

  2. 动态库的载入

     static {
    
                System.loadLibrary("helloworld");

        }
  1. 调用native 方法

    printStr(); 与普通方法相同

  2. C 语言实现共享库

  3. 利用javah 工具生成JNI 接口的头文件

    比如在bin (利用eclipse 工具进行app 开发)目录下执行:

    javah com.simon.HelloWorld
    
  4. C 的接口实现

    实现printStr(), 以及 JNI_OnLoad() 方法

  5. 编写makefile 文件

    1. LOCAL_PATH:= $(call my-dir)
      
      include $(CLEAR_VARS)
      
      LOCAL_SRC_FILES:=com_simon_Helloworld.c
      
      LOCAL_C_INCLUDES := $(JNI_H_INCLUDE)
      
      LOCAL_MODULE := libhelloworld
      
      LOCAL_SHARED_LIBRARIES := libutils
      
      LOCAL_PRELINK_MODULE := false
      
      include $(BUILD_SHARED_LIBRARY)
      
    • 利用c++ 实现共享库

      1 )实现声明的方法

      2javac ++方法名字的映射

      3native 方法的注册

      4C++ 实现的代码如下

       

      1. #include <jni.h> 
        
        #define LOG_TAG "HelloWorld" 
        
        #include <utils/Log.h> 
        
        
        /* Native interface, it will be called in java code */ 
        
        JNIEXPORT jstring JNICALL Java_com_ar_JNIStudy_printJNI(JNIEnv *env, jobject obj) 
        
        { 
        
            LOGI("Hello World From libhelloworld.so!"); 
        
        
            return env->NewStringUTF("Hello World!"); 
        
        } 
        
        
        static const char *classPathName = "com/ar/JNIStudy"; 
        
         
        
        static JNINativeMethod methods[] = { 
        
            {"printJNI", "()Ljava/lang/String;", (void*)Java_com_ar_JNIStudy_printJNI }, 
        
        }; 
        
        
        /* 
        
         * Register several native methods for one class. 
        
         */ 
        
        static int registerNativeMethods(JNIEnv* env, const char* className, 
        
            JNINativeMethod* gMethods, int numMethods) 
        
        { 
        
            jclass clazz; 
        
        
            clazz = env->FindClass(className); 
        
            if (clazz == NULL) { 
        
                LOGE("Native registration unable to find class '%s'", className); 
        
                return JNI_FALSE; 
        
            } 
        
            if (env->RegisterNatives(clazz, gMethods, numMethods) < 0) { 
        
                LOGE("RegisterNatives failed for '%s'", className); 
        
                return JNI_FALSE; 
        
            } 
        
        
            return JNI_TRUE; 
        
        } 
        
        /* 
        
         * Register native methods for all classes we know about. 
        
         * 
        
         * returns JNI_TRUE on success. 
        
         */ 
        
        static int registerNatives(JNIEnv* env) 
        
        { 
        
          if (!registerNativeMethods(env, classPathName, 
        
                         methods, sizeof(methods) / sizeof(methods[0]))) { 
        
            return JNI_FALSE; 
        
          } 
        
        
          return JNI_TRUE; 
        
        } 
        
        /* This function will be call when the library first be loaded */ 
        
        jint JNI_OnLoad(JavaVM* vm, void* reserved) 
        
        { 
        
            JNIEnv* env = NULL; 
        
            LOGI("JNI_OnLoad2!"); 
        
        
            if (vm->GetEnv((void**)&env, JNI_VERSION_1_4) != JNI_OK) { 
        
                LOGE("ERROR: GetEnv failed"); 
        
                return -1; 
        
            } 
        
        
            if (registerNatives(env) != JNI_TRUE) { 
        
                LOGE("ERROR: registerNatives failed"); 
        
                return -1; 
        
            } 
        
        
            LOGI("JNI_OnLoad register OK"); 
        
             return JNI_VERSION_1_4; 
        
        }
        

       

       

    • What Next?

      1.  
        1. JNI 的进一步学习, 如native method 中的参数的含义,如何从native method 调用Java mthod

        2. 标准JNI 的学习, 可以参考book

          The Java Native Interface --------Programmer’s Guide and Specification

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值