Android Java与JNI层互传数据总结

Android Studio开发之 从Java层传参数到JNI层 如题: 1、新建一个Java层的class来做测试 传递对象,将一个int类型数据和一个byte数组数据传到JNI去玩耍! package com.example.android_params; public class Jimmy_Params { int nID; byte []szSrc; } 2、JNI接口类: package com.example.and... 阅读详情

在开发中常常会遇到从Java层传递数据到JNI层,然后在JNI拿到数据后就可以用C语言进行操作了,操作完数据后通常还需要把处理后的数据传回Java层。下面分别进行小结。

从Java层传到JNI层

  • 使用GetByteArrayRegion的方式。
    该方法的本质是将Java端数组数据拷贝到本地的数组中,所以在JNI对数据修改后Java端的数据并没有改变。
  • 使用GetPrimitiveArrayCritical。
    GetPrimitiveArrayCritical 表面上可以得到底层数据指针,在JNI层修改数组时Java层的数据也会变。But,如果只使用GetPrimitiveArrayCritical获取数据,程序运行一段时间内存会crash。所以,使用GetPrimitiveArrayCritical时必须使用ReleasePrimitiveArrayCritical ,通过测试发现当数据量大时执行ReleasePrimitiveArrayCritical会非常耗时。

从JNI层传到Java层

  • 把Jni层的数组传递到Java层,一般有两种方法,一种是通过native函数的返回值来传递,另一种是通过jni层回调java层的函数来传递,后者多用于jni的线程中或是数据量较大的情况。无论哪种方法,都离不开 SetByteArrayRegion 函数,该函数将本地的数组数据拷贝到了 Java 端的数组中。

注意上面的方式中都会涉及到内存拷贝,根据实战经验,在Android系统中,一旦数据量变大,拷贝一次内存将非常耗时。所以上述方式在追求效率时不推荐使用。解决的方法可以尝试让JAVA层和JNI共享内存的方式。最后找到了两种方式。


Java层和JNI层共享内存空间

  • 使用GetByteArrayElements方式
    该方式是指针的形式,将本地的数组指针直接指向Java端的数组地址,其实本质上是JVM在堆上分配的这个数组对象上增加一个引用计数,保证垃圾回收的时候不要释放,从而交给本地的指针使用,使用完毕后指针一定要记得通过ReleaseByteArrayElements进行释放,否则会产生内存泄露。

    unsigned char* psrcImg = (unsigned char*)(env->GetByteArrayElements(srcImg,0));  
    unsigned char* pBufferI420 = (unsigned char*) (env->GetByteArrayElements(dstImg,0));
    
    if (psrcImg == NULL || pBufferI420 == NULL)
    {
      return -1;
    }
    env->ReleaseByteArrayElements(srcImg,(jbyte*)psrcImg,0);
    env->ReleaseByteArrayElements(dstImg,(jbyte*)pBufferI420,0);

    注意if那里最好加上,网上查了说,get那里可能失败,失败得到的psrcImg是NULL,Release的时候程序就会崩。

  • Direct Buffer 方式传递。
    Java和Jni层的数组传递还有一个比较重要的方式,就是通过Direct Buffer来传递,这种方式类似于在堆上创建创建了一个Java和Jni层共享的整块内存区域,无论是Java层或者Jni层均可访问这块内存,并且Java端与Jni端同步变化,由于是采用的是共享内存的方式,因此相比于普通的数组传递,效率更高,但是由于构造/析构/维护这块共享内存的代价比较大,所以小数据量的数组建议还是采用上述方式,Direct Buffer方式更适合长期使用频繁访问的大块内存的共享。具体可使用GetDirectBufferAddress获得共享的内存地址。

综上,在图像算法开发中,我采用了GetByteArrayElements-ReleaseByteArrayElements的方式来传递图像数据。此外,在开发Android上的算法时,尽量避免内存拷贝,特别是JNI层。

Reference:
http://blog.youkuaiyun.com/xinchen200/article/details/25333047
http://zsaber.com/blog/p/107

