Android JNI(一):JNI基础概念

2023-11-10

本文讲述:
NDK和JNI是什么,JNI的原理,JNI开发流程的步骤,认识JNI相关的代码语法

名称概念
什么是NDK?
NDK 其中NDK的全拼是:Native Develop Kit。

Android NDK 就是一套工具集合,允许你使用C/C++语言来实现应用程序的部分功能。

大家都知道,Android 开发语言是Java,不过我们也知道,Android是基于Linux的,其核心库很多都是C/C++的,比如Webkit等。那么NDK的作用,就是Google为了提供给开发者一个在Java中调用C/C++代码的一个工作。NDK本身其实就是一个交叉工作链,包含了Android上的一些库文件,然后,NDK为了方便使用,提供了一些脚本,使得更容易的编译C/C++代码。总之,在Android的SDK之外,有一个工具就是NDK,用于进行C/C++的开发。一般情况,是用NDK工具把C/C++编译为.so文件,然后在Java中调用。

为什么要用NDK?
1、在平台之间移植其应用
2、重复使用现在库,或者提供其自己的库重复使用
3、在某些情况下提性能,特别是像游戏这种计算密集型应用
4、使用第三方库,现在许多第三方库都是由C/C++库编写的,比如Ffmpeg这样库。
5、不依赖于Dalvik Java虚拟机的设计
6、代码的保护。由于APK的Java层代码很容易被反编译,而C/C++库反编译难度大。

在这里插入图片描述
从上图这个Android系统框架来看,我们上层通过JNI来调用NDK层的,使用这个工具可以很方便的编写和调试JNI的代码。

什么是JNI?
JNI,全称为Java Native Interface,即Java本地接口。
在这里插入图片描述
通过JNI可以使得Java与C/C++机型交互。即可以在Java代码中调用C/C++等语言的代码或者在C/C++代码中调用Java代码。

JNI下一共涉及到三个角色:C/C++代码、本地方法接口类、Java层中具体业务类。

JNI简要流程
在这里插入图片描述

JNI原理
JNI开发流程的步骤:
第1步:在Java中先声明一个native方法
第2步:编译Java源文件javac得到.class文件
第3步:通过javah -jni命令导出JNI的.h头文件
第4步:使用Java需要交互的本地代码,实现在Java中声明的Native方法(如果Java需要与C++交互,那么就用C++实现Java的Native方法。)
第5步:将本地代码编译成动态库(Windows系统下是.dll文件,如果是Linux系统下是.so文件,如果是Mac系统下是.jnilib)
第6步:通过Java命令执行Java程序,最终实现Java调用本地代码。
在这里插入图片描述
JNI结构
在这里插入图片描述
这张JNI函数表的组成就像C++的虚函数表。虚拟机可以运行多张函数表,举例来说,一张调试函数表,另一张是调用函数表。JNI接口指针仅在当前线程中起作用。这意味着指针不能从一个线程进入另一个线程。然而,可以在不同的线程调用本地方法。

在这里插入图片描述
基本概念

Java语言的执行环境是Java虚拟机(JVM),JVM其实是主机环境中的一个进程,每个JVM虚拟机都在本地环境中有一个JavaVM结构体
1、JavaVM
JavaVM是Java虚拟机在JNI层的代表,JNI全局仅仅有一个JavaVM结构中封装了一些函数指针(或叫函数表结构),JavaVM中封装的这些函数指针主要是对JVM操作接口
2、JNIEnv
JNIEnv是一个线程相关的结构体,该结构体代表了Java在本线程的执行环境

JNIEnv的作用:

调用Java 函数:JNIEnv代表了Java执行环境,能够使用JNIEnv调用Java中的代码
操作Java代码:Java对象传入JNI层就是jobject对象,需要使用JNIEnv来操作

这个Java对象

JNIEnv和JavaVM的区别:
JavaVM:JavaVM是Java虚拟机在JNI层的代表,JNI全局仅仅有一个
JNIEnv:JavaVM 在线程中的代码,每个线程都有一个,JNI可能有非常多个JNIEnv;

JNI的命名规则
通过javah -jni命令导出JNI的.h头文件

示例代码

