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

常德网站优化推广百度推广投诉电话

常德网站优化推广,百度推广投诉电话,btoc电子网站,国外网站为什么不用备案Android之JNI详解 简介创建项目注册动态注册静态注册 关键词解读基础数据类型引用java对象JNI引用与释放cmake配置文件 简介 JNI(Java Native Interface) 是 Java 提供的一种编程框架,用于在 Java 应用程序中调用和与用其他编程语言&#xf…

Android之JNI详解

  • 简介
  • 创建项目
  • 注册
    • 动态注册
    • 静态注册
  • 关键词解读
  • 基础数据类型
  • 引用java对象
  • JNI引用与释放
  • cmake配置文件

简介

JNI(Java Native Interface) 是 Java 提供的一种编程框架,用于在 Java 应用程序中调用和与用其他编程语言(如 C、C++ 等)编写的本地代码(Native Code)进行交互。它允许 Java 程序访问操作系统或硬件提供的底层功能。

创建项目

  1. 在AS中选择Native C++创建项目
    在这里插入图片描述
  2. 项目结构
  • native.cpp:实现本地代码(Native Code)的C++源文件。
  • CmakeList.txt:是 CMake 工具使用的配置文件,用于指定如何构建一个 C/C++ 项目。CMake 是一个跨平台的构建系统生成器,它可以根据 CMakeLists.txt 文件生成适合特定平台和编译器的构建文件。
    在这里插入图片描述

注册

动态注册

  1. 简介:与静态注册不同,动态注册通过调用 JNI 提供的RegisterNatives函数,在程序运行时显式地注册本地方法。
  2. 实现步骤
    重要点:构建JNINativeMethod结构体:
typedef struct {const char* name; // java类对应的方法名const char* signature;	//函数签名void*       fnPtr;	//cpp方法的指针函数
} JNINativeMethod;
  • 步骤一:
package com.hzh.jnidemo;import androidx.appcompat.app.AppCompatActivity;public class MainActivity extends AppCompatActivity {static {System.loadLibrary("jnidemo");}public native String stringFromJNI();public native String jniTest();
}
  • 步骤二:
//cpp交互方法,这里是属于native的命名
jstring native_stringFromJNI(JNIEnv *env,jobject thiz){return env->NewStringUTF("动态注册成功!");
}
jstring native_jniTest(JNIEnv *env, jobject thisz) {std::string str = "动态注册成功!";return env->NewStringUTF(str.c_str());
}// 需要动态注册native方法的类名
static const char *mClassName = "com/hzh/jnidemo/MainActivity";// 动态注册函数结构数组
static const JNINativeMethod methods[] = {{"jniTest",	//对应java交互类的方法名"()Ljava/lang/String;", //对应方法名的函数签名(jstring *) native_jniTest //对应cpp交互的指针函数},{"stringFromJNI","()Ljava/lang/String;",(void *) native_stringFromJNI}
};JNIEXPORT jint JNI_OnLoad(JavaVM *vm, void *reserved) {JNIEnv* env = NULL;// 1. 获取 JNIEnv,这个地方要注意第一个参数是个二级指针int result = vm->GetEnv(reinterpret_cast<void **>(&env), JNI_VERSION_1_6);// 2. 是否获取成功if(result != JNI_OK){return JNI_VERSION_1_6;}// 3. 注册方法,通过FindClass寻找jclass classMainActivity = env->FindClass(mClassName);//RegisterNatives 函数接受三个参数://jclass clazz:Java 类的引用。//const JNINativeMethod* methods:指向 JNINativeMethod 结构体数组的指针,描述 Java 方法与本地方法的映射关系。//jint nMethods:映射关系的数量。result = env->RegisterNatives(classMainActivity,methods, 2);if(result != JNI_OK){return JNI_VERSION_1_2;}return JNI_VERSION_1_6;
}

JNI_OnLoad是在初始化的时候调用,参考activity的生命周期,通过FindClass找到对应的class,最后通过RegisterNatives来实现动态注册。需要留意的是JNINativeMethod结构体以及RegisterNatives的参数。

静态注册

  1. 简介:通过 JNI 规范中约定的命名规则,将 Java 方法与本地(Native)方法的实现直接映射。这种映射关系在编译时由编译器根据方法名和签名自动生成。
  2. Native命名规则:遵循Java_包名_类名_方法名的格式,包咯面的"."需要转换成“_”,例如Java 类 com.hzh.jnidemo中的方法 MainActivity,对应的 C/C++ 函数名应为com_hzh_jnidemo_MainActivity。
  3. 原理:Java 编译器会根据 native 方法的声明生成方法签名,而 C/C++ 编译器会根据命名规则生成符号表。JVM 在加载类时,通过方法签名匹配符号表中的函数名,完成绑定。
  4. 实现步骤
  • Java端的实现如下:
    通过System.loadLibrary(“*****”)进行加载交互。
package com.hzh.jnidemo;import androidx.appcompat.app.AppCompatActivity;public class MainActivity extends AppCompatActivity {static {System.loadLibrary("jnidemo");}...public native String stringFromJNI();
}
  • Native端的实现:
#include <jni.h>
#include <string>extern "C" JNIEXPORT jstring JNICALL
//*遵循命名规则实现方法*
Java_com_hzh_jnidemo_MainActivity_stringFromJNI(JNIEnv* env,jobject /* this */) {std::string hello = "Hello from C++";return env->NewStringUTF(hello.c_str());
}

关键词解读

  • extern “C”:在 c++ 中可以使用使用 c 代码
  • JNIEXPORT:是一个宏,用于导出本地方法。
  • JNICALL:是一个宏,用于指定调用约定(Calling Convention),通常是个空的宏定义。
  • JNIEnv:是一个指向JNI函数的指针结构体。
    作用:调用JNI函数,如创建Java对象、访问Java字段、调用Java方法等。
    示例:
JNIEnv *env;
jclass clazz = (*env)->FindClass(env, "class");
  • JavaVM:一个指向Java虚拟机的指针,表示整个JVM实例。
  • jclass:表示Java类的引用。
  • jobject:表示Java对象的引用。
  • jmethodID:表示Java方法的标识符。
  • jfieldID:表示Java字段的标识符。

基础数据类型

!](https://i-blog.csdnimg.cn/direct/1bc956b2ab584e4da6e609f6578af899.png)

引用类型
在这里插入图片描述
类型签名

在这里插入图片描述

  • 简介:是用于描述 Java 方法或字段的特定字符串。JNI 签名是方法描述符的一部分,它包含了方法的参数类型和返回值类型,确保本地代码能够正确调用 Java 方法或访问 Java 字段。每次GetMethodID 或 GetFieldID或者返回数据都会用到。
  • 签名格式:
    方法签名的格式为:(参数类型签名)返回值类型签名
    示例:
int add(int a, int b)(II)I
String getName()()Ljava/lang/String;
void print(String message)(Ljava/lang/String;)V

引用java对象

Field/Method ID:JNIEvn 操作 java 对象时会使用 java 中的反射,引用某个属性都需要 field 和 method 的 id,而id都是指针类型。
实现步骤:

  1. 获取 JNIEnv 指针:
  2. 查找类:
  • 使用 FindClass 函数获取 Java 类的引用。
  • 获取方法 ID 或字段 ID:
  • 使用 GetMethodID 或 GetFieldID 获取方法或字段的标识符。
  1. 操作 Java 对象:
  • 使用 NewObject、CallObjectMethod、SetObjectField 等函数创建或操作 Java 对象。

示例:获取一个class的getName()方法

extern "C" JNIEXPORT jstring JNICALL
Java_com_hzh_jnidemo_MainActivity_stringFromJNI(JNIEnv *env, jobject thiz) {// 1. 获取 thiz 的 class,也就是 java 中的 Class 信息jclass thisclazz = env->GetObjectClass(thiz);// 2. 根据 Class 获取 getClass 方法的 methodID//GetMethodID/GetFieldI的参数://jclass//filed/methon name //类型签名: JNI 使用 jvm 的类型签名jmethodID mid_getClass = env->GetMethodID(thisclazz, "getClass", "()Ljava/lang/Class;");// 3. 执行 getClass 方法,获得 Class 对象jobject clazz_instance = env->CallObjectMethod(thiz, mid_getClass);// 4. 获取 Class 实例jclass clazz = env->GetObjectClass(clazz_instance);// 5. 根据 class  的 methodIDjmethodID mid_getName = env->GetMethodID(clazz, "getName", "()Ljava/lang/String;");// 6. 调用 getName 方法jstring name = static_cast<jstring>(env->CallObjectMethod(clazz_instance, mid_getName));......}

JNI引用与释放

  • 局部引用(Local Reference):参考java 中的局部变量
    // 查找类jclass myClass = (*env)->FindClass(env, "com/hzh/jnidemo/MainActivity");// 获取方法 IDjmethodID myMethod = (*env)->GetMethodID(env, myClass, "stringFromJNI", "()Ljava/lang/String");// 调用 Java 方法(*env)->CallVoidMethod(env, obj, myMethod);
  • 全局引用(Global Reference):参考java 中的全局变量
 	// 创建局部引用jobject localRef = (*env)->NewObject(env, /* 类和方法 ID 略 */);// 创建全局引用globalRef = (*env)->NewGlobalRef(env, localRef);//释放//局部的释放DeleteLocalRef(localRef)//全局的释放if (globalRef != NULL) {(*env)->DeleteGlobalRef(env, globalRef);globalRef = NULL;}
  • 弱全局引用(Weak Global Reference):参考java 中的弱引用
	// 创建引用jobject localRef =(*env)->NewObject(env, /* 类和方法 ID 略 */);;weakRef = (*env)->NewWeakGlobalRef(env, localRef);//释放DeleteLocalRef(localRef)

cmake配置文件

# 设置最低版本
cmake_minimum_required(VERSION 3.22.1)# 引用的项目名
project("jnidemo")# 创建的库名
add_library(# 库名字${CMAKE_PROJECT_NAME}# 设置是动态库(SHARED)还是静态库(STATIC)SHARED# 设置库文件native-lib.cpp)# 加载的库,比如第三方的库,脚本等
target_link_libraries(${CMAKE_PROJECT_NAME}androidlog)

导入android项目的配置:

   externalNativeBuild {cmake {path file('src/main/cpp/CMakeLists.txt')version '3.22.1'}}
http://www.dtcms.com/wzjs/101449.html

相关文章:

  • 网店推广的平台有哪些seo 是什么
  • 化工营销型网站网络策划是做什么的
  • 阿里云服务器网站建设深圳网络推广培训中心
  • 怎么把网站做漂亮个人网站制作流程
  • 政府门户网站建设规划书南宁百度推广代理公司
  • 东营垦利灰色词优化培训
  • 合肥做网站排名广州企业网站seo
  • 网站报价收费单建什么网站可以长期盈利
  • 上海网站制作福州军事新闻俄乌最新消息
  • 做推广优化的网站有哪些内容怎么接推广
  • python网站开发实例教程软文发布公司
  • 公众号微信效果好的关键词如何优化
  • 公司商标标志设计seo关键词排名价格
  • 做网站申请域名的流程短视频平台推广方案
  • 企业网站深圳中国的网络营销公司
  • 做一个网站的完整教程高级搜索百度
  • 张家港做网站排名网络推广方案范文
  • 关键词整站排名优化整站优化多少钱
  • 中山企业网站制作公司品牌推广服务
  • 保定微网站 建设排名优化关键词
  • 微信网站建设和维护上海发布微信公众号
  • 做的网站是怎么被收录站长统计app网站
  • 网址生成济宁seo优化公司
  • 网站维护 静态页面企业宣传方式
  • 深圳最好的网站开发公司灵感关键词生成器
  • 网站建设找什么工作百度搜索趋势
  • 重庆网站建设 沛宣百度手机助手下载安卓版
  • 网站建设公司的职责网络销售适合什么人做
  • 吉林做网站数字营销公司排行榜
  • 做国内网站多少钱厦门seo顾问