Android架构师之路-JNI与NDK编程知识基础详解(c++音视频编码基础)
时间:2025-11-05 09:35:22 出处:休闲阅读(143)
前沿小记
1、架基础基础Android架构师要学习的构师知识点有很多,后面我会总结下关于Android开发中jni和ndk开发的知识知识点,当前基础是编程编码越牢固越好,后期学习起来就不会太累,详解一点就懂; 2、视频今天我们就来总结下jni和ndk的架基础基础基础知识点; 3、Android 平台从一开就已经支持了C/C++了。构师我们知道Android的知识SDK主要是基于Java的,所以导致了在用Android SDK进行开发的编程编码工程师们都必须使用Java语言。不过,详解Google从一开始就说明Android也支持JNI编程方式,视频也就是架基础基础第三方应用完成可以通过JNI调用自己的C动态度;一、什么是构师ndk
NDK提供了一系列的工具,帮助开发者快速开发C(或C++)的知识动态库,并能自动将so和java应用一起打包成apk。这些工具对开发者的帮助是巨大的; NDK集成了交叉编译器,并提供了相应的亿华云mk文件隔离CPU、平台、ABI等差异,开发人员只需要简单修改mk文件(指出“哪些文件需要编译”、“编译特性要求”等),就可以创建出so; NDK可以自动地将so和Java应用一起打包,极大地减轻了开发人员的打包工作; NDK提供了一份稳定、功能有限的API头文件声明;Google明确声明该API是稳定的,在后续所有版本中都稳定支持当前发布的API。从该版本的NDK中看出,这些API支持的功能非常有限,包含有:C标准库(libc)、标准数学库(libm)、压缩库(libz)、Log库(liblog); NDK的发布,使“Java+C”的开发方式终于转正,成为官方支持的开发方式; 使用NDK,我们可以将要求高性能的应用逻辑使用C开发,从而提高应用程序的执行效率; 使用NDK,我们可以将需要保密的应用逻辑使用C开发。站群服务器毕竟,Java包都是可以反编译的; NDK促使专业so组件商的出现:比如视频库的编译、音频库、图片库滤镜等等; NDK将使Android平台支持C开发的开端;NDK提供了的开发工具集合,使开发人员可以便捷地开发、发布C组件。同时,Google承诺在NDK后续版本中提高“可调式”能力,即提供远程的gdb工具,使我们可以便捷地调试C源码;二、为什么使用NDK
在平台之间移植其应用;
重复使用现在库,或者提供其自己的库重复使用;
在某些情况下提性能,特别是像游戏这种计算密集型应用;
使用第三方库,现在许多第三方库都是由C/C++库编写的,比如Ffmpeg这样库;
不依赖于Dalvik Java虚拟机的设计;
代码的保护。由于APK的Java层代码很容易被反编译,而C/C++库反编译难度大;
三、jni详解
1、jni是服务器租用什么?以及和ndk关系
JNI,全称为Java Native Interface,即Java本地接口,JNI是Java调用Native 语言的一种特性。通过JNI可以使得Java与C/C++机型交互。即可以在Java代码中调用C/C++等语言的代码或者在C/C++代码中调用Java代码。由于JNI是JVM规范的一部分,因此可以将我们写的JNI的程序在任何实现了JNI规范的Java虚拟机中运行; 在Android Framework中,需要提供一种媒介或 桥梁,将Java层(上层)与C/C++层(下层)有机的联系起来,使得他们互相协调完成某些任务。而充当这种媒介的就是Java本地接口(JNI,Java Native Interface); JNI提供一些列的接口,允许Java类与C/C++等本地编辑语言(在JNI中,这些语言被称为 本地语言)编写的应用 程序、模块 、库进行交互操作。比如,在Java类中使用C语言库中的函数或在C语言中使用 Java类库,都需要借助JNI; Android NDK是一个开发工具集,提供一系列工具快速开发C/C++的动态库,并能自动将 .so/.dll 和 Java 应用一起打包到Apk;NDK提供工具可以方便JNI调用C/C++,而且提供了交叉编译器可以修改.mk文件生成特定CPU平台的动态库,并能将so和java应用一起打包到apk中;简单说就是JNI负责Java与C/C++进行互相操作,NDK提供工具方便在Android平台使用JNI;2、JNI开发流程的步骤
在Java中先声明一个native方法; 编译Java源文件javac得到.class文件; 通过javah -jni命令导出JNI的.h头文件; 使用Java需要交互的本地代码,实现在Java中声明的Native方法; 将本地代码编译成动态库(Windows系统下是.dll文件,如果是Linux系统下是.so文件,如果是Mac系统下是.jnilib); 通过Java命令执行Java程序,最终实现Java调用本地代码; 
3、 JNI数据结构