jdouble Java_com_example_hellojni_MainActivity_stringFromJNI (JNIEnv *env, jobject obj, jint i, jstring s)
{
     const char *str = (*env)->GetStringUTFChars(env, s, 0); 
     (*env)->ReleaseStringUTFChars(env, s, str); 
     return 10;
}

里面的方法入参,我们就依次来看下:
jdouble 是返回值类型
Java_com_example_hellojni 是包名
MainActivity 是类名
stringFromJNI 是方法名
其中JNIExport和JNICALL是不固定保留的关键字不要修改

*env:一个接口指针
obj:在本地方法中声明的对象引用
i和s:用于传递的参数
关于obj、i和s的类型大家可以参考下面的JNI数据类型,JNI有自己的原始数据类型和数据引用类型如下:

在这里插入图片描述
参考资料:

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

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Android JNI(一):JNI基础概念 的相关文章

  • 在名称中使用时间戳时,Android Studio 在构建后无法启动应用程序

    我遇到了 gradle 和 Android Studio 的问题 该问题仅在 Android Studio 中构建时出现 BuildServer 和 Commandline 工作正常 applicationVariants all vari
  • Android向后兼容技术

    我现在在开发基于最新 API 15 ICS 的 15 项活动 Android 应用程序方面取得了进展 现在我发现应用程序的主要功能主义者即使支持 android v4 也不向后兼容 例如 1 fragment事务动画 2 将StringSe
  • 在代码中旋转按钮(或其中的文本)

    我必须通过编码随机旋转按钮 或里面的文本 它是相同的 API级别低于11是否有button setRotate x 好吧 看了一下 答案是 很复杂 您可以使用旧的动画框架旋转按钮 例如像这样 Button button Button fin
  • 有没有办法将搜索栏添加到我的实际首选项屏幕?

    我一直看到有关添加您自己的搜索栏首选项的教程 但它不在我实际的 prefs xml 中 有什么方法可以在我的主偏好设置屏幕中添加一个 或者我必须将其分开 Google 似乎有 2 个滑块首选项 搜索栏首选项 https github com
  • BluetoothAdapter.getDefaultAdapter() 不返回 null

    这是我的第一篇文章 所以如果我做了一些愚蠢的事情 请告诉我 这个问题可能看起来与其他帖子类似 但或多或 少与我所看到的所有内容相反 关于该项目的事情 我正在开发 android 4 0 4 4 应用程序 我正在使用蓝牙 我正在运行 andr
  • Android 中的 java.util.Observable 是线程安全的吗?

    Android 中的 java util Observable 是线程安全的吗 这文档 http developer android com reference java util Observable html说只有deleteObser
  • FLAG_ACTIVITY_REORDER_TO_FRONT 被忽略

    我有一个包含项目列表的 FragmentActivity 当应用程序处于后台时 可以推送该项目列表 发生这种情况时 我想创建一个状态栏通知并提醒用户更新 当用户单击通知时 活动应重新排序到前面并显示在屏幕上 同时在列表底部显示新项目 所以我
  • 我的 Android 设备需要安装哪个驱动程序才能运行我的应用程序?

    我购买了 intex mobile 来在真实设备中测试我的 Android 应用程序 然而 该设备不存在于 OEM USB 驱动程序列表中 android 提供的设备列表中 我检查了 intex 官方网站 但不确定到底需要安装哪个驱动程序
  • 在 Android 中始终以横向模式打开相机

    在我的 Android 应用程序中 单击按钮后我希望相机以横向模式打开 即使我将手机旋转为纵向模式 相机也应始终处于横向模式或纵向模式 使用此代码在横向模式下打开相机 Intent cameraIntent new Intent Media
  • 使用 RxJava 限制吞吐量

    我现在遇到的情况很难解释 所以我会写一个更简单的版本来解释这个问题 我有一个Observable from 它发出一系列由ArrayList文件数量 所有这些文件都应上传到服务器 为此 我有一个函数可以完成这项工作并返回一个Observab
  • 更改 Android 中的媒体音量?

    我可以更改媒体音量吗 如何 到目前为止我用过这个 setVolumeControlStream AudioManager STREAM MUSIC 但有一个搜索栏并且想要更改媒体音量 而不是铃声音量 那么有人可以告诉我如何更改媒体音量onC
  • 将图像保存到内部存储器并将出现在图库中

    我搜索了很多与我的问题相关的问题 是否有办法将图像存储在内存中并且它也应该出现在图库中 这是完全有可能的 我以前也这么做过 在将图像保存到内存 或称为应用程序文件夹等 之前 您最好设置Context MODE WORLDREADABLE 虽
  • 如何使用 Swipe 视图实现 Android TabLayout 设计支持库

    我将使用 android TabLayout 设计支持库 但我不知道如何使用滑动视图 这是我的代码 XML
  • Android Drawable 绘图性能?

    在我看来 我有一个简单的 ARGB 可绘制对象 大约需要 2 毫秒才能绘制 但我可以在 0 5 毫秒内绘制与位图相同的文件 只是一些快速代码 我真的不能认为它是一个选项 优化可绘制对象的绘制速度的最佳方法是什么 这取决于可绘制的数量以及每个
  • 在 android 中,第一次单击时按钮侦听器未注册

    因为我是 Android 新手 所以我遇到了按钮监听器的问题 我正在使用 OnClickListener 来处理胸像 但它第一次点击后不执行一旦我单击多个 它就会表现良好 但如何使其在第一次单击时成为可能 这是我的代码 public cla
  • 使用后退按钮启动 Activity

    我正在 Android 中开发一个应用程序 我正在寻找解决方案 有一个活动 例如 A1 通过单击按钮 用户可以转到另一个活动 例如 A2 现在 一旦用户完成 A2 活动 他就会单击后退按钮 返回到上一个活动 A1 这是众所周知的事实 A1此
  • 如何在 kotlin 中检查 lambda 空值

    在 Kotlin 中如何检查 lambda 是否为空 例如 我有这样的签名 onError Throwable gt Unit 我如何区分它的默认值是应用于主体还是应用于此函数的值 您无法测试 lambda 的主体是否为空 因此它不包含源代
  • 应用程序中空指针异常[重复]

    这个问题在这里已经有答案了 我正在尝试在我的应用程序中实施应用程序内计费 我写了这段代码 public class Settings extends PreferenceFragment ServiceConnection mService
  • 制作弹跳动画

    我想做图层的弹跳动画 我已经完成了该图层从右到中心的操作 现在我想将其向后移动一点 然后回到中心 这会产生反弹效果 我想我可以用这样的翻译来做到这一点
  • Android Jasper 报告

    Jasper Reporting 可以集成到 Android 应用程序中吗 我正在尝试从 jrxml 文件生成 PDF CSV 文本和 XLS 报告 但是 我没有看到 Android SDK 支持 net sf jasperreports

