JNI介绍(二)

前面一篇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

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值