Android Studio 3.5 JNI编程与动态注册

android Ndk Jni动态注册方式以及静态注册 1.项目名\app\src\main下新建一个jni目录2.在jni目录下,再新建一个Android.mk文件写入以下配置LOCAL_PATH := $(call my-dir)//获取当前Android.mk所在目录include $(CLEAR_VARS)//清空变量,确保不会有不必要的变量被继承下去LOCAL_MODULE := TestJni//定义了将要生成的库的名称,及xx.so。 阅读详情

Android的JNI、so与JAVA

Android程序分2层,java层与native层,Java层就是Java代码编译为dex文件的。而native层则是c++代码编译为so动态库。两者使用jni(java native interface)来进行链接。相比于java,native层安全性更加高,隐蔽性更好,某种情况下效率更高。国内的加密与检测一般都放在native层中进行。

Jni分为静态和动态注册两种方式,Android Studio默认的工程是静态注册。

环境搭建:

Android Studio 3.5.3

打开SdkManager下载LLDB、NDK、CMake。
在这里插入图片描述
Project Structure中配置NDK。
在这里插入图片描述

建立一个C++Native工程

[File] -> [New] ->[New Project…],选择Native C++模版。
在这里插入图片描述
点[Next],其余默认就行。完成后工程结构如下:
在这里插入图片描述
红色框中为自动生成。

蓝色框内为手动添加,目的是熟悉CMake工具构建过程,可以不添加。

CMakeLists.txt文件是CMake构建需要的文件,文件内容解析如下:

# For more information about using CMake with Android Studio, read the
# documentation: https://d.android.com/studio/projects/add-native-code.html

# Sets the minimum version of CMake required to build the native library.

cmake_minimum_required(VERSION 3.4.1)

# Creates and names a library, sets it as either STATIC
# or SHARED, and provides the relative paths to its source code.
# You can define multiple libraries, and CMake builds them for you.
# Gradle automatically packages shared libraries with your APK.

# 创建和命名库,将其设置为静态或共享,并提供到其源代码的相对路径。
# 您可以定义多个库,然后CMake为您构建它们。Gradle自动将共享库打包到你的APK中。

add_library( # Sets the name of the library.
        native-lib  # 设置库的名字叫native-lib

        # Sets the library as a shared library.
        SHARED  # 设置为共享库

        # Provides a relative path to your source file(s).
        # 源码文件的相对路径
        native-lib.cpp
        one-lib.cpp  # 自己添加的CPP文件
        two-lib.cpp) # 自己添加的CPP文件

# Searches for a specified prebuilt library and stores the path as a
# variable. Because CMake includes system libraries in the search path by
# default, you only need to specify the name of the public NDK library
# you want to add. CMake verifies that the library exists before
# completing its build.

# 搜索指定的预构建库并将路径存储为变量。
# 由于默认情况下CMake的搜索路径中包含系统库,因此只需指定要添加的公共NDK库的名称。
# CMake在完成构建之前验证该库是否存在。

# 将log库存储为名叫log-lib的变量
find_library( # Sets the name of the path variable.
        log-lib

        # Specifies the name of the NDK library that
        # you want CMake to locate.
        log)

# Specifies libraries CMake should link to your target library. You
# can link multiple libraries, such as libraries you define in this
# build script, prebuilt third-party libraries, or system libraries.

# 在上方定义好的native-lib库中引入log库
target_link_libraries( # Specifies the target library.
        native-lib

        # Links the target library to the log library
        # included in the NDK.
        ${log-lib})

# 参数传入的是指定包含CMakeLists文件的目录的相对路径
add_subdirectory(one)  # 添加子目录one, 为手动添加
add_subdirectory(two)  # 添加子目录two, 为手动添加

静态注册:

因为Android Studio默认是静态注册,所以工程自动在native-lib.cpp中生成了如下代码:

#include "jni.h"
#include <string>

extern "C" JNIEXPORT jstring JNICALL
Java_org_mu_myfirsthellonative_MainActivity_stringFromJNI(
        JNIEnv *env,
        jobject /* this */) {
    std::string hello = "Hello from C++";
    return env->NewStringUTF(hello.c_str());
}

