JNI之函数介绍一

NDK  2023年7月22日 am8:08发布1年前 (2023)更新 城堡大人
112 0 0

前言

虽然jni.h中定义了很多函数,但也不是每个都需要用,这个主要是看需求。今天介绍一下常用jni函数,方便自己后续查阅。

正文

每个个函数可通过JNIEnv指针以固定偏移量进行访问。JNIEnv指针可指向存储全部JNI函数指针的结构。

如果要看全部的函数定义,可以看《NDK中jni.h头文件完整内容》,这里只介绍常用的函数。

GetVersion

返回本地方法接口的版本。

jint        (*GetVersion)(JNIEnv *env);

仅一个参数,env是jni接口指针。

在C++中调用更简洁些,后续都以C++方法调用,不重复解释了。

jint version = env->GetVersion();
#打印十六进制
LOGE("GetVersion:%#x", version);

输出

GetVersion:0x10006

16 位返回主版本号,低 16 位返回次版本号

我这用的是jdk1.6。

FindClass

jclass      (*FindClass)(JNIEnv* env, const char* name);

该函数用于加载本地定义的类。搜索在由环境变量 CLASSPATH 目录下的子目录和zip文件中搜索指定的类名。

只关注第二个参数name,类全名 ,即包名后跟类名,之间由“ /” 分隔。如果名称以“ [” ( 数组签名字符)打头,则返回一个数组类 。

举些例子:

# String 的类全名(java.lang.String)
name = "Ljava/lang/String"

# Object[] 的类全名
name = "[Ljava/lang/Object;"

# 自定义Hello类
name = "com/biumall/dynamic/one/Hello"

如果存在,返回指定名称的类的对象,否则返回NULL。

存在如下异常:

  1. ClassFormatError:如果class内容不是一个有效的class文件。

  2. ClassCircularityError:如果class或interface是它自己的父类或父接口,造成循环层级关系。

  3. OutOfMemoryError:如果系统在载入的过程中内存不足

  4. NoClassDefFoundError`:如果指定的类或接口没有被找到。

GetSuperclass

jclass      (*GetSuperclass)(JNIEnv* env, jclass clazz);
  1. 如果clazz代表类而非类object,则该函数返回由clazz所指定的类的超类。

  2. 如果clazz指定类object或代表某个接口,则该函数返回 NULL 。

至于第二个参数表示clazz还是object的,可以看《JNI之函数的参数介绍》这篇。

这里总结一下,clazz在静态函数时是jcalss,非静态时是jobject。

IsAssignableFrom

jboolean    (*IsAssignableFrom)(JNIEnv* env, jclass clazz1, jclass clazz2);

判断clazz1的对象是否可安全地强制转换为clazz2。

如果是以下情况则返回 JNI_TRUE :

  • clazz1 和 clazz2 指向同一个java类

  • clazz1 是 clazz2 的子类。(向上转型是安全的)

  • clazz1 是 clazz2(接口)的实现类。(也属于向上转型)

Throw

jint Throw(JNIEnv *env, jthrowable obj);

触发一个 java.lang.Throwable 对象的异常被抛出。obj是java.lang.Throwable对象。

成功则返回0, 失败时返回负数。

抛出 java.lang.Throwable 对象。

jthrowable exception = env->ExceptionOccurred();
if (exception) {
  env->ExceptionClear();
  detach_internal(env, this_obj);
  env->Throw(exception);
  return;
}

ThrowNew

jint ThrowNew(JNIEnv *env, jclass clazz, const char *message);

Exception对象的构造器函数,message为异常的错误消息,clazz为异常的类。

clazz为java.lang.Throwable的子类。

message用于创建 java.lang.Throwable 对象时传入的错误消息。这个是字符串是UTF-8编码。

成功则返回0, 失败时返回负值。并抛出刚构造出来的 java.lang.Throwable对象。

env->ThrowNew(env->FindClass("sun/jvm/hotspot/debugger/DebuggerException"), errMsg);

其他的暂时不记录了,主要没常用。请看参考文3吧。多谢

参考文章

  1. JNI完全手册]》

  2. NDK中jni.h头文件完整内容

  3. JNI技术规范 - 第四章 JNI函数(1)》(后面几个函数的主要来源)

 历史上的今天

  1. 2021: 余秋雨:我在等你(0条评论)
  2. 2019: 郁达夫:北平的四季(0条评论)
版权声明 1、 本站名称: 笔友城堡
2、 本站网址: https://www.biumall.com/
3、 本站部分文章来源于网络,仅供学习与参考,如有侵权,请留言

暂无评论

暂无评论...

随机推荐

早班火车:淡黄色的山坡

我记得我们象鸟儿一样站在树上坡下是另一个村庄我们吆喝着彼此的名字那声音在脚下盘旋连山上的刚冒出来的嬷嬷花都听到了我们去刨小蒜我们看麦地一群群暗褐色的乌鸦红拉拉的喙落下来啄食幼苗我们虚张声势惊走他们风很大半导体里的天气预报说“北部”的时候我们的老师就解释那是说我们的家乡年轻人...

Android WindowManager弹窗容易出现的问题

WindowManager弹窗提示时需要注意下,比如系统应用和非系统应用权限的不同、Android不同版本的权限申请不同等,下面是我在应用中出现的问题,因此整理一下。问题一:没有设置android.permission.SYSTEM_ALERT_WINDOW出现异常提示Unable to a...

龙应台:回家

三个兄弟,都是五十多岁的人了,这回摆下了所有手边的事情,在清明节带妈妈回乡。 红磡火车站大厅里,人潮涌动,大多是背着背包、拎着皮包、推着带滚轮的庞大行李箱、扶老携幼的,准备搭九广铁路北上。就在这川流不息的滚滚红尘里,妈妈突然停住了脚。她皱着眉头说:“这,是什么地方?”哥哥原来就一路牵着她的手,这...

蒙田:论友谊

人类钟情于交往超过任何其他活动,这或许是本能赋予我们的。亚里士多德曾说,最好的法官把友谊看得比正义好重要。友谊各种各样,通常由欲望、利益、公众或私人的需要和维系。因此越是掺杂着其他的动机、目的和利益的就越难有其美好和真诚的东西,也就越无友谊可言了。从古到今,友谊有四种:血缘的、社交的、礼仪的和男女...

Android View Binding的使用简介

前言简单记录一下,方便自己查阅。好记性不如烂笔头正文PS: 本文内容大都摘抄,感谢什么是View BindingView Binding是Android Studio 3.6推出的新特性,目的是为了替代findViewById(内部实现还是使用findViewById)。在启动视图绑...

Android截图命令总结

前言简单记录一下Android设备多个屏幕或单个屏幕的截图方式。记录一下,方便自己查阅。正文查看displayId查看有屏幕的displayIdadb shell dumpsys window displays | grep displayIdubuntu$ adb shell d...