Android JNI开发高级篇有关Android JNI开发中比较强大和有用的功能就是从JNI层创建、构造Java的类或执行Java层的方法获取属性等操作。 一、类的相关操作 1. jclass FindClass(JNIEnv *env, const char *name);

摘要:
4.jmethodIDGetStaticMethodID;5.NativeTypeCallStaticXXXMethod;三、访问Java对象的域Java对象的域或者说字段、属性类似方法的执行1.jfieldIDGetFieldID;获取实例对象的域ID需要注意的是,非静态的实例化后的对象,可能产生的异常有(1NoSuchFieldError找不到指定的域(2ExceptionInInitializerError因为异常而导致类初始化失败(3OutOfMemoryError内存不足。

有关Android JNI开发中比较强大和有用的功能就是从JNI层创建、构造Java的类或执行Java层的方法获取属性等操作。

一、类的相关操作

1.jclass FindClass(JNIEnv *env, const char *name);查找类

该函数可能做过Java开发的不会陌生,这个是JNI层的实现,需要注意的是第二个参数为const char*类型的,我们如果从Java从层传入unicode编码的jstring类型需要使用GetStringUTFChars函数转换成utf8的const char*,如果成功返回这个Java类的对象jclass,相关的异常可能有

(1.ClassFormatError 类的数据格式无效
(2. ClassCircularityError 该类或接口是自身的超类或超接口
(3. NoClassDefFoundError 没有找到指定名称的类或接口
(4. OOM内存不足错误,即OutOfMemoryError

2.jclass GetSuperclass(JNIEnv *env, jclass clazz);获取父类或者说超类

该函数的第二个参数为jclass类,我们调用时传入的是子类,否则返回将是NULL

3.jboolean IsAssignableFrom(JNIEnv *env, jclass clazz1,jclass clazz2);判断class1对象能否安全的强制转换为class2对象

如果可以将返回 JNI_TRUE,JNI_TRUE的定义值为1,否则返回JNI_FALSE即0 ,这里Android123详细说明下哪些情况可能返回真:

(1 这两个类参数引用同一个 Java 类
(2 第一个类是第二个类的子类
(3 第二个类是第一个类的某个接口

4.jclass GetObjectClass(JNIEnv *env, jobject obj);通过对象获取这个类

该函数比较简单,唯一注意的是对象不能为NULL,否则获取的class肯定返回也为NULL。

5.jboolean IsInstanceOf(JNIEnv *env, jobject obj,jclass clazz);判断对象是否为某个类的实例

这个函数是JNI层的实现,相信大家都不陌生,Android开发网提醒大家需要注意的是返回值可能产生异议,就是如果传入的第二个参数为NULL对象,NULL对象可以强制转换为各种类,所以这种情况也将会返回JNI_TRUE,所以一定判断传入的对象是否为空。

6.jboolean IsSameObject(JNIEnv *env, jobject ref1,jobject ref2); 判断两个对象是否引用同一个类

需要注意的是如果两个对象均为空,返回的值也会是JNI_TRUE所以使用时判断对象为空。

二、调用Java方法

首先说下有关签名sig相关的比如 "Ljava/lang/String;"

1.jmethodID GetMethodID(JNIEnv *env, jclass clazz,const char *name, const char *sig); 获取一个Java方法的ID

这个函数将返回非静态类或接口实例方法的方法 ID。这个方法可以是某个clazz 的超类中定义,也可从clazz 继承,最后一个参数为签名,最后两个参数是const char*类型,是utf8类型。需要注意的是Android123提醒大家执行GetMethodID()函数将导致未初始化的类初始化,如果要获得构造函数的方法ID,使用 <init> 作为方法名,同时将 void (V) 作为返回类型,如果找不到指定的ID将返回NULL,同时异常可能有:

(1 NoSuchMethodError 找不到指定的Java方法。
(2 ExceptionInInitializerError 如果由于异常而导致类初始化程序失败
(3 OutOfMemoryError 内存不足

2 .NativeType CallXXXMethod (JNIEnv *env, jobject obj,jmethodID methodID, va_list args);调用XXX类型的Java方法

执行Java类中某个方法,需要注意的是这个里的java类是非静态的,由于Java的方法的类型比较多,所以该函数可能有以下几种形式,如CallObjectMethod,CallBooleanMethod,CallByteMethod,CallCharMethod,CallShortMethod,CallIntMethod,CallLongMethod,CallFloatMethod,CallDoubleMethod和CallVoidMethod,需要注意的是,该函数的第三个参数为通过GetMethodID函数获取的方法ID,最后一个参数为这个方法的参数表,最后的va_list宏可以通过搜索获取具体的使用方法,这里Android开发网不再赘述。

3.NativeType CallNonvirtualXXXMethod (JNIEnv *env, jobject obj,jclass clazz, jmethodID methodID, jvalue *args);

CallNonvirtualXXXMethod函数和上面的CallXXXMethod 不同之处是多了一个jclass参数,CallXXXMethod是根据对象来调用方法,而CallNonvirtualXXXMethod是根据类的实例调用,区别在这点。

上面的三个均为非静态类的获取,执行调用,需要实例化这个类才可以执行,下面的为静态调用。

4. jmethodID GetStaticMethodID(JNIEnv *env, jclass clazz,const char *name, const char *sig);

5. NativeType CallStaticXXXMethod(JNIEnv *env, jclass clazz,jmethodID methodID, ...);

三、访问Java对象的域

Java对象的域或者说字段、属性(Field) 类似方法的执行

1. jfieldID GetFieldID(JNIEnv *env, jclass clazz,const char *name, const char *sig); 获取实例对象的域ID

需要注意的是,非静态的实例化后的对象,可能产生的异常有

(1 NoSuchFieldError 找不到指定的域
(2 ExceptionInInitializerError 因为异常而导致类初始化失败
(3 OutOfMemoryError内存不足。

2. NativeType GetXXXField(JNIEnv *env, jobject obj,jfieldID fieldID);

类似GetXXXMethod函数,可能有的类型有 GetObjectField,GetBooleanField,GetByteField,GetCharField,GetShortField,GetIntField,GetLongField,GetFloatField,GetDoubleField。

3. void SetXXXField(JNIEnv *env, jobject obj, jfieldID fieldID,NativeType value);

Java的域可以赋值的,可能有的类型有 SetObjectField,SetBooleanField,SetByteField,SetCharField,SetShortField,SetIntField,SetLongField,SetFloatField,SetDoubleField。

上面3种情况均为非静态对象的域,对于不需要实例化对象的域,可以直接使用下面的。

4. jfieldID GetStaticFieldID(JNIEnv *env, jclass clazz,const char *name, const char *sig);

5. NativeType GetStaticXXXField(JNIEnv *env, jclass clazz,jfieldID fieldID);

6. void SetStaticXXXField(JNIEnv *env, jclass clazz,jfieldID fieldID, NativeType value);

四、实例代码,Android123给网友准备了一个例子,帮助大家实战Android JNI开发,大家可以移植到Android NDK环境中执行,网友可以访问 Android JNI开发代码 (Android JNI实例代码(一))

最后有关Android JNI最后的终极内容,Android开发网主要说明下JVM和JNI的全局引用相关内容,比如本地全局引用LocalGlobalRef,弱全局引用WeakGlobalRef,JNI中线程处理的高级方法比如AttachCurrentThread,以及JNI中的NIO的相关特性将在明天继续讲解,更多的有关Android平台NDK开发内容可以查看我们 Android NDK开发技巧系列文章。

免责声明:文章转载自《Android JNI开发高级篇有关Android JNI开发中比较强大和有用的功能就是从JNI层创建、构造Java的类或执行Java层的方法获取属性等操作。 一、类的相关操作 1. jclass FindClass(JNIEnv *env, const char *name);》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇一次性完成分页查询并且附带数据总条数SQLServer代理新建或者编辑作业报错下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

Android 4.0 SDK的离线方式安装(转)

转自:http://networking.ctocio.com.cn/110/12195610.shtml  作 为一个IT技术人员,迫不及待地就奔向了http://developer.android.com去看看有没有新的SDK公布出来,当时是上午,没见到 有更新,心想一定是若干天后才会发布。没想到同事下午告诉我,新版的SDK已经发布了。当时是临下班,...

Android上GDB的使用

转自:blog.163.com/bjtornado@yeah/blog/static/69510484201081181657449/ 1) 编译包含Debug 信息设置如下环境变量:TARGET_BUILD_TYPE=debugTARGET_STRIP_MODULE=false (发现即使设置编译为Debug模式, 最后生成的文件系统中的程序和库还是会被...

Android权限大全1

这是我在网上搜集的所有有关Android的一些权限,希望能帮到大家一些 权限定义 功能 android.permission.ACCESS_CHECKIN_PROPERTIES 允许读写访问"properties"表在checkin数据库中,改值可以修改上传 android.permission.ACCESS_COARSE_LOCATION 允...

SqlServer数据库基本用法

1. 利用T-SQL语句,创建数据库(工资管理数据库),要求如下: 数据库初始大小:3MB;文件大小按兆字节3MB自动增长,增长限制为:15MB; 数据库日志文件初始大小:1MB; 文件大小按百分比5%自动增长,增长限制为:10MB; 设定数据库文件保存路径为D:gzgl,其余为默认。 create database工资管理数据库 on(name=工资管...

SQL SERVER性能分析死锁检测数据库阻塞语句&amp;lt;转&amp;gt;

工作中数据库经常出现内存,找了篇文章 参照CSDN,中国风(Roy)一篇死锁文章 阻塞:其中一个事务阻塞,其它事务等待对方释放它们的锁,同时会导致死锁问题。 整理人:中国风(Roy) 参照Roy_88的博客 http://blog.csdn.net/roy_88/archive/2008/07/21/2682044.aspx 日期:2008.07.20...

echarts实时数据图表

import React, { PureComponent } from 'react'; import ReactEcharts from 'echarts-for-react'; import moment from 'moment'; export defaultclass Charts extends PureComponent { getO...