此系列记录Android NDK基础开发知识,在Android NDK开发基础篇(一)中介绍了NDK、JNI以及关系,包括AS创建JNI的项目及第一个函数解析,

目的

  1. Java类型和native类型的映射关系
  2. jobject
  3. jclass
  4. JNIEnv 的基本使用

用于参数解析:

Java_com_kpa_jnijavademo_MainActivity_stringFromJNI(        JNIEnv *env,        jobject obj/* this */) {    return env->NewStringUTF(hello.c_str());}

一、Java类型和native类型的映射关系

Java类型 本地类型 JNI定义的别名
int long jint/jsize
short short jshort
long _int64 jlong
float float jfloat
double double jdouble
byte signed char jbyte
boolean unsigned char jboolean
char unsigned char jchar
Object _jobject* jobject

本地类型指的是在C/C++中的使用,JNI定义的别名是C/C++在JNI中的使用,不需要多记,后续回经常出现

二、 jobject

jobject 表示的是Java中的Object类型,在参数中有两个不同的意义需要知道

  • native方法是static 修饰的: 代表native方法的类的class对象的实例
  • native方法不是static 修饰的:表示native方法的实例

三、jclass

jclass 表示Java的中的Class类

在下面的JNIEnv 中会解释jclass 在C/C++中的集中获取方法

四、 JNIEnv

JNIEnv 类型在native 中实际代表了Java在native中的Java环境 ,通过JNIEnv*指针可以对Java端的代码进行操作,为什么JNI开发中首先要了解对Java的操作呢?

JNI作为Java和C/C++的连接桥梁,自然能在C/C++中操作Java的对象,最起码我们在C/C++中的一系列操作完成之后,将结果返回给Java就需要用到Java操作,以此问题还有很多。

既然是代表了Java环境,那首先有这几个概念需要了解一下:

  1. 对象
  2. 属性
  3. 方法

这是最起码操作一个Java对象应该具备的要素

4.1在native中创建一个Java对象

Newobject

/***jclass : Class 对象(后续解释怎么获取一个class对象)*methodID: 方法ID**/jobject NewObject(jclass clazz, jmethodID methodID, ...)    {        va_list args;        va_start(args, methodID);        jobject result = functions->NewObjectV(this, clazz, methodID, args);        va_end(args);        return result;    }

jmethodID 在JNI中表示一个指向method的指针,创建对象时的method哪里来呢? 没错就是构造方法

为了后续更好的理解 先看一下jclass 的获取方法

4.2 JNIEnv 中获取jclass 的方法

  • FindClass
// 通过类的全名获取class 对象 jclass FindClass(const char* name)    { return functions->FindClass(this, name); }

eg:

// 获取Java中Date 对象的Class对象jclass date_clazz = env->FindClass("java/util/Date");
  • GetObjectClass
// 通过native方法中的jobject对象获取Class 对象jclass GetObjectClass(jobject obj)    { return functions->GetObjectClass(this, obj); }

eg:

Java_com_kpa_jnijavademo_JNIDemo_sayHello(JNIEnv *env, jobject thiz) {// 根据native sayHello方法中jobject 的class 对象    jclass jniDemo = env->GetObjectClass(thiz);    }
  • GetSuperClass
//根据jclass 可以获取他的父类的jclass 对象jclass GetSuperclass(jclass clazz)    { return functions->GetSuperclass(this, clazz); }

4.3 JNI获取jmethod、jfieldID

GetMethodID/GetStaticMethodID

/*** clazz 所在class 对象* name: 方法名称* sig: 方法签名(变量和方法在JNI中都是有签名的)**/jmethodID GetMethodID(jclass clazz, const char* name, const char* sig)    { return functions->GetMethodID(this, clazz, name, sig); }jmethodID GetStaticMethodID(jclass clazz, const char* name, const char* sig)    { return functions->GetStaticMethodID(this, clazz, name, sig); }

GetFieldID/GetStaticFieldID

jfieldID GetFieldID(jclass clazz, const char* name, const char* sig)    { return functions->GetFieldID(this, clazz, name, sig); }jfieldID GetStaticFieldID(jclass clazz, const char* name, const char* sig)    { return functions->GetStaticFieldID(this, clazz, name, sig); }

通过javap命令查看类中的属性和方法的签名

javap -s -p XXX.class

eg:

public class com.kpa.jnijavademo.Demo {  public int a;    descriptor: I  public com.kpa.jnijavademo.Demo();    descriptor: ()V //构造方法签名  public int add(int, int);    descriptor: (II)I  public static void main(java.lang.String[]);    descriptor: ([Ljava/lang/String;)V}

I、()V、(II)I都是签名

eg:

void createObj1(JNIEnv *env) {// native 创建Java对象// 获取Java中的Date的Class对象    jclass date_clazz = env->FindClass("java/util/Date");    // 获取构造方法的ID 构造方法名称始终是    jmethodID mid_date = env->GetMethodID(date_clazz, "", "()V");    // 生成Date对象    jobject date_obj = env->NewObject(date_clazz, mid_date);    jmethodID get_time_id = env->GetMethodID(date_clazz, "getTime", "()J");    jlong time = env->CallLongMethod(date_obj, get_time_id);    printf("时间 ==== %I64d", time);}

然后看一下上面4.1中NewObject创建一个对象

eg:

// 获取Java中的Date的Class对象    jclass date_clazz = env->FindClass("java/util/Date");    // 获取构造方法的ID 构造方法名称始终是    jmethodID mid_date = env->GetMethodID(date_clazz, "", "()V");

4.4

到此为止,介绍了JNI中如果获取对象的Class 对象,创建对象,以及获取方法、属性等功能。

在Android NDK特别篇中多介绍几个使用案例

更多相关文章

  1. Android快速开发工具集合——YUtils
  2. Android的Btimap处理大图片解决方法
  3. JetPack 之 DataBinding 的使用
  4. Android中如何将dp,dip,sp与px相互转化
  5. Android屏幕元素层次结构
  6. 浅谈Java中Collections.sort对List排序的两种方法
  7. 类和 Json对象
  8. Python list sort方法的具体使用
  9. python list.sort()根据多个关键字排序的方法实现

随机推荐

  1. 使用 Android Compatibility Package 来
  2. Mac下Android Studio使用
  3. android 网络实时监听网络状态变化 及 网
  4. C#开发Android手机应用全接触(mono for a
  5. Android ListView 不显示分割条 分隔条
  6. android基础知识15:获得android系统信息01
  7. 【Android】跑马灯效果(文字滚动)
  8. Android定制ListView的界面(使用继承自Arr
  9. ADB命令大全之二
  10. Android 安全加密:数字签名和数字证书详解