调用 Java 方法流程 ---- JNI 中调用 Java 方法流程 : ① 获取 jclass 类型变量 : 调用 jclass GetObjectClass(jobject obj) 或 jclass..., …) 调用 Java 对象方法 , void CallStaticVoidMethod(jclass clazz, jmethodID methodID, …) 调用 Java 的静态方法 ;...C++ 中的 jclass 对象 ; 参数 : 传入 Java 对象 ; ( 该对象一般是由 JNI 方法传入的 ) struct _JNIEnv { /* _JNIEnv 结构体中封装了...对应 C/C++ jclass 类型对象 ) , Java 方法 ID , 及根据函数签名传入的 参数列表 ( 可变参数 ) , 反射调用该 Java 对象的方法 ; 返回值 : Void , 注意这里的返回值可以是...调用 Java 对象的方法 /* 调用 Java 引用对象的方法 : 要根据 返回值类型不同 , 调用不同的方法 如果返回值是 int 类型 , 那么就需要调用
上次说到c/c++调用Java的变量,同样的c/c++也可以调用Java的方法 1.c/c++native方法调用Java非静态方法 首先看下我们Java的类 package com.aruba.jniapplication...,再通过jclass获取jmethodID ,然后根据jmethodID调用Java的方法,最后打印输出。...Java方法被成功调用了,一般c/c++调用Java方法用于使用一些Java封装好的方法,而c/c++库函数又没有提供,自己手写又比较复杂,此时调用Java的方法会非常便利 2.c/c++静态native...3.c/c++调用Java对象的构造方法 首先我们创建一个Java类:HelloC public class HelloC { public HelloC() { } private...成功的实例化了一个HelloC对象 总结:c/c++调用Java方法流程:根据jclass获取jmethodID->根据具体返回值调用相应的callXXXMethod方法或者构造方法的话调用NewObject
在 JNI 去调用 Java 的方法和访问字段时,最先要做的操作就是获得对应的类以及对应的方法 id。...事实上,通过 FindClass 、GetFieldID、GetMethodID 去找到对应的信息是很耗时的,如果方法被频繁调用,那么肯定不能每次都去查找对应的信息,有必要将它们缓存起来,在下一次调用时...当类被加载进内存时,会先调用类的静态代码块,所以可以在类的静态代码块中进行缓存。...env->GetMethodID(cls, "getName", "()Ljava/lang/String;"); } 在 JNI 中直接将方法 id 缓存成全局变量了,这样再调用时,就不要再进行一次查找了...,并且避免了多个线程同时调用会多次查找的情况。
} 在上面的代码中,首先通过 GetObjectClass 函数获取对应的 Java 类,其参数就是要获得的对象类型 jobject ,然后得到的结果就是一个 jclass 类型的值,代表 Java...,JNI 调用对应的方法不同。...对于类的静态字段,JNI 的方法多了 Static 的标志来表明这个对应于类的静态字段访问。...方法调用 JNI 调用 Java 方法和 JNI 访问 Java 字段的步骤也大致相同, 获取 Java 对象的类 获取对应方法的 id 调用具体的方法 以调用类的实例方法和静态方法为例: 调用类的实例方法...小结 可以看到,从 JNI 中访问 Java 的字段和访问,两者的步骤都是大致相似的,只是调用的 JNI 方法有所区别。 具体示例代码可参考我的 Github 项目,欢迎 Star。
Android 还可以通过 JNI 来调用 Java 一个类的构造方法,从而创建一个 Java 类。 调用构造方法 调用构造方法的步骤和之前调用类的实例方法步骤类似,也需要获得对应的类和方法 id。...除了 NewObject 方法之外,JNI 还提供了 AllocObject 方法来创建对象,以同样调用 Animal 类构造方法为例: /** * 通过 AllocObject 方法来创建一个类...然后通过 AllocObject 方法创建对象,但要注意的是,此时创建的对象是未被初始化的,不同于 NewObject 方法创建的对象直接就是初始化了,在一定程度上,可以说 AllocObject 方法是延迟初始化的...接下来是要通过 CallNonvirtualVoidMethod 来调用对应的构造方法。此处传入的一个参数不再是 jclass 类型,而是创建的未被初始化的类 jobject 。...通过这种方法,同样可以创建一个 Java 中的类。 调用父类的方法 可以通过 JNI 来调用父类的实例方法。
调用其他三方动态库的使用过程,可以参见博主的另一篇文章介绍: 支付宝二维码脱机认证库在android的app下测试过程记录_特立独行的猫a的博客-CSDN博客 java调用JNI总结_特立独行的猫a的博客...* kClassName= "com/mypackage/jni/CalcMac"; jclass clazz; debug_level = 5; LOGD(">>> .....目录 //目前的手机架构基本上都是arm架构,x86的基本上没有,基本上是平板 abiFilters "armeabi-v7a",//arm架构的32位...如果接口不带参数,所以签名是()I,如果我的接口方法带两个参数,这里签名应该是 (II)I, I表示的是int类型,否则java层通过JNI调用时,会报找不到方法。...从入门到精通(汇总篇)_阿飞__的博客-CSDN博客 JNI基础:JNI数据类型和类型描述符_阿飞__的博客-CSDN博客 java调用JNI总结_特立独行的猫a的博客-CSDN博客 支付宝二维码脱机认证库在
本篇博客将介绍Java和JNI的互相调用,因此主要包括两部分: JNI层调用Java层 Java层调用JNI、Native层 JNI层调用Java层 JNI层调用Java层有点类似Java的反射机制,需要首先找到类...层的代码 这里采用静态注册的方式,方法的的实现如下: //调用MainActivity中的两个方法,得到两个数,相加,再显示到TextView上JNIEXPORT void JNICALLJava_com_enniu_jnidemo_MainActivity_jniInvokeJava...Call*Method()的第一个参数是jobject,表示在某个对象上调用该方法,因此如果需要调用对象的方法,JNI又无法获取的话,需要从Java层传入。...这里的情形可以举个例子:比如说需要在C++层创建多份同一个对象,Java层会根据不同情况调用不同对象,那么该怎么做呢? Java层要能调用不同对象,得保存各个对象的信息,但那是C层的对象,怎么保存了?...JNI调用Java代码是一种类似反射的原理,先找到jclass、再找到jmethodId,然后调用,这样一步步地来;Java调用C/C++代码创建对象是需要保存对象指针,然后各种操作是要将指针传入到jni
通过适当的方法得到 field 的内容,如 GetIntField。 调用方法也是相似的,首先要得到类对象的引用,然后是方法ID。ID通常是指向内部运行时数据结构的指针。...Local 和 Global 引用 传给Native方法的每个参数和几乎由JNI函数返回的每个对象都是一个本地引用。这意味着它在当前线程,当前Native方法里是有效的。...在从Native方法返回后,虽然对象本身还存活着,但它的引用已经失效了。 这个规则适用于jobject所有的子类,包括jclass, jstring和 jarray。...引用同一个对象有两个不同的引用值也是有可能的。例如,在同一对象上连续调用NewGlobalRef的返回值可能不同。查看两个引用是否指向同一个对象必须使用 IsSameObject 方法。...一个后果是,在本地代码中你不能假定对象引用是不变的或唯一的。这次方法的调用与下次方法调用返回的32位对象值可能是不同的,并且两个不同对象可能在连续调用后具有相同的32位值是可能的。
上面讲解了如何从JNI中调用Java类中的方法,其实在jni.h中已经定义了一系列函数来实现这一目的,下面我们就以此举例说明: (一)、获取Class对象 为了能够在C/C++中调用Java中的类,jni.h...比如: jclass jcl_string=env->FindClass("java/lang/String"); 来获取Java中的String对象的class对象 jclass GetObjectClass...(jobject obj): 通过对象实例来获取jclass,相当于Java中的getClass()函数 jclass getSuperClass(jclass obj): 通过jclass可以获取其父类的...jclass对象 (二)、获取属性方法 在Native本地代码中访问Java层的代码,一个常用的常见的场景就是获取Java类的属性和方法。...(三)、构造一个对象 常用的JNI中创建对象的方法如下: jobject NewObject(jclass clazz, jmethodID methodID, ...)
, 值 对应 属性值 ; 逗号隔开 : 多个 表示 属性 和 方法 的 键值对 之间 使用逗号隔开 ; 对象方法 : 表示 方法名称 的 键 后面的 冒号 后面 写一个 " 匿名函数 " , 如 :...调用对象属性 : 使用 对象名.属性名 的方式 , 调用 对象属性 ; // 访问对象属性 - 方式一 : 对象名.属性名 console.log(person.name...(person['name']); 执行结果 : 3、调用对象方法 调用对象方法 : 使用 对象名.方法名(...) 的方式 , 调用对象方法 ; // 调用对象方法 - 对象名.方法名() person.hello(); 完整代码示例 : 对象名.方法名() 的方式使用 ;
1 JNI定义 JNI(Java Native Interface),即Java本地接口,JNI是Java调用Native 语言的一种特性。通过JNI可以使得Java与C/C++机型交互....两者本质上都是指向函数表的二级指针。 JavaVM 理论上,每个进程可以有多个 JavaVM,但 Android 只允许有一个。...开发者可以通过JNIEnv调用Java函数和操作Java代码 4 jobject与jclass类型 jobject与jclass通常作为JNI函数的第二个参数,当所声明Native方法是静态方法时,对应参数类型...jclass,因为静态方法不依赖对象实例,而依赖于类,所以参数中传递的是一个jclass类型。...类型 描述 Object jobject 任何Java对象 class jclass class对象 String jstring 字符串对象 Object[] jobjectArray 对象数组 boolean
JNI函数,本地方法通过JNI函数来访问JVM中的数据结构 3.1 JNIEnv 作用 调用 Java 函数 : JNIEnv 代表 Java 运行环境, 可以使用 JNIEnv 调用 Java 中的代码...; 操作 Java 对象 : Java 对象传入 JNI 层就是 Jobject 对象, 需要使用 JNIEnv 来操作这个 Java 对象 3.2 JNIEnv 与线程 JNIEnv指针只在它所在的线程中有效...不同线程调用一个本地方法时,传入的JNIEnv指针是不同的. 比如,在jni的方法中起了线程去处理事件,处理完后希望能通知java层,线程中是不能使用参数JNIEnv的。...函数的第二个参数,当所声明Native方法是静态方法时,对应参数jclass,因为静态方法不依赖对象实例,而依赖于类,所以参数中传递的是一个jclass类型。...相反,如果声明的Native方法时非静态方法时,那么对应参数是jobject。 jobject 也是不能跨线程调用的。
import java.lang.reflect.Method; class MethodInvokeTest { public static ...
中定义的函数指针 , 实际都定义在 JNINativeInterface 结构体中 ; C 语言中的 JNIEnv * env 实际上是 JNINativeInterface ** 类型 , 调用其中的方法指针时...结构体中的函数指针 , 只需要调用 JNIEnv 结构体中的方法即可 , C++ 中的 JNIEnv * env , 可以直接调用其中的方法 , 将其当做一个对象使用 , env->方法名称 , 即可完成调用...; 一、 JNI 方法解析 ---- 1 ....JNI 方法定义 : ① 在 Android 的 Java 层定义方法 : 在 MainActivity 类中定义 如下 Native 方法 ; public native String stringFromJNI...Native 方法定义在 MainActivity 类中 ; 1> 非静态方法 : 如果该方法是非静态方法 , 那么 jobject 参数表示 MainActivity 类的对象 ; 2> 静态方法
2 如何使用 在目前的Android开发中,一般情况下有2种方法来使用JNI编程,就是传统的需要手动生成h文件和新版的CMake,Cmake的是利用配置文件来完成一些配置,实际上只是简化了流程,用CMakeLists.txt...jobject同样也是JNI的数据类型,对应于Java的Object,系统在调用native方法的时候会根据方法名,将Java方法和JNI方法建立关联,但是它有一些明显的缺点: JNI层的方法名称过长...因为以上的不方便,所以才有了动态注册的机制存在,下面简单分析一下: JNI_OnLoad函数 在调用了 System.loadLibrary("native-lib"); 方法加载so库的时候,Java...__android_log_print(ANDROID_LOG_DEBUG,kTAG,__VA_ARGS__) #endif 注释也已经很清楚了,我们需要知道C语言中调用Java的一些函数,实际上也是反射获取的...,步骤跟Java层的是一样的,换句话说在Java反射能做到的,在JNI中通过类似的反射也是可以做到的,这些方法原型在jni.h文件里面,比如 大家可以多去看看那些方法,基本上各种类型的方法都有,运行如下
这是JNI实现源码分析系列文章中的一部分,本系列文章结合Dalvik源码来说明JNI实现上的细节,本系列包括: JNI实现源码分析【一 前言】 JNI实现源码分析【二 数据结构】 JNI实现源码分析...【三 间接引用表】 JNI实现源码分析【四 函数调用】 JNI实现源码分析【五 结束语】 正文 在展开深入讨论之前,先说一下Dalvik中和JNI相关的数据结构,是很有必要的。...及虚拟机中的对象。 ...代表了类中的一个方法,通常通过解析Dex中的method构造而来 0x03: 实现JNI需要的数据结构 虚拟机在实现JNI时,需要一些特殊的结构。...0x04: JNI参数传递的数据结构 方法调用少不了参数传递:入参和返回值,在JNI中,并不是直接将虚拟机中的Object暴露给API,而是使用了形如jobject这样的结构,为何?
clazz; clazz = env->FindClass(className); 另一种获取方法是已经知道对象/实例的引用,通过GetObjectClass来获取 jclass clazz = env...static和非static之分,对应的jni反射的接口也有差异 常见的获取方法有: jfieldID GetFieldID(jclass clazz, const char *name, const...通常,在 .class 文件上使用 javap 是查找类的内部名称的好方法。 如果类名称形式正确,则可能是您遇到了类加载器问题。FindClass 需要在与您的代码关联的类加载器中启动类搜索。...在执行 JNI_OnLoad 过程中发出的任何 FindClass 调用都会使用与调用 System.loadLibrary 的函数关联的类加载器(这是一条特殊规则,用于更方便地进行库初始化)。...在某个便捷位置缓存对 ClassLoader 对象的引用,然后直接发出 loadClass 调用。这需要花费一些精力来完成。
Android JNI 调用时的异常主要有如下两种: Native 代码调用 Java 层代码时发生了异常要处理 Native 代码自己抛出了一个异常让 Java 层去处理 可以看到异常的发生和处理基本都需要...Native 调用 Java 方法时的异常 之前的博客中就讲述了如何从 Native 调用 Java 的方法,先准备一个有异常的方法供 Native 去调用。...而 ExceptionClear 方法则是关键的不会让应用直接崩溃的方法,类似于 Java 的 catch 捕获异常处理,它会消除这次异常。...比如 Java 调用 Native 方法传递了某个参数,而这个参数有问题,那么 Native 就可以抛出异常让 Java 去处理这个参数异常的问题。...具体的异常处理方法和时机还是要看具体的使用场景,选择最合适的处理方法。
a.效率上C&C++比Java高, b.C&C++的反编译比Java难度高 c.如果之前用C&C++开发的模块,可以通过JNI来复用 但是一旦使用JNI,就会让Java失去跨平台功能,需要在不同的系统平台下编译本地语言...动态注册对比静态注册 1.静态注册 编写不方便,JNI 方法名字必须遵循规则且名字很长 程序运行效率低,因为初次调用native函数时需要根据根据函数名在JNI层中搜索对应的本地函数,然后建立对应关系...JNI基本使用-拿到JAVA层的保存的Native对象并调用Native层的方法 extern "C" JNIEXPORT jint JNICALL Java_com_kobe_startjni_MainActivity_getValue...->GetLongField(object, jfield); return mainActivity->getValue(); } JNI基本使用-Native层的对象调用Java层的对象的方法...(object, jfield, myclass); } 总结 1.Java层调用Native层的方法,只能通过动态注册或者静态注册的JNI接口 2.Java层可以保存Native层对象的指针long
该对象的 loadLibrary 方法最终会调用 System.loadLibrary 函数完成共享库的加载。...C/C++调用Java方法 在 ijkplayer 中,它会使用C调用android下的 MediaCodec类中的方法。我们就以这个为例子看一下它是如何从C调用的java方法吧。...首先,通过 FindClass 拿到想要处理类的 jclass 对象。然后获得该对象的全局引用,并将本地引用删除。 这些方法的调用都要做异常判断,如果出现异常所有的结果都是无效的值。...获得了 jclass 后,就可以通过 GetMethodID 获取类方法的jmethodID对象。 .........非常简单,JNI调用 GetField或SetField方法获取或设置Java的字段。 至此我们就分析完了 ijkplayer 对 JNI的使用。
领取专属 10元无门槛券
手把手带您无忧上云