位置: 编程技术 - 正文

深入了解android平台的jni---注册native函数(深入了解是啥意思)

编辑:rootadmin
注册native函数有两种方法:静态注册和动态注册。1、静态注册方法根据函数名找到对应的JNI函数:Java层调用函数时,会从对应的JNI中寻找该函数,如果没有就会报错,如果存在则会建立一个关联联系,以后在调用时会直接使用这个函数,这部分的操作由虚拟机完成。静态方法就是根据函数名来遍历java和jni函数之间的关联,而且要求jni层函数的名字必须遵循特定的&#;式,其缺点在于:1)javah生成的jni层函数特别长;2)初次调用native函数时要根据名字搜索对应的jni层函数来建立关联联系,这样影响效率。2、动态注册方法JNI 允许你提供一个函数映射表,注册给Jave虚拟机,这样Jvm就可以用函数映射表来调用相应的函数,就可以不必通过函数名来查找需要调用的函数了。Java与JNI通过JNINativeMethod的结构来建立联系,它在jni.h中被定义,其结构内容如下:typedef struct {const char* name;const char* signature;void* fnPtr;} JNINativeMethod;第一个变量name是Java中函数的名字。第二个变量signature,用字符串是描述了函数的参数和返回&#;第三个变量fnPtr是函数指针,指向C函数。当java通过System.loadLibrary加载完JNI动态库后,紧接着会查找一个JNI_OnLoad的函数,如果有,就调用它,而动态注册的工作就是在这里完成的。1)JNI_OnLoad()函数JNI_OnLoad()函数在VM执行System.loadLibrary(xxx)函数时被调用,它有两个重要的作用:指定JNI版本:告诉VM该组件使用那一个JNI版本(若未提供JNI_OnLoad()函数,VM会默认该使用最老的JNI 1.1版),如果要使用新版本的JNI,例如JNI 1.4版,则必须由JNI_OnLoad()函数返回常量JNI_VERSION_1_4(该常量定义在jni.h中) 来告知VM。初始化设定,当VM执行到System.loadLibrary()函数时,会立即先呼叫JNI_OnLoad()方法,因此在该方法中进行各种资源的初始化操作最为恰当,2)RegisterNativesRegisterNatives在AndroidRunTime里定义syntax:jint RegisterNatives(jclass clazz, const JNINativeMethod* methods,jint nMethods)3、在android中加入自定义的native函数JNI在Android层次结构中的作用如下图所示: 在Android中,主要的JNI代码在以下的路径中:Android源码根目录/frameworks/base/core/jni/这个路径中的内容将被编译成库libandroid_runtime.so,这就是一个普通的动态库,被放置在目标系统的/system/lib目录中.除此之外,Android还包含其他的JNI库,例如,媒体部分的JNI目录frameworks/base/media/jni/中,被编译成库libmedia_jni.so.JNI中的各个文件实际上就是C&#;&#;的普通文件,其命名一般和支持的Java类有对应关系。这种关系是习惯上的写法,而不是强制的。1)注册JNI方法在Android源码根目录/frameworks/base/services/jni/目录下有一个onload.cpp文件,加入 jni函数申明和jni函数注册方法#include "JNIHelp.h" #include "jni.h" #include "utils/Log.h" #include "utils/misc.h" namespace android { int register_android_server_AlarmManagerService(JNIEnv* env); int register_android_server_BatteryService(JNIEnv* env); int register_android_server_InputApplicationHandle(JNIEnv* env); int register_android_server_InputWindowHandle(JNIEnv* env); int register_android_server_InputManager(JNIEnv* env); int register_android_server_LightsService(JNIEnv* env); int register_android_server_PowerManagerService(JNIEnv* env); int register_android_server_UsbDeviceManager(JNIEnv* env); int register_android_server_UsbHostManager(JNIEnv* env); int register_android_server_VibratorService(JNIEnv* env); int register_android_server_SystemServer(JNIEnv* env); int register_android_server_location_GpsLocationProvider(JNIEnv* env); int register_android_server_connectivity_Vpn(JNIEnv* env); int register_android_server_HelloService(JNIEnv *env); //此处加入自定义jni函数申明}; using namespace android; extern "C" jint JNI_OnLoad(JavaVM* vm, void* reserved) { JNIEnv* env = NULL; jint result = -1; if (vm->GetEnv((void**) &env, JNI_VERSION_1_4) != JNI_OK) { LOGE("GetEnv failed!"); return result; } LOG_ASSERT(env, "Could not retrieve the env!"); register_android_server_PowerManagerService(env); register_android_server_InputApplicationHandle(env); register_android_server_InputWindowHandle(env); register_android_server_InputManager(env); register_android_server_LightsService(env); register_android_server_AlarmManagerService(env); register_android_server_BatteryService(env); register_android_server_UsbDeviceManager(env); register_android_server_UsbHostManager(env); register_android_server_VibratorService(env); register_android_server_SystemServer(env); register_android_server_location_GpsLocationProvider(env); register_android_server_connectivity_Vpn(env); register_android_server_HelloService(env); //jni方法注册 return JNI_VERSION_1_4; } onload.cpp文件上部分为注册函数的声明,下部分为调用各种注册函数,而这些注册函数就是JNI方法的注册函数! 正是通过这些注册函数,上层才能调用注册的JNI方法.以register_android_server_HelloService为例,来看一个注册函数的具体实现过程是如何的。打开com_android_service_HelloService.cpp文件2)加入注册函数的实现代码,如下:int register_android_server_HelloService(JNIEnv *env) { return jniRegisterNativeMethods(env, "com/android/server/HelloService", method_table, NELEM(method_table)); } #其中jniRegisterNativeMethods为注册JNI方法函数,#此函数的第二个参数为对应着java类即HelloService.java的文件名,第三个参数为注册的方法表3)加入jni方法表 static const JNINativeMethod method_table[] = { {"init_native", "()Z", (void*)hello_init}, {"setVal_native", "(I)V", (void*)hello_setVal}, {"getVal_native", "()I", (void*)hello_getVal}, }; 4)方法表内各个接口的实现代码static void hello_setVal(JNIEnv* env, jobject clazz, jint value) { val = value; LOGI("Hello JNI: set value %d to device.", val); } static jint hello_getVal(JNIEnv* env, jobject clazz) { LOGI("Hello JNI: get value %d from device.", val); return val; } static jboolean hello_init(JNIEnv* env, jclass clazz) { LOGI("Hello JNI: initializing......"); return -1; } 完整代码如下:namespace android{ int val; static void hello_setVal(JNIEnv* env, jobject clazz, jint value) { val = value; LOGI("Hello JNI: set value %d to device.", val); } static jint hello_getVal(JNIEnv* env, jobject clazz) { LOGI("Hello JNI: get value %d from device.", val); return val; } static jboolean hello_init(JNIEnv* env, jclass clazz) { LOGI("Hello JNI: initializing......"); return -1; } static const JNINativeMethod method_table[] = { {"init_native", "()Z", (void*)hello_init}, {"setVal_native", "(I)V", (void*)hello_setVal}, {"getVal_native", "()I", (void*)hello_getVal}, }; int register_android_server_HelloService(JNIEnv *env) { return jniRegisterNativeMethods(env, "com/android/server/HelloService", method_table, NELEM(method_table)); } }出处:

