JNI开发
文件结构(选中的为生成的)

CMake构建不需要执行命令,会自动生成so文件打包进apk
Android mk构建需要执行命令生成so文件,再打包进apk。命令如下。
# 在jni目录下执行
# 生成com_demo_cppproject_OtherNdkTest.h头文件
javac -h ./ ../java/com/demo/cppproject/OtherNdkTest.java
# 构建出so文件
ndk-build NDK_PROJECTPATH=. NDK_APPLICATION_MK=Application.mk NDK_BUILD_SCRIPT=Android.mk NDK_LIBS_OUT=..\jniLibs\
MainActivity.java
package com.demo.cppproject;
public class MainActivity extends AppCompatActivity {// Used to load the 'cppproject' library on application startup.static {System.loadLibrary("cppproject");System.loadLibrary("DEMO");}private ActivityMainBinding binding;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);binding = ActivityMainBinding.inflate(getLayoutInflater());setContentView(binding.getRoot());TextView tv = binding.sampleText;String temp = stringFromJNI() + "\n" + new MyNdkTest().getData() + "\n"+ new OtherNdkTest().getName() + "==" + new OtherNdkTest().count();tv.setText(temp);}public native String stringFromJNI();
}
MyNdkTest.java
package com.demo.cppproject;public class MyNdkTest {public native String getData();
}
OtherNdkTest.java
package com.demo.cppproject;public class OtherNdkTest {public native String getName();public native int count();
}
CMakeLists.txt
# 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.22.1)# Declares and names the project.project("cppproject")# 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.add_library( # Sets the name of the library.cppproject# Sets the library as a shared library.SHARED# Provides a relative path to your source file(s).native-lib.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.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.target_link_libraries( # Specifies the target library.cppproject# Links the target library to the log library# included in the NDK.${log-lib})
native-lib.cpp
#include <assert.h>
#include <jni.h>
#include <string>#ifndef _Included_com_demo_cppproject_MyNdkTest
#define _Included_com_demo_cppproject_MyNdkTest
#ifdef __cplusplus
extern "C" {
#endifJNIEXPORT jstring JNICALL Java_com_demo_cppproject_MainActivity_stringFromJNI(JNIEnv *env,jobject /* this */) {std::string hello = "静态注册!cmake构建!Hello from C++";return env->NewStringUTF(hello.c_str());
}// 定义的对应java中的定义native方法, 采用动态注册
//extern "C" JNIEXPORT jstring JNICALL Java_com_demo_cppproject_MyNdkTest_getData(
JNIEXPORT jstring JNICALL getData(JNIEnv *env,jobject /* this */) {std::string hello = "动态注册!cmake构建!get data";return env->NewStringUTF(hello.c_str());
}//需要动态注册的native方法所在的类
#define JNIREG_CLAS_MAIN "com/demo/cppproject/MyNdkTest"//创建JNINativeMethod的数组,用来存放,JNINativeMethod结构变量,
// JNINativeMethod结构存放:注册的native方法,对应的签名,C++/C的对应的JNI方法
static JNINativeMethod gMethods[] = {{"getData", "()Ljava/lang/String;", (void*)getData}
};static int registerNativeMethods(JNIEnv *env, const char *className,JNINativeMethod *gMethods, int numMethods) {jclass clazz;clazz = env->FindClass(className);if (clazz == NULL) {return JNI_FALSE;}if (env->RegisterNatives(clazz, gMethods, numMethods) < 0) {return JNI_FALSE;}return JNI_TRUE;
}/***
* 注册native方法
*/
static int registerNatives(JNIEnv *env) {if (!registerNativeMethods(env, JNIREG_CLAS_MAIN, gMethods,sizeof(gMethods) / sizeof(gMethods[0]))) {return JNI_FALSE;}return JNI_TRUE;
}/**
* 如果要实现动态注册,这个方法一定要实现
* 动态注册工作在这里进行
*/
JNIEXPORT jintJNICALL JNI_OnLoad(JavaVM *vm, void *reserved) {JNIEnv *env = NULL;jint result = -1;if (vm->GetEnv((void **) &env, JNI_VERSION_1_4) != JNI_OK) {return -1;}assert(env != NULL);if (!registerNatives(env)) { //注册return -1;}result = JNI_VERSION_1_4;return result;
}#ifdef __cplusplus
}
#endif
#endif
demo.cpp
//
// Created by Admins on 2023/5/6.
//
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
#include <string>
/* Header for class com_demo_cppproject_MyNdkTest */#ifndef _Included_com_demo_cppproject_OtherNdkTest
#define _Included_com_demo_cppproject_OtherNdkTest
#ifdef __cplusplus
extern "C" {
#endif
/** Class: com_demo_cppproject_MyNdkTest* Method: getData* Signature: ()Ljava/lang/String;*/
JNIEXPORT jstring JNICALL Java_com_demo_cppproject_OtherNdkTest_getName(JNIEnv *env, jobject){std::string hello = "静态注册!Android mk构建!Hi from C++";return env->NewStringUTF(hello.c_str());
}/** Class: com_demo_cppproject_MyNdkTest* Method: count* Signature: ()I*/
JNIEXPORT jint JNICALL Java_com_demo_cppproject_OtherNdkTest_count(JNIEnv *env, jobject){return 11;
}#ifdef __cplusplus
}
#endif
#endif
Android.mk
# Android.mk 参数# 设置工作目录,它用于在开发tree中查找源文件。宏my-dir由Build System提供,会返回Android.mk文件所在的目录
LOCAL_PATH := $(call my-dir)# CLEAR_VARS变量由Build System提供。指向一个指定的GNU Makefile,由它负责清理LOCAL_xxx类型文件,
# 但不是清理LOCAL_PATH
# 所有的编译控制文件由同一个GNU Make解析和执行,其变量是全局的。所以清理后才能便面相互影响,这一操作必须有
include $(CLEAR_VARS)# LOCAL_MODULE模块必须定义,以表示Android.mk中的每一个模块,名字必须唯一且不包含空格
# Build System 会自动添加适当的前缀和后缀。例如,demo,要生成动态库,则生成libdemo.so。
# 但请注意:如果模块名字被定义为libabd,则生成libabc.so。不再添加前缀。
LOCAL_MODULE := DEMO# 指定参与模块编译的C/C++源文件名。不必列出头文件,build System 会自动帮我们找出依赖文件。
# 缺省的C++ 源码的扩展名为.cpp。
LOCAL_SRC_FILES := demo.cpp# BUILD_SHARED_LIBRARY是Build System提供的一个变量,指向一个GUN Makefile Script。它负责收集自从上次调用include $(CLEAR_VARS)后的所有LOCAL_xxxxinx。并决定编译什么类型
# 1. BUILD_STATIC_LIBRARY:编译为静态库
# 2. BUILD_SHARED_LIBRARY:编译为动态库
# 3. BUILD_EXECUTABLE:编译为Native C 可执行程序
# 4. BUILD_PREBUILT:该模块已经预先编译
include $(BUILD_SHARED_LIBRARY)# 命令:
# ndk-build NDK_PROJECTPATH=. NDK_APPLICATION_MK=Application.mk NDK_BUILD_SCRIPT=Android.mk NDK_LIBS_OUT=..\jniLibs\
Application.mk
#Application.mk 参数
APP_MODULES := DEMO
# 默认生成支持的多种类型.so
APP_ABI := allAPP_STL := c++_shared
#APP_PLATFORM := android-16不配置,打包.so会出错
APP_PLATFORM := android-19
参考:
JNI中native方法的几种注册方式
[NDK]-搭建ndk-build环境
Android Studio 4.0.+NDK .so库生成打包
相关文章:
JNI开发
文件结构(选中的为生成的) CMake构建不需要执行命令,会自动生成so文件打包进apk Android mk构建需要执行命令生成so文件,再打包进apk。命令如下。 # 在jni目录下执行 # 生成com_demo_cppproject_OtherNdkTest.h头文件 javac -h .…...
JAVA有哪些特点?
JAVA有以下特点: 综上所述,Java作为一种先进的面向对象编程语言,具有简单、可移植、健壮、高性能、多线程、动态性、跨平台、开放性和安全性等众多特点,已经成为广泛使用的编程语言之一。 简单易学:JAVA语言的语法与C语…...
使用读写锁提高并发
我们想要的是:允许多个线程同时读,但只要有一个线程在写,其他线程就必须等待。 ReadWriteLock ReadWriteLock的作用: 只允许一个线程写入(其他线程既不能写入也不能读取);没有写入时…...
使用@PropertySource加载配置文件
1.PropertySource和PropertySources注解 1.1.PropertySource注解概述 PropertySource注解是Spring 3.1开始引入的配置类注解。通过**PropertySource注解可以将properties配置文件中的key/value存储到Spring的Environment中,Environment接口提供了方法去读取配置文…...
事务及分布式事务解决方案
基础概念 1.1.事务 事务可以看做是一次大的活动,它由不同的小活动组成,这些活动要么全部成功,要么全部失败。 1.2.本地事务 在计算机系统中,更多的是通过关系型数据库来控制事务,利用数据库本身的事务特性来实现&a…...
【思科、华为、华三、锐捷网络设备巡检命令】
华三 screen-1ength disable 取消分页 displayversion 查看版本 displayclock 查看日期时钟 displayfan 查看风扇状态 displaypower 查看电源信息 displaycpu-usage 查看CPU利用率 displaymemory 查看内存利用率 display environment 查看温度信息 display device 查看设备信息…...
代码随想录算法训练营第五十二天
代码随想录算法训练营第五十二天| 300.最长递增子序列,674. 最长连续递增序列,718. 最长重复子数组 300.最长递增子序列674. 最长连续递增序列718. 最长重复子数组 300.最长递增子序列 题目链接:最长递增子序列 这里是不用处理if nums[i] &l…...
【Linux网络】传输层中UDP和TCP协议
文章目录 1、再谈端口号2、UDP协议3、TCP协议3.1 TCP协议段格式3.2 TCP的三次握手和四次挥手(连接管理机制)3.3 TCP的滑动窗口3.4 TCP的流量控制3.5 拥塞控制3.6 延迟应答和捎带应答3.7 面向字节流和粘包问题3.8 TCP总结 1、再谈端口号 端口号port标识一…...
工具︱ Web3加密浏览器Brave有什么特别之处?
使用浏览器来上网访问和获取各种信息和资源已经成为传统互联网民的普遍活动,下一代互联网协议Web3的核心特点是去中心化,即不依赖于中心化的服务器和数据中心,而是通过分布式的网络节点来实现数据存储和传输。 浏览器承载着信息网络与用户需求…...
绝对不能错过这份沃尔玛实用插件工具大全
龙哥最近发现很多跨境卖家都比较少运营沃尔玛这个平台。沃尔玛除了是世界500强之外,它的线上商城也弄得很好。它的电商平台主要是售卖自营的,然后你也可以入驻来卖自己的产品,就像是我们国内的京东一样。今天龙哥就给大家分享一些沃尔玛专用插…...
【Java】字符串模板拼接的方法
引 在Java中,构建字符串是非常常见的操作。在很多时候,我们都需要使用变量或输入来定制一个文本输出,例如打印日志、生成HTML代码或构建错误消息。而当需要进行字符串连接时,字符串模板是一种常用的方法。在本篇博客中࿰…...
Vue3项目中使用ECharts图表并实现自适应效果
文章目录 一、Vue3项目安装ECharts二、引入、使用ECharts1.创建图表组件,并在父组件中引入使用2.引入ECharts3.ECharts图表自适应 总结 一、Vue3项目安装ECharts 在项目中输入如下代码: npm install echarts --save安装完成可以在package.json中看到&a…...
快速跑通环信IM Android Demo
1、以Android 4.0.0 Demo为例 https://www.easemob.com/download/demo (下载别的版本的demo 可以修改版本号直接下载就就可以) https://downloadsdk.easemob.com/downloads/easemob-sdk-4.0.0.zip 运行时遇到以下报错在项目build.gradle中添加运行时遇…...
leetcode解题思路分析(一百三十九)1190 - 1196 题
反转每对括号间的子串 给出一个字符串 s(仅含有小写英文字母和括号)。请你按照从括号内到外的顺序,逐层反转每对匹配括号中的字符串,并返回最终的结果。注意,您的结果中 不应 包含任何括号。 可以简单的用栈保存当前层…...
PHP+vue基于web的小区物业管理管理系统1995a
小区物业管理系统主要是对小区物业以及居民信息进行管理,方便用户使用该资源的一种有效手段。能有效地对物业以及用户信息进行管理并为广大用户服务是该管理系统的基本要求,同时用户也可以及时了解最新的物业信息,方便地查询相关物业情况。基…...
区间预测 | MATLAB实现QRCNN卷积神经网络分位数回归时间序列区间预测
区间预测 | MATLAB实现QRCNN卷积神经网络分位数回归时间序列区间预测 目录 区间预测 | MATLAB实现QRCNN卷积神经网络分位数回归时间序列区间预测效果一览基本介绍模型描述程序设计参考资料 效果一览 基本介绍 区间预测 | MATLAB实现QRCNN卷积神经网络分位数回归时间序列区间预测…...
【AI 导航网站】为了更好的收集 AI 资源,我开发了一个 AI 导航网站
AI 导航网站 目前 AI 应用正呈迸发式增长,然而一个人获取资源的途径有限,对于目前存在的AI工具不能很好的收集总结,所以基于此,我开发了这个一个AI导航网站,希望通过它,收集出目前存在的热门的AI应用&…...
谈谈HMI 的自动化生成技术
人机界面(HMI)是自动化领域不可或缺重要组成部分。尽管人机界面系统的设计看上去并没有太大的技术门槛,但是设计一个HMI系统的工作量是巨大的。如果你没有足够的耐心便完成不了一个通用的HMI系统。构建UI控件库是一个似乎永远完不成的事情&am…...
docker安装elasticsearch
使用docker部署 部署elasticsearch # 拉取镜像 docker pull elasticsearch# 创建容器 docker run --name es -p 9200:9200 \-p 9300:9300 \-e "discovery.typesingle-node" \-e ES_JAVA_OPTS"-Xms64m -Xmx128m" \-v /home/es/conf/elasticsearch.yml:/…...
Docker:使用dockerFile创建镜像(war包和jar包)
1、使用war包打镜像 (1)在war的当前路径下,新建一个文件——Dockerfile (2)编辑Dockerfile文件 vim Dockerfile Dockerfile文件内容: FROM java:8 # 选择项目中要求的版本 MAINTAINER ylb …...
5个实用技巧让华硕笔记本性能提升30%:GHelper全功能解析
5个实用技巧让华硕笔记本性能提升30%:GHelper全功能解析 【免费下载链接】g-helper Lightweight, open-source control tool for ASUS laptops and ROG Ally. Manage performance modes, fans, GPU, battery, and RGB lighting across Zephyrus, Flow, TUF, Strix, …...
GetQzonehistory:QQ空间数据备份工具全指南
GetQzonehistory:QQ空间数据备份工具全指南 【免费下载链接】GetQzonehistory 获取QQ空间发布的历史说说 项目地址: https://gitcode.com/GitHub_Trending/ge/GetQzonehistory 一、价值定位:数字记忆的守护者 1.1 数据永存的必要性 在数字时代&…...
Wan2.2-I2V-A14B协作开发:利用GitHub进行模型配置与提示词库管理
Wan2.2-I2V-A14B协作开发:利用GitHub进行模型配置与提示词库管理 1. 团队协作的痛点与解决方案 在AI模型开发过程中,团队协作常常面临配置混乱、经验难以共享、问题追踪困难等挑战。特别是对于Wan2.2-I2V-A14B这样的复杂模型,不同环境下的部…...
从零打造微信聊天记录导出工具:PySide6界面开发与PyInstaller打包实战
1. 为什么需要自己开发微信聊天记录导出工具 最近有不少朋友问我,为什么市面上那么多微信聊天记录导出工具,还要自己动手开发?这个问题问得好。作为一个经常需要备份聊天记录的程序员,我试过不下十款工具,发现它们普遍…...
Python爬虫实战:手把手教你古文字字形索引全量采集与图文数据库构建!
㊗️本期内容已收录至专栏《Python爬虫实战》,持续完善知识体系与项目实战,建议先订阅收藏,后续查阅更方便~ ㊙️本期爬虫难度指数:⭐ (基础入门篇) 🉐福利: 一次订阅后,专栏内的所有…...
BGE-Large-Zh与传统算法对比:TF-IDF vs 语义向量
BGE-Large-Zh与传统算法对比:TF-IDF vs 语义向量 当传统的关键词匹配遇到深度语义理解,文本搜索技术正在经历一场革命性的变革 1. 引言:从关键词到语义理解的跨越 在信息检索领域,我们经历了从基于规则到统计方法,再到…...
伊朗媒体:美军试图炸死在伊朗失联飞行员
新华社德黑兰4月5日电 伊朗塔斯尼姆通讯社5日凌晨报道称,美军搜救被击落战机的一名飞行员无果,试图通过空袭其在伊朗的可能藏身之处将其炸死。报道援引一名伊朗军方消息人士的话说,4日夜间至5日凌晨,美军出动战机,轰炸…...
OpenSpeedy:开源游戏速度调节工具提升玩家效率指南
OpenSpeedy:开源游戏速度调节工具提升玩家效率指南 【免费下载链接】OpenSpeedy 🎮 An open-source game speed modifier. 项目地址: https://gitcode.com/gh_mirrors/op/OpenSpeedy 在游戏世界中,时间掌控往往决定着体验质量。当你面…...
你的杜邦线和PCB走线,可能正在‘谋杀’J-Link SWD的高速信号
你的杜邦线和PCB走线,可能正在‘谋杀’J-Link SWD的高速信号 在嵌入式开发中,我们常常会遇到一个令人头疼的问题:昨天还能正常工作的调试接口,今天突然就无法识别芯片了。更令人困惑的是,降低SWD时钟速率后࿰…...
NEURAL MASK 开发避坑指南:解决部署中常见的403 Forbidden等网络问题
NEURAL MASK 开发避坑指南:解决部署中常见的403 Forbidden等网络问题 最近在星图GPU平台上折腾NEURAL MASK服务,发现不少朋友在部署和调用时,总会遇到一些让人头疼的网络和权限问题。比如镜像死活拉不下来,或者好不容易部署好了&…...