Android Studio下JNI编程2(接上篇,详细讲解java与c层互传参数) Android Studio下JNI环境搭建、编译、运行等可以参考: http://blog.youkuaiyun.com/huangximin1990/article/details/50441400 上篇文章讲述的JNI示例编程主要涉及两个文件: NativeKit.java cn_com_losy_jnitest_jni_NativeKit.cpp NativeKit. 阅读详情

相关推荐

android studio创建NDK项目流程

1.android studio新建NDK项目 ①.创建新的项目,然后选择最下面的Native C++ ②.然后一路next,最后点finish ③.下面项目就是显示一个字符串,字符串是native底层返回的 ④.运行结果如下: ⑤.build.gradle中cmake相关编译内容,其实真正native层编译还是在cmake中进行的 ⑥.刚运行的编译so包产物位置 2.CMake编译 ①.编译so包 ②.cmake相关编译so包讲解 ​​​注意真...

龚礼鹏的博客 4314

android---JNI:GetPrimitiveArrayCritical 错误

android---JNI:GetPrimitiveArrayCritical 调用易错解析

Trent1985的专栏 3554

COMSOL多物理场仿真:瓷绝缘子电热耦合建模与优化策略

本文详细介绍了使用COMSOL Multiphysics进行瓷绝缘子电热耦合仿真的完整流程与优化策略。文章阐述了电热耦合效应的工程意义,并逐步讲解了从几何建模、材料定义、物理场设置到边界条件与网格划分的关键步骤。重点分析了如何通过焦耳热耦合实现电场与温度场的双向交互,以及如何利用仿真结果进行参数化优化和瞬态故障模拟,为提升电力设备可靠性提供有效的数字化设计工具。

n8m7b6v5c4的博客 883

Java 之JNI基础篇(二)

上一篇完成了JNI流程的编写,现在来看看javah命令生成的本地方法 #include #include #include "Hello.h" JNIEXPORT void JNICALL Java_com_test_JniUtil_sayHello (JNIEnv *env, jobject jobj){ printf("Hello Word!\n"); } 可以看到,在C

编程之路的专栏 1万+

从Chimera到ChimeraX:科研绘图升级指南,让你的论文配图更专业

本文详细介绍了从UCSF Chimera升级到ChimeraX的科研绘图指南,帮助研究者提升论文配图质量。ChimeraX在渲染引擎、大分子处理能力和动画功能上具有显著优势,特别适合生命科学和结构生物学领域。文章涵盖材质设置、专业配色、工作流程和期刊适配等核心技巧,助力产出出版级分子可视化图像。

weixin_33670786的博客 928

雷达气象学(8)——反射率因子图实战(强对流预警篇)

本文聚焦雷达反射率因子图在强对流预警中的实战应用,深入解析了柱状回波、有界弱回波区(BWER)、三体散射(TBSS)等关键回波结构特征,这些是识别超级单体风暴和大冰雹的核心“身份证”。文章强调从静态识别转向动态追踪与多源数据综合研判的思维转变,并提供了系统的实战分析流程与常见误区避坑指南,旨在提升对强对流天气的短临预警能力。

weixin_29213827的博客 485

java jni c 指针_通过JNI传递C和Java之间的指针

目前,我正在尝试创建一个使用CUDA功能的Java应用程序。CUDA和Java之间的连接工作很好,但是我有另一个问题,我想问一下,如果我的想法是正确的。当我从Java调用一个本地函数时,我将一些数据传递给它,函数计算某个结果并返回结果。有没有可能,让第一个函数返回一个对这个结果的引用(指针),我可以把它传递给JNI,并调用另一个函数,用这个结果做进一步的计算?我的想法是通过将数据保留在GPU内存中...

weixin_39977934的博客 1384

避坑指南:RFSoC数据转换器多片同步配置的7个致命错误

本文深入剖析了在配置RFSoC多片同步功能时,工程师最常遇到的七个致命错误。从Tile 0的强制启用、时钟域与SYSREF时序,到跨代器件兼容性、电源序列以及动态重配置的陷阱,文章结合实战经验,提供了从原理到调试的完整RF数据转换器配置指南,旨在帮助开发者高效构建相位一致的大规模射频采样系统。

