首页
学习
活动
专区
圈层
工具
发布
    • 综合排序
    • 最热优先
    • 最新优先
    时间不限
  • 来自专栏进击的多媒体开发

    JNI编程如何巧妙获取JNIEnv

    JNIEnv的指针呢? 解决:使用JavaVM,这里先介绍下JNIEnv和JavaVM的概念。 JNIEnv:Java调用Native语言的环境,是一个封装了几乎所有JNI方法的指针,每一个Java线程都有一个对应的JNIEnvJNIEnv只在当前线程可用,不能跨线程使用,不同线程的JNIEnv 方法二:通过JNIEnv获取JavaVM,在程序的最开始写一个类似于初始化功能的函数,传到Native层一个可用的JNIEnv,之后就可以获取到JavaVM。 JavaVM *global_jvm; void get_jvm(JNIEnv *env) { env->GetJavaVM(&global_jvm); } 如何通过JavaVM获取JNIEnv

    5K30发布于 2020-06-24
  • 来自专栏韩曙亮的移动开发专栏

    【Android 系统开发】Android JNI 之 JNIEnv 解析

    JNIEnv 作用 JNIEnv 概念 : 是一个线程相关的结构体, 该结构体代表了 Java 在本线程的运行环境 ;  JNIEnv 与 JavaVM : 注意区分这两个概念;  -- JavaVM JNIEnv 体系结构  线程相关 : JNIEnv 是线程相关的, 即 在 每个线程中 都有一个 JNIEnv 指针, 每个JNIEnv 都是线程专有的, 其它线程不能使用本线程中的 JNIEnv, 线程 A 不能调用 线程 B 的 JNIEnv; JNIEnv 不能跨线程 :  -- 当前线程有效 : JNIEnv 只在当前线程有效, JNIEnv 不能在 线程之间进行传递, 在同一个线程中, 多次调用 JNI层方法, 传入的 JNIEnv 是相同的; -- 本地方法匹配多JNIEnv : 在 Java 层定义的本地方法, 可以在不同的线程调用, 因此 可以接受不同的 JNIEnv; JNIEnv 结构体指针, 说明 C++ 环境的 JNIEnv 是在 C 语言环境的 JNIEnv 下扩展的; -- 解析 JNIEnv* : 定义是这样的 typedef _JNIEnv JNIEnv, JNIEnv

    50831编辑于 2023-03-27
  • 来自专栏along的开发之旅

    JNI|在子线程中获得JNIEnv|AttachCurrentThread

    A JNI interface pointer (JNIEnv*) is passed as an argument for each native function mapped to a Java Call_Back_Invoke( void *user,int notify_id, unsigned int param ) {     bool  isAttacked = false;     JNIEnv ; return NPT_FAILURE; } int status; JNIEnv *env = NULL; bool isAttach = false

    4.4K10发布于 2019-06-14
  • 来自专栏along的开发之旅

    JNI|在子线程中获得JNIEnv|AttachCurrentThread

    A JNI interface pointer (JNIEnv*) is passed as an argument for each native function mapped to void Call_Back_Invoke( void *user,int notify_id, unsigned int param ) { bool isAttacked = false; JNIEnv

    1.4K20发布于 2019-05-26
  • 来自专栏韩曙亮的移动开发专栏

    【Android NDK 开发】JNI 线程 ( JNI 线程创建 | 线程执行函数 | 非 JNI 方法获取 JNIEnv 与 Java 对象 | 线程获取 JNIEnv | 全局变量设置 )

    线程方法获取 JNIEnv ---- 线程中获取 JNIEnv * env 步骤 : ① JNIEnv 无法跨线程 : JNI 方法参数中的 JNIEnv 指针是不能跨线程使用的 , 在 主线程中调用 JNI 方法 , 其 JNIEnv 指针不能在子线程中使用 ; ② 获取途径 : 如果在子线程中使用 JNIEnv 指针 , 需要使用 JavaVM 获取 指定线程的 JNIEnv 指针 ; ③ 绑定线程 : 调用 JavaVM 的 AttachCurrentThread 方法 , 可以绑定线程 , 其传入一个 JNIEnv ** 二维指针 , 会返回该线程对应的 JNIEnv 指针 ; ④ 剥离线程 在 主线程中调用 JNI 方法 , 其 JNIEnv 指针不能在子线程中使用 如果在子线程中使用 JNIEnv 指针 , 需要使用 JavaVM 获取 指定线程的 JNIEnv 指针 不能跨线程使用 , 这里需要先获取本线程的 JNIEnv JNIEnv *env; //将线程附加到 Java 虚拟机中 ( 注意后面对应剥离线程操作 ) // 如果成功返回

    1.3K20编辑于 2023-03-27
  • 来自专栏韩曙亮的移动开发专栏

    【Android NDK 开发】JNI 方法解析 ( JNIEnv *env 参数 )

    文章目录 一、 JNI 方法解析 二、 JNIEnv *env 参数解析 三、 C 语言 环境中 JNIEnv *env 参数解析 四、 C ++ 环境中 JNIEnv *env 参数解析 总结 : JNI JNIEnv 类型声明 : #if defined(__cplusplus) typedef _JNIEnv JNIEnv; typedef _JavaVM JavaVM; #else typedef JNINativeInterface* JNIEnv; ② C ++ 别名 : C ++ 中 , 将 _JNIEnv 结构体类型声明为 JNIEnv 类型 ; typedef _JNIEnv JNIEnv C++ 环境中 _JNIEnv 类型 : 在 C++ 中 , 将 _JNIEnv 结构体类型 通过 typedef 为其声明别名 JNIEnv ; 2 . C ++ 语言环境中 , 调用 _JNIEnv 结构体中的函数 : ① 类型转换 : 给定的参数是 JNIEnv *env 类型的 , 即 _JNIEnv * env 类型 ; ② 通过 _JNIEnv

    1.3K10编辑于 2023-03-27
  • 来自专栏刘望舒

    Android深入理解JNI(二)类型转换、方法签名和JNIEnv

    3.JNIEnv JNIEnv 是一个指向全部JNI方法的指针,该指针只在创建它的线程有效,不能跨线程传递,因此,不同线程的JNIEnv是彼此独立的,JNIEnv的主要作用有两点: 1.调用Java的方法 先来看JNIEnv的定义,如下所示。 libnativehelper/include/nativehelper/jni.h ? 通过JavaVM的AttachCurrentThread函数可以获取这个线程的JNIEnv,这样就可以在不同的线程中调用Java方法了。 jfieldID和jmethodID 在JNI中用jfieldID和jmethodID来代表Java类中的成员变量和方法,可以通过JNIEnv的下面两个方法来分别得到: ? 同理,如果想要访问Java的方法则可以使用JNIEnv的CallVoidMethod函数。

    2.6K60发布于 2018-02-01
  • 来自专栏全栈程序员必看

    NDK学习笔记:线程JNIEnv,JavaVM,JNI_OnLoad(GetEnv返回NULL?FindClass返回NULL?)

    NDK学习笔记:线程JNIEnv,JavaVM,JNI_OnLoad 此文章是关于NDK线程的第二篇理论知识笔记。 线程中如何获取JNIEnv?GetEnv返回NULL? FindClass返回NULL ? 每一个执行绪在呼叫native函数时,所传递进来的JNIEnv指标值都是不同的。 但是我们必须知道:VM是多执行绪(Multi-threading) ,每个JNIEnv都是不同的!特别是在不同线程,都是独自维护各自独立的JNIEnv。 那么问题又回到最初的? 怎么正确的获取线程安全的JNIEnv

    4K41编辑于 2022-07-30
  • 来自专栏difcareer的技术笔记

    JNI实现源码分析【二 数据结构】正文0x01: 虚拟机中的对象0x02: Dex相关的结构0x03: 实现JNI需要的数据结构0x04: JNI参数传递的数据结构

    JNIEnv typedef const struct JNINativeInterface* JNIEnv; JNIEnv是一个JNINativeInterface类型的指针 e. (*GetSuperclass)(JNIEnv*, jclass); jboolean (*IsAssignableFrom)(JNIEnv*, jclass, jclass) )(JNIEnv*); void (*ExceptionClear)(JNIEnv*); void (*FatalError)(JNIEnv*, const char*); jint (*PushLocalFrame)(JNIEnv*, jint); jobject (*PopLocalFrame)(JNIEnv*, )(JNIEnv*, jint); jobject (*AllocObject)(JNIEnv*, jclass); jobject (*NewObject)(JNIEnv

    1.9K30发布于 2018-08-23
  • 来自专栏韩曙亮的移动开发专栏

    【Android FFMPEG 开发】C++ 回调 Java 方法 模板 ( JavaVM *vm | JNIEnv *env | jobject instance | 引用类型 | 模板代码示例 )

    JNIEnv *env 与 jobject instance ---- 1 . 调用 Java 方法所需参数 : 调用 Java 方法需要 JNIEnv *env 参数 和 对应的 jobject instance Java 类参数 ; ① JNIEnv *env : JNI 环境 子线程 JNIEnv *env 获取方法 : 需要使用 JavaVM *vm 获取 , 即 Java 虚拟机参数 ; 获取流程如下 : ① 声明子线程 JNIEnv* 指针 ; ② Java 虚拟机 调用附加线程的方法 ; //子线程 : 需要通过 JavaVM * 获取该子线程的 JNIEnv * JNIEnv *env_thread; //Java 虚拟机 调用附加线程的方法 Native 调用 Java 方法 ( 子线程 ) ---- 子线程需要通过 JavaVM * 获取该子线程的 JNIEnv * , 然后通过子线程的 JNIEnv * 调用 Java 方法 ;

    1.4K20编辑于 2023-03-27
  • 来自专栏字节流动

    深入 Android 系统 - Android 的 JNI

    复制代码 JNI 环境 结构体 JNIEnv JNIEnv 是代表JNI环境的结构体,定义如下: struct _JNIEnv; struct _JavaVM; typedef const struct JNINativeInterface* C_JNIEnv; #if defined(__cplusplus) typedef _JNIEnv JNIEnv; typedef _JavaVM JavaVM 在C++部分,JNIEnv相当于_JNIEnv,我们看下_JNIEnv定义: struct _JNIEnv { /* do not rename this; it does not seem to JNIEnv 的创建和初始化 JNIEnv是JNI的使用环境。 JNIEnv 对象的初始化总结 对于JNIEnv对象的初始化就两点: 主线程中的JNIEnv对象在创建虚拟机时就已经建好了 Java 中新建线程的JNIEnv对象是在该线程运行时建立的,并在线程结束时释放

    2.4K40编辑于 2022-09-26
  • 来自专栏曾大稳的博客

    mediacodec解码ffmpeg AvPacket

    *jniEnv; if(javaVM->AttachCurrentThread(&jniEnv, 0) ! ->NewStringUTF(mime); jbyteArray csd0 = jniEnv->NewByteArray(csd0_size); jniEnv->SetByteArrayRegion (csd1_size); jniEnv->SetByteArrayRegion(csd1, 0, csd1_size, reinterpret_cast<const jbyte *>(csd_1 )); jniEnv->CallVoidMethod(jobj, jmid_initmediacodec, type, width, height, csd0, csd1); jniEnv ->DeleteLocalRef(csd0); jniEnv->DeleteLocalRef(csd1); jniEnv->DeleteLocalRef(type); javaVM

    1.9K40发布于 2018-09-11
  • 来自专栏韩曙亮的移动开发专栏

    【Android NDK 开发】JNI 方法解析 ( C/C++ 调用 Java 方法 | 函数签名 | 调用对象方法 | 调用静态方法 )

    (JNIEnv*, jobject, jmethodID, const jvalue*); jboolean (*CallBooleanMethod)(JNIEnv*, jobject, )(JNIEnv*, jobject, jmethodID, ...); jbyte (*CallByteMethodV)(JNIEnv*, jobject, jmethodID, (*CallCharMethod)(JNIEnv*, jobject, jmethodID, ...); jchar (*CallCharMethodV)(JNIEnv*, jobject )(JNIEnv*, jclass, jmethodID, const jvalue*); jshort (*CallStaticShortMethod)(JNIEnv*, jclass )(JNIEnv*, jclass, jmethodID, ...); jint (*CallStaticIntMethodV)(JNIEnv*, jclass, jmethodID

    10K40编辑于 2023-03-27
  • 来自专栏韩曙亮的移动开发专栏

    【Android 应用开发】Android 开发 之 JNI入门 - NDK从入门到精通

    JNIEnv 详解 JNIEnv作用 : JNIEnv 是一个指针,指向了一组JNI函数, 这些函数可以在jni.h中查询到,通过这些函数可以实现 Java层 与 JNI层的交互 , 通过JNIEnv (1) JNIEnv的C/C++声明 jni.h中声明JNIEnv : C语言中定义的JNIEnv 是 JNINativeInterface* , C++中定义的JNIEnv 是 _JNIEnv; ) //为了兼容C 和 C++两种代码 使用该 宏加以区分 typedef _JNIEnv JNIEnv; //C++ 中的JNIEnv类型 typedef _JavaVM JavaVM; #else * JavaVM; #endif (2) C语言中的JNIEnv 关于JNIEnv指针调用解析 : C中JNIEnv就是 const struct JNINativeInterface*, JNIEnv (3) C++中的JNIEnv C++ 中的JNIEnv: C++ 中的JNIEnv 就是 _JNIEnv 结构体, 二者是等同的; 因此在调用 JNI函数的时候, 只需要使用 env->NewStringUTF

    4K11编辑于 2023-03-27
  • 来自专栏后端码匠

    【Android】JNI静态与动态注册介绍

    ++ extern "C" JNIEXPORT jstring JNICALL Java_cn_com_codingce_ndkpractice_MainActivity_stringFromJNI(JNIEnv *jniEnv) { if (jniEnv == nullptr) { return; } jclass clazz = nullptr; do { jniEnv->ExceptionClear(); } if (clazz ! 函数 JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void *reserved) { JNIEnv *jniEnv{nullptr}; if (vm->GetEnv((void **) &jniEnv, JNI_VERSION_1_6) !

    1.3K30编辑于 2023-02-27
  • 来自专栏Android 研究

    Android JNI(一)——NDK与JNI基础

    下面我们来重点说一下JNIEnv 2、JNIEnv JNIEnv是当前Java线程的执行环境,一个JVM对应一个JavaVM结构,而一个JVM中可能创建多个Java线程,每个线程对应一个JNIEnv结构 JNIEnv:JavaVM 在线程中的代码,每个线程都有一个,JNI可能有非常多个JNIEnv; 2.3、JNIEnv的作用: 调用Java 函数:JNIEnv代表了Java执行环境,能够使用JNIEnv 调用Java中的代码 操作Java代码:Java对象传入JNI层就是jobject对象,需要使用JNIEnv来操作这个Java对象 2.4、JNIEnv的创建与释放 2.4.1、JNIEnv的创建 JNIEnv DetachCurrentThread(this); } 方法,就可以释放 本线程的JNIEnv 2.5、JNIEnv与线程 JNIEnv是线程相关的,即在每一个线程中都有一个JNIEnv指针,每个JNIEnv JNIEnv只在当前线程有效:JNIEnv仅仅在当前线程有效,JNIEnv不能在线程之间进行传递,在同一个线程中,多次调用JNI层方便,传入的JNIEnv是同样的 本地方法匹配多个JNIEnv:在Java

    9K32发布于 2018-08-30
  • 来自专栏Android开发实战

    JNI开发总结

    , "JNIMsg", "getName ---- > %s",cstr ); //释放资源 (*jniEnv)->ReleaseStringUTFChars(jniEnv, jstr, cstr) ; (*jniEnv)->DeleteLocalRef(jniEnv, jstr); 释放 类 、对象、方法 (*jniEnv)->DeleteLocalRef(jniEnv, XXX);//“XXX” 代表 引用对象 释放 数组家族 jobjectArray arrays = NULL; jclass jclsStr = NULL; jclsStr = (*jniEnv)->FindClass(jniEnv , "java/lang/String"); arrays = (*jniEnv)->NewObjectArray(jniEnv, len, jclsStr, 0); (*jniEnv)->DeleteLocalRef (jniEnv, jclsStr); //释放String类 (*jniEnv)->DeleteLocalRef(jniEnv, arrays); //释放jobjectArray数组 native

    1.9K41发布于 2018-10-22
  • 来自专栏李蔚蓬的专栏

    Tip | JNI数据类型与指针嵌套

    像图中的CallObjectMethod()、CallIntMethod()等这里写的这些方法其实只是一个调用而已, 这些方法在NDK的工具集里面已经实现好了; JNIEnv //JNIEnv结构体的指针别名 typedef struct MYJNINativeInterface_* JNIEnv; JNIEnv就是JNI获取Java对象、Java变量的一个上下文环境: ? _* JNIEnv; //结构体 struct MYJNINativeInterface_ { //函数声明 char* (*NewStringUTF)(JNIEnv*,char*); }; //函数实现 char* NewStringUTF(JNIEnv* env, char* str){ //在NewStringUTF执行过程,仍然需要JNIEnv return str; } //JNIEnv 就是一级结构体指针 //JNIEnv* 则是二级结构体指针 void main(){ //实例化结构体 struct MYJNINativeInterface

    91110发布于 2020-05-29
  • 来自专栏曾大稳的博客

    jni基础

    _; struct JNIEnv_; #ifdef __cplusplus //如果是c++就是JNIEnv_对象 JNIEnv_对象里面其实也是通过JNINativeInterface_调用 typedef JNIEnv_ JNIEnv; #else //如果是c的话就是JNINativeInterface_指针 typedef const struct JNINativeInterface _ *JNIEnv; #endif struct JNIEnv_ { const struct JNINativeInterface_ *functions; // .... *JNIEnv; // 模拟一个结构体 struct JNINativeInterface{ // 结构体的方法指针 char*(*NewStringUTF)(JNIEnv*,char*); }; * JNIEnv env = &nativeInterface;// 一级指针 JNIEnv* jniEnv = &env;// 二级指针 // 把 jniEnv 对象传给 Java_com_darren_ndk12

    93620发布于 2018-09-11
  • 来自专栏码上就说

    关于JNI开发的一些建议

    JNIEnv和线程相关,一个线程对应一个JNIEnv,如果想要切换到当前线程的JNIEnv,首先通过JavaVM获取JNIEnv,然后调用JavaVM的AttachCurrentThread来切换到对应线程的 JNIEnv,使用完了之后还要DetachCurrentThread切走。 每个线程缓存JNIEnv 每个线程都缓存自己的JNIEnv实例表明如果这个线程attach到JavaVM的时候就将获取的JNIEnv保存起来,等会销毁这个线程的时候才将JNIEnv实例DetachCurrentThread 使用时获取JNIEnv 还有一种方式就是每个需要使用JNIEnv的实例的时候Attach,用完之后立即Detach。 因为JNIEnv不是缓存下来的,每次获取的JNIEnv实例都是不同的,如果需要调用Java层类中static方法,使用第二种方法调用会出现ClassNotFound的问题,为什么会出现这种现象了,因为JNIEnv

    1.2K10编辑于 2022-05-25
领券