2020年最新as中jni----------动态注册

第一步:静态代码块 导入so库

static {
    System.loadLibrary("native-lib");   //native-lib是so名,可随意更改
}

第二步:写外部函数

public native String getString();  //native代表c\c++实现

第三步:创建新的 C/C++ 源代码文件

要将新的 C/C++ 源代码文件添加到现有项目,请按以下步骤操作:

如果您的应用的主源代码文件集内还没有 cpp/ 目录,请按如下所示的方法创建一个:
从 IDE 的左侧打开 Project 窗格,然后从下拉菜单中选择 Project 视图。
转到 your-module > src,右键点击 main 目录,然后依次选择 New > Directory。
输入 cpp 作为目录名称,然后点击 OK。
右键点击 cpp/ 目录,然后依次选择 New > C/C++ Source File。
为您的源代码文件输入一个名称,例如 native-lib。
从 Type 下拉菜单中,为您的源代码文件选择文件扩展名,例如 .cpp。
您可以向此下拉菜单添加其他文件类型(例如 .cxx 或 .hxx),只需点击 Edit File Types 图标  即可。在弹出的 C/C++ 对话框中,从 Source Extension 和 Header Extension 下拉菜单中选择另一个文件扩展名,然后点击 OK。
如果您还想要创建头文件,请选中 Create an associated header 复选框。
点击 OK。

第四步:定义一个JNINativeMethod数组

typedef struct {
    const char* name;     //函数名
    const char* signature;  //参数和返回值 格式是()V,括号里面是参数,后边是返回值
    void*       fnPtr;
} JNINativeMethod;

第五步: 加载并注册jni

函数均为c++中的函数,如果是c语言需要调用c的函数(函数的返回值就是c的函数),
获得class函数:

jclass FindClass(const char* name)   //name是class的路径和名称
{ return functions->FindClass(this, name); }

用到的函数:加载jni函数

JNIEXPORT jint JNI_OnLoad(JavaVM* vm, void* reserved);

  获得env函数:

jint GetEnv(void** env, jint version)  //jni版本一般使用JNI_VERSION_1_4
{ return functions->GetEnv(this, env, version); }

 注册env函数:

jint RegisterNatives(jclass clazz, const JNINativeMethod* methods,
    jint nMethods)
{ return functions->RegisterNatives(this, clazz, methods, nMethods); }

完整动态注册代码:

jint getInt(JNIEnv *env, jobject, jint n)
{
    int m=n;
    return ++m;
}
void  getStaticMode(JNIEnv *env, jobject)
{
    jclass clazz= env->FindClass("com/example/myapplication/MainActivity");
    jmethodID methodID=env->GetStaticMethodID(clazz, "staticMothod", "()V");
    env-> CallStaticVoidMethod( clazz, methodID);
    return;
}
JNINativeMethod nativeMethod[]={{"getString","()Ljava/lang/String;",(void*)getString}};

JNIEXPORT jint JNI_OnLoad(JavaVM* vm, void* reserved)
{
    JNIEnv* env;
   if(vm->GetEnv((void**)(&env), JNI_VERSION_1_4) != JNI_OK)
   {
       return JNI_ERR;
   }
    jclass clazz= env->FindClass("com/example/myapplication/MainActivity");

if(env->RegisterNatives(clazz,nativeMethod,sizeof(nativeMethod)/sizeof(JNINativeMethod))!=JNI_OK)
{
    return JNI_ERR;
}
return JNI_VERSION_1_4;
}

第六步:配置CMake

此处和静态注册处理相同

动态注册和静态注册的区别:

静态注册

编写不方便,jni方法名字必须遵循规则而且名字很长

过程较多

程序运行的效率极低,不安全

java_开头

动态注册

流程清晰可控

效率更高,安全

你可能感兴趣的:(c\c++)