weixin_28452161的博客 533

Android For JNI(三)——C的指针,指针变量,指针常见错误,值传递,引用传递,返回多个值...

Android For JNI(三)——C的指针,指针变量,指针常见错误,值传递,引用传递,返回多个值 C中比较难的这一块,大概就是指针了,所以大家还是多翻阅一下资料,当然,如果只是想了解一下,看本篇也就够了,不过我也尽量陈述的很详细 一.指针 要说指针,其实通俗易懂的话来说,他应该是保存内存地址的一个变量,我们来...

weixin_33738555的博客 571

基于STM32的智能垃圾分类机器人

垃圾分类是城市管理的重要环节,传统人工分拣效率低、成本高。本文设计了一款基于STM32的智能垃圾分类机器人,通过视觉识别与机械臂协同作业,实现垃圾自动分类与投放,适用于社区、公共场所等场景,可显著提升垃圾分类效率。:STM32H743(480MHz Cortex-M7,支持AI加速)本系统实现了垃圾分拣的自动化,显著提升了分类效率。OV5640摄像头(500万像素,支持JPEG输出)支持4类垃圾识别(可回收/厨余/有害/其他)问题讨论,stm32的资料领取可以私信!超声波避障(探测距离0.1-4m)

stm32d1219的博客 1820

大模型——AI对话四象限

{ "摘要": "文章揭示了90%的人不会有效与AI沟通的问题,指出简单粗暴的提问只能得到标准答案。作者提出'AI对话四象限'模型:1)双方都懂时提效;2)AI懂但需学会分层提问;3)共同探索未知领域;4)向AI传授独家知识。强调沟通技巧的重要性,认为会提问的人不会被AI替代。最后呼吁读者尝试四象限思维,与AI碰撞火花。" }

311

java与jni共享内存_Android Java与JNI层互传数据总结

在开发中常常会遇到从Java层传递数据到JNI层,然后在JNI拿到数据后就可以用C语言进行操作了,操作完数据后通常还需要把处理后的数据传回Java层。下面分别进行小结。从Java层传到JNI层使用GetByteArrayRegion的方式。该方法的本质是将Java端数组数据拷贝到本地的数组中,所以在JNI对数据修改后Java端的数据并没有改变。使用GetPrimitiveArrayCritical...

weixin_42396174的博客 1375

DeepSeek-OCR安装部署文档和避坑指南,包含大多数人遇到的安装报错问题

DeepSeek-OCR安装部署指南摘要:本文详细介绍高性能OCR工具DeepSeek-OCR的安装流程,支持多语言识别和复杂场景文字提取。系统要求包括Linux/Windows/macOS操作系统,推荐NVIDIA显卡(显存≥6GB)和≥16GB内存。安装步骤涵盖:1)创建conda虚拟环境;2)安装PyTorch等核心依赖;3)解决常见问题如CUDA版本冲突、模型下载慢等。提供GPU内存不足等问题的解决方案,帮助开发者快速部署OCR服务。(149字)

yolo模型训练找我,AI游戏合作找我 2945

Android的jni下c与java数据互传测试代码

test.java public class test { public native String test(); public native byte[] testbyte(byte[] by); }hello.c #include #include #include "com_example_jnitest_test.h" #include #include #define

shareinfo2018 1079

电机驱动器MP6540H应用设计

/ ... 其他初始化函数(SystemClock_Config, MX_GPIO_Init, MX_TIM1_Init, MX_TIM2_Init)需要你根据STM32CubeMX生成或手动编写。// 假设霍尔传感器引脚是 GPIO_PIN_8, GPIO_PIN_9, GPIO_PIN_10。// 低侧U相GPIO引脚。

zhusl6688的博客 660

visio安装包

Microsoft Office Visio 是一款专业的制图软件。利用经过更新的形状、协作工具和数据链接图表,创建专业级图表以简化复杂的信息。

