[NDK/JNI系列01] NDK与JNI的基本概念与使用场景

简介: [NDK/JNI系列01] NDK与JNI的基本概念与使用场景

1,什么是NDK和JNI,它们有什么作用和优势?

  • NDK是Native Development Kit的缩写,是Android提供的一个工具集,可以让你在Android应用中使用C或C++语言编写部分代码,并将其编译成动态链接库(.so文件),然后在Java层通过JNI调用这些原生代码。
  • JNI是Java Native Interface的缩写,是Java提供的一个标准接口,可以让Java代码和其他语言(如C或C++)编写的代码进行交互。JNI定义了一套规范,包括数据类型、函数签名、命名规则等,以保证不同语言之间的兼容性和可移植性。
  • NDK和JNI的作用和优势主要有以下几点:
  • 提高性能:对于一些计算密集型或者对实时性要求高的任务,使用C或C++语言可以比Java语言更高效地利用CPU资源,减少内存开销和垃圾回收的影响,提升运行速度和响应能力。
  • 重用代码:对于一些已经存在的用C或C++语言编写的模块或库,可以通过NDK和JNI直接在Android应用中使用,而不需要重新用Java语言编写,节省开发时间和成本,同时保证代码的一致性和可维护性。
  • 调用系统底层:对于一些Java层无法访问或者不方便访问的系统底层功能,例如驱动、硬件、操作系统等,可以通过NDK和JNI调用C或C++语言提供的接口,实现更多的功能和控制。

2,NDK和JNI的使用场景和案例?

  • NDK和JNI的使用场景一般是当Java层无法满足需求时,才会考虑使用。因为使用NDK和JNI也会带来一些缺点和风险,例如增加代码复杂度、增加调试难度、增加安全风险等。因此,在使用NDK和JNI之前,应该先评估是否有必要、是否有替代方案、是否有足够的技术能力等。
  • NDK和JNI的使用案例有很多,例如:
  • 游戏开发:游戏开发通常需要高性能的图形渲染、物理引擎、音频处理等功能,而这些功能往往是用C或C++语言编写的。因此,游戏开发可以通过NDK和JNI调用这些原生代码,实现高质量的游戏体验。
  • 图像处理:图像处理也是一个计算密集型的任务,涉及到很多复杂的算法和数据结构。使用C或C++语言可以更好地处理图像数据,实现更快的处理速度和更低的内存消耗。例如,人脸识别、滤镜、美颜等功能都可以通过NDK和JNI实现。
  • 文件操作:文件操作涉及到对系统底层的访问和控制,例如文件加密、文件拆分、文件合并等。使用C或C++语言可以更方便地调用系统提供的接口,实现更安全和更高效的文件操作。

3,Android系统服务与JNI

  • Android系统服务是一种运行在Android系统中的后台进程,提供了一些核心的功能和接口,供应用层和框架层使用。例如,ActivityManagerService、WindowManagerService、PackageManagerService等。
  • Android系统服务通常是用Java语言编写的,但是也有一些是用C或C++语言编写的,例如SurfaceFlinger、MediaServer等。这些原生服务也需要通过JNI和Binder机制与Java层进行通信。
  • Android系统服务的架构如下图所示:

4,如何通过JNI与Android系统服务通信

  • 通过JNI与Android系统服务通信的步骤大致如下:
  • 1.在Java层,定义一个native方法,声明要调用的原生服务的接口
  • 2.在C/C++层,实现该native方法,使用JNI API获取原生服务的对象引用、方法ID、字段ID等
  • 3.在C/C++层,调用原生服务的方法或访问其字段,使用JNI API转换数据类型和处理异常
  • 4.在C/C++层,返回结果给Java层,使用JNI API转换数据类型和处理异常。

    例如,假设要通过JNI调用原生SurfaceFlinger服务的dump方法,打印其状态信息。可以参考以下代码:

Java代码:

public class SurfaceFlingerTest {
 
    static {
        System.loadLibrary("surfaceflinger_jni");
    }
 
    public static void main(String[] args) {
        dumpSurfaceFlinger();
    }
 
    public static native void dumpSurfaceFlinger();
}

C/C++代码:

#include <jni.h>
#include <gui/SurfaceComposerClient.h>
#include <android/log.h>
 