工程自动在MainActivity.java中生成如下方法与C++方法连接:

public native String stringFromJNI();

C++代码有JNIEXPORT和JNICALL,这两个宏定义的作用就是说明该函数为JNI函数,在Java虚拟机加载的时候会链接对应的native方法。

JNI函数名的构成是:以Java为前缀,并且用“_”下划线将包名、类名以及native方法名连接起来就是对应的JNI函数了。

静态注册的JNI方法的弊端:

  • 名字过长,要遵循规则
  • 运行时去找效率不高

动态注册:

动态注册在jni层实现,JAVA层不需要关心方法的命名。JAVA在System.loadLibrary("native-lib");中自动调用JNI_OnLoad方法,在此方法中JNI层与JAVA层的方法进行关连。

动态注册的原理:JNI 允许我们提供一个函数映射表(一个结构体数组JNINativeMethod),注册给 JVM,这样 JVM 就可以用函数映射表来调用相应的函数。

动态注册过程

1.参数映射表

在JNI层添加函数映射表,Native方法都在这里添加。这是一个结构体数组,这个工程中因为只有一个Native方法,所以数组中只有一个成员。

static JNINativeMethod gMethods_MainActivity[] = {
        {"stringFromJNI", "()Ljava/lang/String;", (void*)strFromJni}
};

参数说明:

参数1:就是java代码中用native关键字声明的函数名字符串

参数2:native方法的签名(参数类型和返回值类型)

参数3:C/C++中对应函数的函数名(地址)

2.注册native方法

将native方法关联到JAVA层的类中。

// JAVA层的类
static const char* gClassName = "org/mu/myfirsthellonative/MainActivity";

static int registerNatives(JNIEnv *env, const char* classname) {
    jclass clazz;
    clazz = env->FindClass(classname);
    if(clazz == NULL) {
        return JNI_FALSE;
    }
    if(env->RegisterNatives(clazz, gMethods_MainActivity, sizeof(gMethods_MainActivity) / sizeof(gMethods_MainActivity[0])) < 0) {
        return JNI_FALSE;
    }
    return JNI_TRUE;
}
3.载入JNI方法

因为 JVM 执行到 System.loadLibrary() 函数时,会立即调用 JNI_OnLoad() 方法,因此在该方法中进行各种资源的初始化操作最为恰当。

JNIEXPORT jint JNI_OnLoad(JavaVM *vm, void *reserved) {
    JNIEnv *env = NULL;
//    jint result = -1;
    if (vm->GetEnv((void **) &env, JNI_VERSION_1_6) != JNI_OK) {
        return -1;
    }
    assert(env != NULL);
    //为了方便管理我们可以将native方法分别注册到java的不同类中
    //这里只有一个方法
    registerNatives(env, gClassName); //注册MainActivity类的native方法
    return JNI_VERSION_1_6;
}
4.实现的Native方法

此处定义了C++的方法,以供JAVA调用。因为JAVA层的方法是实例方法,此处参数为jobject类型。若JAVA层的方法是静态方法,此处参数为jclass类型。

jstring strFromJni(JNIEnv *env, jobject /*0bj*/) {
    std::string hello = "欢迎来到native的世界";
    return env->NewStringUTF(hello.c_str());
}
Android Studio + NDK JNI调用openCV图像处理 本文介绍如何通过android studio通过jni调用openCV,不使用Opencv Manager,使用静态编译openCV的方式,生成单独的一个so文件。 可先看上篇文章http://blog.csdn.net/cheng20150809/article/details/51348420,AndroidStudio基本的JNI编程。 1、新建一个空的Activity工程,添加Add- 阅读详情

相关推荐

Android jni引用第三方so动态库和.a静态库并且调用(c)方法

最近花了一周时间来入门学习 Android JNI方面的知识,因为后续的工作很多需要用到c c++库,我需要用jni来包装一下c函数,来提供给上次java调用。总之多学点知识对自己有好处。案例效果:上文我们讲解了本文接着上文,这次我们利用JNI 来引用第三方动态库so文件,并且让Java调用它的函数。

yundashi168.com 2473

Android JNI之动态注册(android studio)