JNI函数表的组成就像C++的虚函数表。虚拟机可以运行多张函数表,举例来说,一张调试函数表,另一张是调用函数表。JNI接口指针仅在当前线程中起作用。这意味着指针不能从一个线程进入另一个线程,然而,可以在不同的咸亨中调用本地方法;
jdouble test (JNIEnv *env, jobject obj, jint i, jstring s) { const char *str = (*env)->GetStringUTFChars(env, s, 0); (*env)->ReleaseStringUTFChars(env, s, str); return 10; }
JNI有自己的原始数据类型和数据引用类型如下

四、jni交互原理详解
1、JavaVM
JavaVM是Java虚拟机在JNI层的代表,JNI全局仅仅有一个JavaVM结构中封装了一些函数指针(或叫函数表结构),JavaVM中封装的这些函数指针主要是对JVM操作接口。另外,在C和C++中的JavaVM的定义有所不同,在C中JavaVM是JNIInvokeInterface_类型指针,而在C++中有对JNIInvokeInterface_进行了一次封装,比C中少了一个参数,这也是为什么JNI代码更推荐使用C++来编写的原因;
2、JNIEnv
JNIEnv是一个线程相关的结构体,该结构体代表了Java在本线程的执行环境
JNIEnv是当前Java线程的执行环境,一个JVM对应一个JavaVM结构,而一个JVM中可能创建多个Java线程,每个线程对应一个JNIEnv结构,它们保存在线程本地存储TLS中。因此,不同的线程的JNIEnv是不同,也不能相互共享使用。JNIEnv结构也是一个函数表,在本地代码中通过JNIEnv的函数表来操作Java数据或者调用Java方法。也就是说,只要在本地代码中拿到了JNIEnv结构,就可以在本地代码中调用Java代码;
调用Java 函数:JNIEnv代表了Java执行环境,能够使用JNIEnv调用Java中的代码;
操作Java代码:Java对象传入JNI层就是jobject对象,需要使用JNIEnv来操作这个Java对象;
3、JNIEnv和JavaVM的区别
JavaVM:JavaVM是Java虚拟机在JNI层的代表,JNI全局仅仅有一个; JNIEnv:JavaVM 在线程中的代码,每个线程都有一个,JNI可能有非常多个JNIEnv;4、JNIEnv与线程
JNIEnv是线程相关的,即在每一个线程中都有一个JNIEnv指针,每个JNIEnv都是线程专有的,其他线程不能使用本线程中的JNIEnv,即线程A不能调用线程B的JNIEnv,所以JNIEnv不能跨线程; JNIEnv只在当前线程有效:JNIEnv仅仅在当前线程有效; JNIEnv不能在线程之间进行传递,在同一个线程中,多次调用JNI层方便,传入的JNIEnv是同样的; 本地方法匹配多个JNIEnv:在Java层定义的本地方法,能够在不同的线程调用,因此能够接受不同的JNIEnv;5、JNIEnv结构

6、JNIEnv相关的常用函数

总结:
以上是学习jni的基础知识点,必须理解的,不懂的就问就学; jni还有很多知识点,比如动态注册,静态注册等等; 要学习一点c语言和c++的基础知识点,后面会讲到总结。本文转载自微信公众号「Android开发编程」,可以通过以下二维码关注。转载本文请联系Android开发编程公众号。