android 中java与JNI数据交互

在android编程中,经常要使用到JNI调用native方法,这时就无法避免要解决java与native数据交互的问题。 下面是一个数据从java传递给JNI,处理之后在传递给java数据的例子(java ->JNI ->java) 在java中定义一个本地方法: public native int DevICCardThreadCommand(byte cardno,byte[] w

Young的专栏 3408

蓝牙模块HM-10手册

蓝牙模块HM-10手册,该手册对蓝牙模块HM-10进行了详细的介绍和使用方法以及一些AT指令。

cocos2d-x 通过JNI实现c/c++和Android的java层函数互调

本文主要实现两个功能: (1)通过Android sdk的API得到应用程序的包名(PackageName),然后传递给c++层函数。 (2)通过c++函数调用Android的java层函数,显示一个对话框,点击按钮退出程序。 1. 首先来简单学习一下JNI的相关知识,我这篇文章中简单实现了怎么在Android Java层调用c++函数。要想使用JNI,必须得包含头文件,android是使用

峻峰飞阳的博客 blog.youkuaiyun.com/while0 1703

假人有限元模型

假人模型,车辆碰撞假人有限元模型,适合做乘员安全的研究者利用

怀旧版电脑GBC模拟器

再现原版GBC掌机的界面,电脑运行连游戏界面都一样大小,很怀旧,很真实,(英文版)强烈推荐,很小的文件,很难才找到的。

java android接参_android-jni与java参数传递 | 学步园

android-jni与java参数传递===================================================================================================问题的来源:jni与java层之间互传参数,有几个问题需要解决:1、需要传递的参数的函数非常多,达到100个左右2、传递的参数有些比较复杂,涉及到结构的嵌套3、参...

weixin_29619665的博客 218

JNI学习———集合对象的互传

前言 关于JNI/NDK的博客,开发指南等网上都有很多资源,而且这篇博客的主要内容是关于集合对象的互传,所以就不再介绍了。 附上一个开发指南开发指南链接。 Java层传递集合对象到Native层 在java层新建一个简单的类 public class Test { private int a; static int num = 1; public T...

奇妙能力倩 1037

JNI问题

1.java.lang.UnsatisfiedlinkError: Native method not found 关于这个问题,网上已经有许多人遇到并列出最后解决办法。却于我无用,最后才发现,在java层声明了JNI 函数接口(JNI层有实现),却没有使用它,导致编译器连它后面的jni函数都不“加载”进来,一调用它后面的函数就报java.lang.UnsatisfiedlinkError: N

hhbgk的专栏 525

Android音频播放有杂音?原来是这个JAVA API接口惹的祸

一个Android音频应用中使用ByteBuffer接口导致数据丢失的问题的分析与处理。

wwwyuewww的专栏 3164

android-jni与java参数传递

android-jni与java参数传递

张同光 (Tongguang Zhang):Hello everyone ! 402

Android-NDK开发之基础--Android JNI有关Java类命名方式

原文地址:http://blog.youkuaiyun.com/geolo/article/details/6168536 (Ljava/lang/String;I)V   其中本句  I = Integer B = Byte S = Short C = Char LXXX; = L加上类名       3. 在JNI下面,我们常用的命名方式:     static JavaVM

知至智 567

Android使用JNI实现Java与C之间传递数据

介绍Java如何将数据传递给C和C回调Java的方法。 java传递数据给C,在C代码中进行处理数据,处理完数据后返回给java。C的回调是Java传递数据给C,C需要用到Java中的某个方法,就需要调用java的方法。 Android中使用JNI七个步骤: 1.创建一个android工程 2.Java代码中写声明native 方法 public native String helloF...

weixin_34217773的博客 168
上一篇: 在Android和iOS中读取静态图像
下一篇: Mac平台下QT+Opencv 环境搭建
IT修道者
IT修道者 领域专家: 人工智能技术领域 领域专家: 人工智能技术领域
博客等级 码龄17年 326粉丝 95原创
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值