故事得从这里开始-静态注册没有对比,就没有伤害。静态注册自出生以来,就非议颇多。繁琐的过程(javah生成头文件),每增加一个接口,渣握h一下。长长长的函数名称,一个详细的身份证明。运行效率较低,第一次进行交流的时候,根据详细的身份去jni中查找对应身份的人,这个难度比较大,一个一个去对比,运气好,一次匹配就建立了关系,如果,假如说如果,等到最后,黄花菜都凉了。艰难的时候,到了要放弃的时候,man是

744

Android JNI 开发完全指南:从静态注册到动态注册

本文系统梳理 Android JNI 的使用流程,从 native 方法声明、头文件生成到 NDK 编译打包。重点对比静态注册与动态注册:分析静态注册的函数名冗长、首次调用开销等缺陷,详解基于 JNI_OnLoad 与 RegisterNatives 的动态注册方案,包括映射表构建、初始化时机及实际代码示例,并给出高效、可维护的工程化选型建议。

学无止境 899

android jni动态注册实例,android jni动态注册

题外话转眼间2019年也已经接近尾声了,回顾这一年也发生了很多事,换工作、搬家、赶项目、学习新技术等等很多事,忙碌的一年,博客也被放下了,真的是越来越懒了,每次都有一万个不写博客的理由,之前每年至少还要更新几篇文章,然而今年一篇文章也没写,趁着这个周末没事情,抓住2019年的小尾巴,把自己一直想写的文章写了,于是就有了今天这篇文章。jni简介JNI是Java Native Interface的缩写...

weixin_39977586的博客 483

Android studio 下 NDK Jni 开发 简单例子

Android studio 下 NDK Jni 开发 简单demo 谢谢

android stadio jni动态注册函数

JNI静态函数注册,根据Java+packname+method来实现的,名称过长,需要JNI开始时去遍历查找,比较麻烦!这个例子用了动态注册方式。当JAVA层通过System.loadLibrary加载完JNI动态库后,紧接着会查找该库中一个叫JNI_OnLoad 的函数。如果有,就调用它,而动态注册的工作就是在这里完成的。

Android JNI 编程之动态注册(设置返回 long float double 型数据)

jni静态注册和 jni动态注册,jni返回double型数据, jni返回float型数据,jni返回long型数据,jni返回java对象,jni返回传递对象 静态注册 理解和使用方式简单, 使用相关工具按流程操作就行, 编码出错率低 JNI 层函数名特别长,且当需要更改类名,包名或者方法时, 需要按照之前方法重新生成头文件, 灵活性不高 初次调用 native 函数时要根据函数...

AlanWang4523 1260

win11怎么安装dosbox和masm来运行汇编程序(小白,萌新篇)

一文教会你如何部署dosbox和masm环境

m0_73279193的博客 4704

注册JNI函数的两种方式

注册JNI函数是两种方式

巫山老妖 1万+

KEGG两类报错--①No gene can be mapped--②URL ‘https://rest.kegg.jp/link/hsa/pathway‘…

版本问题,重新安装一下clusterProfiler包。网络问题,可以等待之后再试一下(试过不是)(以上可以排除基因不存在的错误因素)

weixin_57699783的博客 2万+

网安保研避坑指南:中科院信工所各研究室真实体验与导师选择建议

本文为中科院信工所网络安全保研生提供深度指南,详细解析了信工所六个研究室的研究方向、真实氛围与导师选择策略。文章特别强调,选择导师是决定研究生体验的关键,并提供了针对各研究室的避坑建议与实战调研方法,帮助学生做出明智选择。

weixin_29210727的博客 1587

安卓JNI开发终极指南:静态/动态注册实战与逆向安全全解析

本文全面介绍了安卓JNI开发的核心技术与实战应用,主要包含以下内容:1)NDK环境配置与项目搭建;2)JNI开发四步流程(声明、生成头文件、实现C函数、CMake配置);3)类型映射与签名体系解析;4)高级实战案例(十六进制编码、C调用Java方法);5)动态注册实现与安全加固方案;6)逆向分析与防护策略。文章通过10+可运行代码案例,详细演示了Java与C/C++的双向调用技术,并重点分析了动态注册在安全防护上的优势,最后提供IDA反编译防护技巧与安全建议。

