当前位置: 首页 > news >正文

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库生成打包

http://www.lryc.cn/news/66013.html

相关文章:

  • JAVA有哪些特点?
  • 使用读写锁提高并发
  • 使用@PropertySource加载配置文件
  • 事务及分布式事务解决方案
  • 【思科、华为、华三、锐捷网络设备巡检命令】
  • 代码随想录算法训练营第五十二天
  • 【Linux网络】传输层中UDP和TCP协议
  • 工具︱ Web3加密浏览器Brave有什么特别之处?
  • 绝对不能错过这份沃尔玛实用插件工具大全
  • 【Java】字符串模板拼接的方法
  • Vue3项目中使用ECharts图表并实现自适应效果
  • 快速跑通环信IM Android Demo
  • leetcode解题思路分析(一百三十九)1190 - 1196 题
  • PHP+vue基于web的小区物业管理管理系统1995a
  • 区间预测 | MATLAB实现QRCNN卷积神经网络分位数回归时间序列区间预测
  • 【AI 导航网站】为了更好的收集 AI 资源,我开发了一个 AI 导航网站
  • 谈谈HMI 的自动化生成技术
  • docker安装elasticsearch
  • Docker:使用dockerFile创建镜像(war包和jar包)
  • 2.基础篇
  • 取代你的可能不是AI,而是比你更会使用AI的人
  • NECCS|全国大学生英语竞赛C类|词汇和语法|语法题|时态 非谓语动词 |19:00~20:15|完形填空·词性转化
  • 【高等数学笔记】Stolz定理
  • 【24】核心易中期刊推荐——图像处理研究大数据及智能处理研究
  • Codeforces Round 870 (Div. 2)【A、B、C、D】
  • BetaFlight统一硬件AOCODARC H7DUAL配置文件讨论
  • 力扣题库刷题笔记682-棒球比赛
  • SpringCloud------Eureka修改实例显示信息、服务发现Discovery、自我保护(六)
  • Java 远程debug,IDEA 远程 Debug 调试
  • 将webrtc的音频模式改为共享模式