推荐整理分享深入了解android平台的jni---注册native函数(深入了解是啥意思),希望有所帮助,仅作参考,欢迎阅读内容。

深入了解android平台的jni---注册native函数(深入了解是啥意思)

文章相关热门搜索词:深入了解求助者时,首先要进行工作是,深入了解对方的36个问题,深入了解英语,深入了解的高级表达,深入了解android系统,深入了解的高级表达,深入了解android系统,深入了解的高级表达,内容如对您有帮助,希望把文章链接给更多的朋友!

Android 接口回调实例 Android接口回调方法处处涉及到,比如常用的Button点击事件就是一个接口回调,可见掌握熟练使用接口回调方法的重要性。接口回调的简单解释就是:比

Android中Context详解 大家好,今天给大家介绍下我们在应用开发中最熟悉而陌生的朋友-----Context类,说它熟悉,是应为我们在开发中时刻的在与它打交道,例如:Service、Broa

Afinal AfinalAfinal是什么

标签: 深入了解是啥意思

本文链接地址:https://www.jiuchutong.com/biancheng/378124.html 转载请保留说明!

上一篇:静态注册JNI和动态注册JNI(jni静态注册和动态注册)

下一篇:Android 接口回调实例(接口回调java)

  • 员工离职再入职个税人员信息该如何录入?
  • 六税一费优惠政策
  • 报送会计报表
  • 购入固定资产入账
  • 个人所得税怎么交
  • 资本回收系数等于什么系数与利率之和
  • 仓储货架工厂仓库货架
  • 产品因质量问题造成损害的,应当承担责任的主体是
  • 或有负债记入哪个科目?
  • 国税局网上申报
  • 当期免抵税额和当期留抵税额
  • 汇算清缴交的税怎么做分录
  • 电子商业承兑与银行承兑哪个好
  • 电脑不用的情况下怎么让它关闭屏幕
  • 广告费和业务宣传费
  • 工会经费会计分局
  • 退休返聘人员的优点
  • 如何给网页添加水印
  • 排污费应计入什么会计科
  • 工程结算和决算一样吗
  • PHP:getimagesizefromstring()的用法_GD库图像处理函数
  • 无偿转让股权如何做账
  • 税收返还会计核算
  • 卢塞恩小镇瑞士
  • 自动驾驶决策规划技术理论与实践电子版
  • web主要的请求方式有几种
  • vue常用
  • 使用微软必应需要哪些条件
  • thinkphp自动加载类
  • php 自定义函数
  • 多交增值税计入什么科目
  • 固定资产的装修费计入固定资产吗
  • 固定资产租赁费的税率是多少
  • 增值税普通发票有什么用
  • 收银算不算财务工作
  • 一般纳税人内账考虑税额吗
  • 停工期间工资支付标准
  • 负债类科目有借贷方向吗
  • 销售旧货和销售使用过的固定资产区别
  • SQL2005 自动备份的脚本
  • 公司销售不动产增值税
  • 物业建车棚谁出钱
  • 其他收益期末余额
  • 跨年进项发票怎样账务处理
  • 跨年度退货
  • 电子发票上面的字体是什么字体
  • 投资收益的账务怎么处理
  • 建筑简易征收适用哪些业务
  • 业务收入和营业收入关系
  • 最新职工福利费列支范围
  • Windows下MySQL5.7.18安装教程
  • mysql5.7卸载重装
  • 应用商店升级版
  • SUSE Linux Enterprise Server 11 SP3安装教程详解
  • linux或者命令
  • win10怎么把中文系统改成英文
  • mac使用命令行
  • Win10最新版下载天翼云盘
  • win10系统网络连接配置异常
  • 什么是四个菜
  • 教你一行代码
  • 输出语句的执行过程
  • 批处理自动确定
  • python的理解
  • nodejss
  • python怎么生成随机函数
  • 适用于分析原因的工具有哪些
  • node.js和ajax的顺序
  • html5过渡的触发机制
  • javascript面向对象精要pdf
  • jquery通过属性值获取元素
  • 寻找志同道合的小伙伴
  • 四川省税务局发票查询
  • 购买增值税发票税务局打电话来问怎么处理?
  • 江西省国家税务局
  • 地税的发票是什么样
  • 消费税的征收范围是如何规定的
  • 1000元钱0.05%的利息是多少
  • 郑州土地出让金2023年多少
  • 免责声明:网站部分图片文字素材来源于网络,如有侵权,请及时告知,我们会第一时间删除,谢谢! 邮箱:opceo@qq.com

    鄂ICP备2023003026号

    网站地图: 企业信息 工商信息 财税知识 网络常识 编程技术

    友情链接: 武汉网站建设