学习成长日记 1655

京东云鼎环境配置与API安全接入实战:ISV服务商如何搞定数据加密与商家授权

本文详细介绍了京东云鼎环境配置与API安全接入的实战指南,帮助ISV服务商解决数据加密与商家授权等核心问题。通过京东开放平台的应用申请流程,结合多租户数据隔离策略和自动化授权实现,确保电商生态中的安全高效运营。文章还提供了避坑指南,助力开发者规避常见配置错误。

weixin_28705087的博客 353

Android:JNI 动态注册和静态注册的详解(附android studio实例)

Android:JNI 动态注册和静态注册的详解 一、JNI是什么? JNI是Java Native Interface的缩写,中文名为JAVA本地调用。它允许Java代码和其他语言写的代码进行交互。JNI一开始是为了本地已编译语言,尤其是C和C++而设计的,但是它并不妨碍你使用其他语言,只要调用约定受支持就可以了。Java是支持调用...

海月汐辰 6024

UE5 GAS实战:从零构建一个MOBA英雄技能系统

本文详细介绍了如何利用UE5的Gameplay Ability System(GAS)构建MOBA英雄技能系统,涵盖核心组件如Ability System Component和GameplayEffect的使用,以及技能冷却、资源管理和连招系统等高级功能的实现。通过实战案例和代码示例,帮助开发者快速掌握GAS在MOBA游戏开发中的应用。

weixin_29012765的博客 527

USB3.0一致性测试方案

为各测试项目具体测试结果包括脉冲串突发时间、脉冲串重复时间、时钟周期以及眼图等完整USB3.0测试项目,工程师可以看到各项测试的具体结果方便观察。RIGOL 提供了一套完善的工具,包括数字示波器、专业的测试夹具以及全自动一致性测试软件,使得USB 3.0设备设计人员能够高效精确地进行信号捕捉、测试与分析。报告第二部分测试摘要,在此可以看到USB3.0测试所有测试项目,并且可以观看到测试是否正常,可以帮助工程师更好的判断测试结果。,以简化下载、存储以及对于多媒体的大量内容的共享。

2409_87378937的博客 2530

3、安卓逆向之JNI静态注册

参考资料: 1、安卓逆向5.Android Studio JNI静态注册(C++和Java互操作) 2、安卓逆向4.Android Studio JNI静态注册(一个简单的JNI静态注册流程) 3、安卓逆向_15( 三 ) --- Android NDK 开发【 jni 静态注册、JNI_OnLoad 动态注册】 4、Android JNI编程(七)——使用AndroidStudio编写第一个JNI程序 环境: Windows10 x64 Android Studio 4.0.1 ...

u014738665的博客 2313

步进电机驱动算法——梯形加减速算法

目录步进电机梯形加减速梯形加减速算法原理分析算法实现 步进电机梯形加减速 电机的控制方式一般分为开环控制与闭环控制两种控制方式,其中开环控制原理框图如下: 这种种控制方式的特点是:控制简单、实现容易、价格较低,这种开环控制方式,负载位置对控制电路没有反馈。 对于步进电机,控制脉冲的输入并不依赖于转子的位置,而是按一固定的规律发出控制脉冲,如果励磁变化太快,电机不能移动到新的位置,那么实际负载位置与理想位置就会产生一个偏差,就有可能出现失步或者过冲现象,所以需要使用加减速算法。 梯形加减速算法,S加减速算法等

aaa376070331的博客 3万+

Android动态注册jni

最近整理了以前关于jni的代码,这里梳理下,供以后参考。 JNI简介 JNI是Java Native Interface的缩写,它提供了若干的接口实现了Java和其他语言的通信(主要是c、c++)。从Java1.1开始,JNI标准成为java平台的一部分,它允许Java代码和其他语言写的代码进行交互。jni是Android中java和c++之间连接的桥梁,jni是jvm提供的一种与nativ...

疾风剑豪 472

SCADA|KingSCADA通过组合框选择修改变量的值