猜你喜欢
- 探索HU4803的特性和性能(了解HU4803的优点和应用领域)
- 消灭啤酒肚的最佳方法(健康饮食与有效锻炼的关键)
- 探索IntelX79主板的卓越性能与创新功能(为你带来更强大的计算体验与扩展性能)
- 3D玻璃打印(探索3D玻璃打印的商机与前景,)
- Nginx (engine-x)是一个开源的高性能 HTTP 服务器、反向代理和 IMAP/POP3 代理服务器。nginx 杰出的功能有:稳定、丰富的功能集、简单的配置和低资源消耗。nginx 被用于一些高性能网站并在站长之间变得越来越流行。本教程会从源码构建一个带有 google paespeed 模块的用于 Ubuntu 15.04 的 nginx .deb 安装包。pagespeed 是一个由 google 开发的 web 服务器模块来加速网站响应时间、优化 html 和减少页面加载时间。ngx_pagespeed 的功能如下: 图像优化:去除元数据、动态缩放、重压缩。 CSS 与 JavaScript 压缩、串联、内联、外联。 小资源内联 图像与 JavaScript 延迟加载 HTML 重写 缓存生命期插件前置要求 Ubuntu Server 15.04 64位 root 权限该文我们将要: 安装必备软件包 安装带 ngx_pagespeed 的 nginx 测试安装必备包复制代码代码如下:sudo apt-get install dpkg-dev build-essential zlib1g-dev libpcre3 libpcre3-dev安装带 ngx_pagespeed 的 nginx第一步 - 添加nginx仓库复制代码代码如下: vim /etc/apt/sources.list.d/nginx.list加入下面的行:复制代码代码如下:deb http://nginx.org/packages/ubuntu/ trusty nginx deb-src http://nginx.org/packages/ubuntu/ trusty nginx更新仓库:复制代码代码如下:sudo apt-get update注意:假如你看到信息:GPG error [...] NO_PUBKEY [...] 等等请添加key:复制代码代码如下:sudo sudo apt-key adv --keyserver keyserver.ubuntu.com --recv-keys KEYNUMBER sudo apt-get update第二步 - 从仓库下载 nginx 1.8复制代码代码如下: sudo su cd ~ mkdir -p ~/new/nginx_source/ cd ~/new/nginx_source/ apt-get source nginx apt-get build-dep nginx第三步 - 下载 Pagespeed复制代码代码如下:cd ~ mkdir -p ~/new/ngx_pagespeed/ cd ~/new/ngx_pagespeed/ ngx_version=1.9.32.3 wget https://github.com/pagespeed/ngx_pagespeed/archive/release-${ngx_version}-beta.zip unzip release-${ngx_version}-beta.zip cd ngx_pagespeed-release-1.9.32.3-beta/ wget https://dl.google.com/dl/page-speed/psol/${ngx_version}.tar.gz tar -xzf 1.9.32.3.tar.gz第四步 - 配置 nginx 来编译 Pagespeed复制代码代码如下:cd ~/new/nginx_source/nginx-1.8.0/debin/ vim rules在两处 CFLAGS .configure 下添加模块: --add-module=../../ngx_pagespeed/ngx_pagespeed-release-1.9.32.3-beta adding pagespeed to nginx adding pagespeed to nginx 第五步 - 打包 nginx 软件包并安装复制代码代码如下:cd ~/new/nginx_source/nginx-1.8.0/ dpkg-buildpackage -bdpkg-buildpackage 会编译 ~/new/ngix_source/ 为 nginx.deb。打包完成后,看一下目录:复制代码代码如下:cd ~/new/ngix_source/ ls nginx builded with pagespeed 接着安装 nginx。复制代码代码如下:dpkg -i nginx_1.8.0-1~trusty_amd64.deb 测试运行 nginx -V 测试 nginx 是否已经自带 ngx_pagespeed。复制代码代码如下:nginx -V 总结稳定、快速、开源的 nginx 支持许多不同的优化模块。这其中之一是 google 开发的‘pagespeed’。不像 apache,nginx 模块不是动态加载的,因此你必须在编译之前就选择好需要的模块。
- 探索X79配3960的顶级性能(强大的处理能力与高效的计算体验)
- 新加坡电子产品制造商Venture的发展与竞争力剖析
- 以发烧总监智能体温计
- 三星NP910S3L性能评测及用户体验(一款轻薄本的卓越表现与无憾选择)