随机推荐

  • RS-485详解(一)

    RS 485是美国电子工业协会 EIA 在1983年批准了一个新的平衡传输标准 balanced transmission standard EIA一开始将RS Recommended Standard 做为标准的前缀 不过后来为了便于识别
  • sqli--labs 进阶篇 23_24关

    第二十三关 基于单引号的过滤字符注入 直接爆点 测试是否报错 从下面的提示信息 可以知道是单引号 id 代码审计 进一步确定自己的推论 源码中 存在过滤掉一些注释语句 id 1 推测结构 参数XX limit 0 1 利用回显确定下自己的推
  • 【Linux 速查手册】基于CentOS的Linux 文件结构以及在搭建LAMP环境

    文章目录 LAMP Linux 主要文件结构 Apache 作为 Web 服务器的文件结构 在Centos 中 home目录和 目录的区别 写在最后 LAMP LAMP是指使用 Linux Apache MySql PHP 搭建而成的网站
  • 2018最有前景的编程语言, 你选对了吗?

    对于程序员来说 世间最可怕的事情 莫过于 刚刚学过的编程语言就已经过时 对于求职者来说 了解受欢迎的编程语言及趋势 无论是对找工作 还是规划将来的职业发展 都有很大的好处 基于各种可信来源的数据统计 我对2018年初IT行业编程语言的状态
  • Debian 10驱动Broadcom 无线网卡

    用lspci命令查询无线网卡品牌 运行下面代码后 重启即可 apt get install linux image uname r sed s linux headers uname r sed s broadcom sta dkms
  • QT处理日志文件

    由于实际生产需要 软件系统的运行 会产生大量的日志文件 有时候一天就能产生超过百万条log记录 那么为了能够处理日志文件 查询并且找到我们想要的报错信息 因此不得不考虑怎么实现 打开大日志文件的可行方法 在这里我采用的是内存映射的方式去读取
  • 深入理解神经网络:使用Python实现简单的前馈神经网络

    在本文中 我们将深入理解前馈神经网络的原理 并使用Python编程实现一个简单的前馈神经网络 我们将使用NumPy库来处理矩阵运算 并将逐步解释神经网络的各个组成部分 包括神经元 激活函数 前向传播 反向传播和梯度下降 最后 我们将以一个简
  • k8s-基础入门

    目录 一 k8s的特性 二 kubernetes的基本组件 1 Pod 最小的资源单位 1 1 Pod的两个分类 2 资源清单 3 Pod 控制器 维护Pod状态 期望值 4 服务发现 Service同一个访问入口 5 存储服务分类 6 调
  • linux rpm软件包管理,linux之rpm软件包管理

    1 RPM包的命名规则 例如 httpd 2 2 15 15 el6 centos 1 i686 rpm httpd 软件包名 2 2 15 软件版本 15 发行次数 e16 centos 适合的linux平台 i686 适合的硬件平台 r
  • Angular之ngModel报错:angular-can‘t-bind-to-‘ngModel‘---

    做双向绑定时 如果遇见Angular Can t bind to ngModel since it isn t a known property of input 问题 这是由于没有在当前组件所属的Module中引用FormModule 注
  • 操作系统-进程概念与进程控制块

    进程 在学习操作系统时 对于进程我们经常能看到如下几个定义 一个正在执行的程序 一个正在计算机上执行的程序实例 能分配给处理器并由处理器执行的实体 由一组执行的指令 一个当前状态和一组相关的系统资源表征的活动单元 以上定义都是很抽象的 将进
  • Papers with Code一个查找论文和对应代码的神器

    0x01 Papers with Code是什么 Papers with Code 是一个包含机器学习论文及其代码实现的网站 大多数论文都是有GitHub代码的 这个网站很牛逼的地方就是对机器学习方向做了任务分类 检索对应的论文 数据 代码
  • Shell 编程:探索 Shell 的基本概念与用法

    目录 Shell 简介 Shell 脚本 Shell 脚本运行 Shell 变量 1 创建变量和赋值 2 引用变量 3 修改变量的值 4 只读变量 5 删除变量 6 环境变量 Shell 字符串操作 1 拼接字符串 2 字符串长度 3 字符
  • 实现antd中Form、Form.Item组件

    实现antd中Form Form Item组件 初始化项目 使用create react app初始化项目后创建MyRcFieldForm文件 代码如下 import React Component useEffect from react
  • SWOT分析模型

    SWOT分析模型 出自 MBA智库百科 http wiki mbalib com SWOT分析模型 SWOT Analysis SWOT分析法 也称TOWS分析法 道斯矩阵 即态势分析法 20世纪80年代初由美国旧金山大学的管理学教授韦里克
  • Flask+Nginx+Gunicorn部署应用实现

    实际的开发中 不能使用flask搭建的轻型服务器 无法满足性能要求 在生产环境中可以使用Gunicorn做容器 部署flask程序 Gunicorn 是Python WSGI HTTP 服务器 兼容各种web框架不需要配置 安装后直接使用命
  • Java面向对象编程

    在双向循环链表中 在p指针所指的节点后插入一个指针q所指向的新节点 修改指针的操作是 A p gt next q q gt prior p p gt next gt prior q q gt next q B p gt next q p g
  • tensorflow使用显卡gpu进行训练详细教程

    GPU之nvidia smi命令详解查看显卡的信息 cmd nvidia smi GPU之nvidia smi命令详解 简书 编辑 GPU 本机中的GPU编号 有多块显卡的时候 从0开始编号 图上GPU的编号是 0 Fan 风扇转速 0 1
  • Kotlin柯里化——函数调用链

    一 首先看一个小例子 做个铺垫 package net println kotlin chapter5 currying author wangdong description 柯里化 函数调用链 定义一个Hello的方法 传入三个参数 返
  • Android JNI(一):JNI基础概念

    本文讲述 NDK和JNI是什么 JNI的原理 JNI开发流程的步骤 认识JNI相关的代码语法 名称概念 什么是NDK NDK 其中NDK的全拼是 Native Develop Kit Android NDK 就是一套工具集合 允许你使用C