《SCADA项目中组合框控件的使用方法》 本文详细介绍了SCADA系统中组合框(下拉框)控件的应用方法。通过具体示例演示如何实现:当选择"雷工笔记"时变量值为100,选择"雷工杂谈"时为200,选择"小李食代"时为300的功能。主要实现步骤包括:1)创建项目并添加组合框控件;2)设置Items选项及对应数值;3)创建内存变量;4)使用GetCurrentIndex()和GetItemData()方法;5)在选项变化事件中编写脚本。该控件在SCADA

做有价值的事,积累有价值的笔记! 864

SIMATIC S7-1200, S7-1500 PID 控制[手册]

SIMATIC S7-1200, S7-1500 PID 控制[手册]

Android Studio JNI编程以及NDK环境配置

1. 新建一个工程,并添加JNI文件夹。 2. 在生成的jni文件夹中添加cpp文件。 3. 在添加的cpp文件添加代码 这里我们采用动态注册的方式来添加jni函数,比较方便,不需要用javah生成.h文件 #include #include #include #include /* 输出Log的宏 */ #ifndef LOG

cheng20150809的博客 1749

文档:亲测可用解决vnc灰屏,黑屏,鼠标大黑叉情况

主要解决vnc-viewer灰屏,黑屏,鼠标大黑叉等现象,详细见文档。

Android Studio jni动态注册步骤

本文主要记录jni动态注册的步骤,这里使用Android studio 的ndk-build,关于使用cmake的,有时间再写1、在src/main/java/下新建一个java类,类似如下:public class testUtils { static { System.loadLibrary("testJNI"); //加载so,在mk文件中指定 } //

Tasfa的博客 2107

数学建模模型总结

这是本人在两年内准备参加数学建模竞赛搜集到的模型资料,已经经过了本人的筛选和整理,希望能够对准备参加数学建模竞赛的学弟学妹们提供一些帮助!

温度PID控制PLC程序

温度PID稳定控制程序,适用于欧姆龙PLC,对其他PLC也具有很大参考价值

android 7.0 静态注册,JNI方法的静态注册和动态注册RegisterNatives

代码结构如下:Android下的Java代码 仍然还是使用了eclipse开发环境 这里在NDKUtils.java文件里定义了所有的本地方法 Linux下的C代码 这里是在Linux系统目录下新建的文件 其中libs/和obj/都是由ndk-build编译后编译器产生 // MainActivity.javapublic class MainActivity extends Activity i...

weixin_39705794的博客 252

Android Studio使用JNI (静态注册和动态注册jni函数)

 http://www.cnblogs.com/aliflycoris/p/5507236.html 0x01 前言   本文讲述使用Android Studio通过静态注册、动态注册使用JNI的方法,以及加载第三方so文件的方法   0x02 Android Studio静态注册的方式使用JNI   1. 添加native接口 public class MainActi

991

安卓NDK交叉编译与JNI开发实战指南

JNI(Java Native Interface)是Java与原生代码(C/C++)交互的关键技术,通过NDK(Native Development Kit)工具链实现跨平台编译。交叉编译技术允许开发者在x86架构主机上生成ARM架构可执行文件,这是移动开发中性能优化的核心手段。在安卓生态中,从NDK r19开始推荐使用Clang工具链进行高效编译。JNI开发涉及数据类型映射、异常处理、内存管理等关键技术点,广泛应用于音视频处理、游戏引擎等高性能场景。通过合理使用直接缓冲区、缓存方法ID等优化技巧,可以显

cuibinmo3519的博客 387

android sudio jni 调用so_在 Android 中使用 JNI 开发

这是去年写的一篇文章,至于为什么又发出来了呢,是因为最近在做一些 NDK 的开发,就是 native 层的图像处理,使用 OpenCV 来做,另外还有在 native 层的安全校验和请求加密等。关于 OpenCV 的集成,我已经开源了一个项目 https://github.com/Shouheng88/Android-uix 并且提供了透视变换进行图像切割以及二值化和灰度两种滤镜效果,我...

weixin_39960319的博客 232
上一篇: Python获取当前目录的方法总结
「已注销」
博客等级 码龄10年 2粉丝 4原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值