#define LOG_TAG "SurfaceFlingerTest"
#define LOGI(...) __android_log_print(ANDROID_LOG_INFO,LOG_TAG,__VA_ARGS__)
 
extern "C"
JNIEXPORT void JNICALL
Java_SurfaceFlingerTest_dumpSurfaceFlinger(JNIEnv *env, jclass clazz) {
    // get the surface flinger service object reference
    sp<IBinder> binder = defaultServiceManager()->getService(String16("SurfaceFlinger"));
    if (binder == nullptr) {
        LOGI("Failed to get SurfaceFlinger service");
        return;
    }
    // get the surface flinger interface object reference
    sp<ISurfaceComposer> composer = interface_cast<ISurfaceComposer>(binder);
    if (composer == nullptr) {
        LOGI("Failed to get SurfaceFlinger interface");
        return;
    }
    // call the dump method of surface flinger and print the result to logcat
    Vector<String16> args;
    String8 result;
    composer->dump(args, result);
    LOGI("%s", result.string());
}

参考资料

相关文章
|
存储 Java C++
[NDK/JNI系列02] JNI的设计原理与数据类型
[NDK/JNI系列02] JNI的设计原理与数据类型
163 0
[NDK/JNI系列02] JNI的设计原理与数据类型
|
Web App开发 开发框架 前端开发
移动端window.open跳转链接时,iOS没有反应的问题
【10月更文挑战第9天】在移动端使用 `window.open` 跳转链接时,iOS 可能无响应,原因是 iOS 的安全策略和弹出窗口阻止功能。解决方法包括:确保在用户交互后触发 `window.open`,将目标设置为 `_self`,使用锚点链接模拟跳转,或利用专门的移动端框架。需综合考虑这些方案以优化用户体验。
2000 61
|
Java API Android开发
[NDK/JNI系列04] JNI接口方法表、基础API与异常API
[NDK/JNI系列04] JNI接口方法表、基础API与异常API
266 0
|
数据处理 算法框架/工具 计算机视觉
手把手教你使用YOLOV5训练自己的目标检测模型
本教程由肆十二(dejahu)撰写,详细介绍了如何使用YOLOV5训练口罩检测模型,涵盖环境配置、数据标注、模型训练、评估与使用等环节,适合大作业及毕业设计参考。提供B站视频、CSDN博客及代码资源链接,便于学习实践。
5006 1
手把手教你使用YOLOV5训练自己的目标检测模型
|
NoSQL 算法 JavaScript
一种优雅的方式整合限流、幂等、防盗刷
在工作中,接口防盗刷至关重要,尤其对于短信发送等高风险接口。本文以发送短信接口为例,探讨了仅校验手机号的局限性,并提出基于Ticket机制的解决方案。客户端需先申请Ticket,服务端通过UserAgent、IP等判断请求合法性,生成加密的Ticket。客户端携带Ticket调用接口,并可能需通过图形验证码验证。此方案实现限流、幂等性和防盗刷,适用于多种接口,提升安全性。同时,建议减少明显错误提示,增加破解难度。
434 6
一种优雅的方式整合限流、幂等、防盗刷
|
自动驾驶 物联网 5G
|
XML Java 数据库连接
Spring Boot集成MyBatis
主要系统的讲解了 Spring Boot 集成 MyBatis 的过程,分为基于 xml 形式和基于注解的形式来讲解,通过实际配置手把手讲解了 Spring Boot 中 MyBatis 的使用方式,并针对注解方式,讲解了常见的问题已经解决方式,有很强的实战意义。在实际项目中,建议根据实际情况来确定使用哪种方式,一般 xml 和注解都在用。
|
XML 数据可视化 API
Android经典实战之约束布局ConstraintLayout的实用技巧和经验
ConstraintLayout是Android中一款强大的布局管理器,它通过视图间的约束轻松创建复杂灵活的界面。相较于传统布局,它提供更高灵活性与性能。基本用法涉及XML定义约束,如视图与父布局对齐。此外,它支持百分比尺寸、偏移量控制等高级功能,并配有ConstraintSet和编辑器辅助设计。合理运用可显著提高布局效率及性能。
872 0
|
存储 小程序 JavaScript
|
Oracle Java 关系型数据库
【JavaEE初阶】 JVM简介
【JavaEE初阶】 JVM简介