前面一篇JNI介绍(一)主要介绍如何用Android studio进行JNI的开发,但是并对于为什么要这么写,没有任何的说明。接下来的文章将会逐一进行解释。
Java调用C例子:
//
// Created by zuowe on 2019/5/23.
//
#include "cn_zzw_jnidemo1_jni_JniTools.h"
JNIEXPORT jstring JNICALL Java_cn_zzw_jnidemo1_jni_JniTools_getMessage(JNIEnv *env, jobject obj, jstring jname)
{
return (*env)->NewStringUTF(env,"I am from jni libs!");
}
看到这个方法名,觉得也太长了吧~~~~~~~~,其实不用我们自己写,但是具体是按照什么样的方式命名的呢 ?
JNI的方法命名规则:
a.JNIEXPORT和JNICALL都是JNI的关键字,表示此函数是要被JNI调用的.
b.jstring 代表返回值类型。
c.前缀:Java_
d.类的包名+类名,用下划线进行分隔(_):cn_zzw_jnidemo1_jni_JniTools
e.方法名:getMessage
f.JNIEnv类型实际上代表了Java环境,通过这个JNIEnv* 指针,就可以对Java端的代码进行操作
g.jobject obj:如果native方法不是static的话,这个obj就代表这个native方法的类实例
如果native方法是static的话,这个obj就代表这个native方法的类的class对象实例(static方法不需要类实例的,所以就代表这个类的class对象)。
1.JNI数据类型
1.1 基本数据类型
1.2 引用数据类型
2. JNI方法
2.1 NewStringUTF
Description描述
Constructs a new java.lang.String object from an array of characters in modified UTF-8 encoding.
利用 UTF-8 字符数组构造新的 java.lang.String 对象。
C风格:(*env)->NewStringUTF(env, "Hellow World!");
C++风格:env->NewStringUTF("Hellow World!");
3. C调用Java的代码:
#include "cn_zzw_jnidemo1_jni_ToastTools.h"
JNIEXPORT void JNICALL Java_cn_zzw_jnidemo1_jni_ToastTools_callToastShow
(JNIEnv *env, jobject obj, jstring jmsg)
{
jclass clazz = (*env)->FindClass(env,"cn/zzw/jnidemo1/jni/ToastTools");
jmethodID mid = (*env)->GetMethodID(env,clazz,"show","(Ljava/lang/String;)V");
(*env)->CallVoidMethod(env, obj,mid,jmsg);
}
流程为:获取Java类,从类中再获取方法ID,最后调用方法。
3.1 FindClass 查找类
static function FindClass (name : string)
Description描述
This function loads a locally-defined class.
这个函数加载一个本地定义的类。
其中class name为包名+类名,“.”替换为“/”。
3.2 GetMethodID 获取方法ID
static function GetMethodID (clazz : IntPtr, name : string, sig : string)
Description描述
Returns the method ID for an instance (nonstatic) method of a class or interface.
返回类或接口实例(非静态)方法的方法 ID。方法可在某个 clazz 的超类中定义,也可从 clazz 继承。该方法由其名称和签名决定。GetMethodID() 可使未初始化的类初始化。
GetMethodID(env,clazz,"show","(Ljava/lang/String;)V")
此段代码的"show"方法和后面的"(Ljava/lang/String;)V" 采用下面的方式获取:
D:\AndroidProject\201905\JniDemo1\app\build\intermediates\javac\debug\compileDebugJavaWithJavac\classes>javap -s cn.zzw.jnidemo1.jni.ToastTools
Compiled from "ToastTools.java"
public class cn.zzw.jnidemo1.jni.ToastTools {
public cn.zzw.jnidemo1.jni.ToastTools(android.content.Context);
descriptor: (Landroid/content/Context;)V
public void show(java.lang.String);
descriptor: (Ljava/lang/String;)V
public native void callToastShow(java.lang.String);
descriptor: (Ljava/lang/String;)V
static {};
descriptor: ()V
}
3.3 CallVoidMethod 调用无类型方法
Description描述
Calls an instance (nonstatic) Java method defined by methodID, optionally passing an array of arguments (args) to the method.
调用一个由methodID定义的实例的Java方法,可选择传递参数(args)的数组到这个方法。
更多方法可以参考下这些文章:
https://blog.csdn.net/x284285624/article/details/44753713
https://blog.csdn.net/afei__/article/details/81016413