# 动态注册JNI的方法(4)

作者: 不识水的鱼 | 来源:发表于2017-09-21 14:21 被阅读24次

    动态注册JNI的方法

    之前提供了一篇使用 java -jni来自动生成.h的文件,这种叫做静态注册的方法,现在提供一种动态注册的方法实现调用

    前期的准备工作也是基本上一样的

    不会的可以查看这里

    JNI开发实现helloworld,调用自己的C代码实现

    提供了静态注册的一些准备工作

    如下是基本的准备工作

    在build.gradle里

    ndk{
       moduleName "JNI_DYNAMIC_ANDROID_TEST" //生成的so名字
       abiFilters "armeabi", "armeabi-v7a", "x86" //输出指定的三种abi体系下的so库
    }
    

    在gradle.properties 里

      android.useDeprecatedNdk=true
    

    基本的准备工作做完了,写一个工具类

      package com.cxria.ndkapplication;
      
      /**
       * Created by yukun on 17-9-21.
       */
      
      public class JNIDynamicUtils {
          /**
           * 调用C++代码的方法,计算两数相加的结果返回对应的字符串
           * @return
           */
          public static native String getSumFromJNI(int i1, int i2);
      
          /**
           * 加载so库或jni库
           */
          static {
              System.loadLibrary("JNI_DYNAMIC_ANDROID_TEST");
          }
      }
    

    这里是工具类的代码

    在项目里新建jni包,不知道在那个目录下建立的请看

    JNI开发实现helloworld,调用自己的C代码实现

    这一次新建的不是 .c后缀的文件了 ,是.cpp,因为是C++实现的动态注册

    如下所示

     #include <stdio.h>
     #include <jni.h>
     #include <stdlib.h>
     
     jstring calcSum(JNIEnv *env, jclass clazz, jint i1, jint i2) {
         char result[50];
         sprintf(result, " this is string from jni. result is %d", (i1 + i2));
     //    jstring jstr=(*env)->NewStringUTF(env,result);
     //    return jstr;
         return env->NewStringUTF(result);
     }
     
     /**
      * JNINativeMethod由三部分组成:
      * (1)Java中的函数名;
      * (2)函数签名,格式为(输入参数类型)返回值类型;
      *  ()Ljava/lang/String; (II)表示需要传两个int型参数,Ljava/lang/String;表示返回String,在对象类名(包括包名,‘/’间隔)前面加L,分号结尾
      * (3)native函数名
      */
     static JNINativeMethod gMethods[] = { {"getSumFromJNI", "(II)Ljava/lang/String;", (void *)calcSum }};
     
     //System.loadLibrary过程中会自动调用JNI_OnLoad,在此进行动态注册
     JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *jvm, void *reserved) {
         JNIEnv *env = NULL;
         jint result = JNI_FALSE;
     
         //获取env指针
         if (jvm->GetEnv((void**) &env, JNI_VERSION_1_6) != JNI_OK) {
             return result;
         }
         if (env == NULL) {
             return result;
         }
         //获取类引用
         jclass clazz = env->FindClass("com/cxria/ndkapplication/JNIDynamicUtils");
         if (clazz == NULL) {
             return result;
         }
         //注册方法
         if (env->RegisterNatives(clazz, gMethods, sizeof(gMethods) / sizeof(gMethods[0])) < 0) {
             return result;
         }
         //成功
         result = JNI_VERSION_1_6;
         return result;
     }
    

    这里就是C++的代码实现,里面写了动态注册的一些参数和说明.可以作为参照

    所谓的静态注册,可以让提前写了的C++代码来直接使用,在使用方法,命名上也显得更加的灵活.

    最后调用以上方法实现

     package com.cxria.loadso;
     import android.support.v7.app.AppCompatActivity;
     import android.os.Bundle;
     import android.widget.TextView;
     
     import com.cxria.ndkapplication.JNIDynamicUtils;
     
     public class MainActivity extends AppCompatActivity {
     
         private TextView mTextView;
             @Override
             protected void onCreate(Bundle savedInstanceState) {
                 super.onCreate(savedInstanceState);
                 setContentView(R.layout.activity_main);
                 mTextView = (TextView) findViewById(R.id.textview);
                 mTextView.setText(JNIDynamicUtils.getSumFromJNI(10,10));
    
             }
     }
    

    结果显示为 'this is the add string from jni. result is 20'

    相关文章

      网友评论

        本文标题:# 动态注册JNI的方法(4)

        本文链接:https://www.haomeiwen.com/subject/ukwzsxtx.html