NDK开发之调用方法

NDK开发之访问域中介绍的一样,Java中的方法也是分为两类:实例方法和静态方法。JNI提供了访问两类方法的函数,下面我们一起来看看怎么在C中访问Java中的方法。

我们的MainActivity中有两个方法,分别是:

    private String instanceMethod(){
        return "Instance Method";
    }
    private static String staticMethod(){
        return "static Method";
    }

那么我们该怎么在C中访问这两个方法呢?

步骤和访问域是一样的:



1.通过对象引用获得类

2.通过类获得方法ID

3.通过方法ID调用方法



下面按步骤来

1.通过对象引用获得类

clazz = (*env)->GetObjectClass(env, thiz);


2.通过类获得方法ID

JNI提供了用方法ID访问两类方法的途径,可以用给定实例的class对象获得方法ID,用GetMethodID函数获得实例方法的方法ID。与字段ID获取方法一样,两个函数的最后一个参数均表示方法描述符,在Java中它们表示方法签名。(为了提高应用性能,我们可以缓存方法ID)

instanceMethodID = (*env)->GetMethodID(env, clazz, "instanceMethod",
            "()Ljava/lang/String;");
    staticMethodID = (*env)->GetStaticMethodID(env, clazz, "staticMethod",
            "()Ljava/lang/String;");


3.通过方法ID调用方法

instanceMethodResult = (*env)->CallObjectMethod(env,thiz,instanceMethodID);
    staticMethodResult = (*env)->CallStaticObjectMethod(env,clazz,staticMethodID);


为了查看是否调用成功,我们需要把调用结果打印出来:

    const jbyte* str1;
    const jbyte* str2;
    str1 = (*env)->GetStringUTFChars(env, instanceMethodResult, 0);
    str2 = (*env)->GetStringUTFChars(env, staticMethodResult, 0);
    LOGI("the string is :%s", str1);
    LOGI("the string is :%s", str2);

完整代码是这样的:

void Java_com_example_jni_MainActivity_getMethod(JNIEnv* env, jobject thiz) {
    jclass clazz;
    jmethodID instanceMethodID;
    jmethodID staticMethodID;
    jstring instanceMethodResult;
    jstring staticMethodResult;
    clazz = (*env)->GetObjectClass(env, thiz);
//  clazz = (*env)->FindClass(env,"com/example/jni/JavaClass");
    instanceMethodID = (*env)->GetMethodID(env, clazz, "instanceMethod",
            "()Ljava/lang/String;");
    staticMethodID = (*env)->GetStaticMethodID(env, clazz, "staticMethod",
            "()Ljava/lang/String;");
    instanceMethodResult = (*env)->CallObjectMethod(env,thiz,instanceMethodID);
    staticMethodResult = (*env)->CallStaticObjectMethod(env,clazz,staticMethodID);
    //jstring转为C字符串然后打印出来
    const jbyte* str1;
    const jbyte* str2;
    str1 = (*env)->GetStringUTFChars(env, instanceMethodResult, 0);
    str2 = (*env)->GetStringUTFChars(env, staticMethodResult, 0);
    LOGI("the string is :%s", str1);
    LOGI("the string is :%s", str2);
}


打印结果:

Java和C之间的转换时代价较大的操作,在实际开发中我们应该尽量避免这种情况的出现。

版权声明:本文为博主原创文章,未经博主允许不得转载。若有错误地方,还望批评指正,不胜感激。

时间: 2024-08-01 08:05:08

NDK开发之调用方法的相关文章

Android NDK开发及调用标准linux动态库.so文件

源:Android NDK开发及调用标准linux动态库.so文件 预备知识及环境搭建 1.NDK(native development Kit)原生开发工具包,用来快速开发C.C++动态库,并能自动将so文件和java应用一起打包成apk.对应:jni层c++开发 2.Cygwin:是windows平台上模拟Linux运行环境的工具,即window平台上的linux环境工具,so文件需要在linux平台上编译运行.对应:arm linux平台 3.CDT:eclipse下的C/C++开发工具,

Android Studio NDK开发-JNI调用Java方法

相对于NDK来说SDK里面有更多API可以调用,有时候我们在做NDK开发的时候,需要在JNI直接Java中的方法和变量,比如callback,系统信息等.... 如何在JNI中调用Java方法呢?就需要先了解FindClass和GetMethodID了. FindClass和GetMethodID 在JNI中可以通过FindClass可以找到Java类,得到jclass,例如: jclass clz=(*env)->FindClass(env,"com/jjz/JniHandle"

JNI/NDK开发指南(八)——调用构造方法和父类实例方法

转载请注明出处:http://blog.csdn.net/xyang81/article/details/44002089 在第6章我们学习到了在Native层如何调用Java静态方法和实例方法,其中调用实例方法的示例代码中也提到了调用构造函数来实始化一个对象,但没有详细介绍,一带而过了.还没有阅读过的同学请移步<JNI/NDK开发指南(六)--C/C++访问Java实例方法和静态方法>阅读.这章详细来介绍下初始一个对象的两种方式,以及如何调用子类对象重写的父类实例方法. 我们先回过一下,在J

NDK开发中出现各种Semantic Error“XXX &#39;xxx&#39; could not be resolved”的解决方法

项目要求NDK开发App程序,于是import了工程项目,搭好了环境,结果出现各种 Type 'xxx' could not be resolved Method 'xxx' could not be resolved 等等Semantic Error.但是工程本身并不存在错误,可以成功编译. 解决方法:明显是没有包含各种头文件造成的,<jni.h>这些头文件包含进工程即可. 右键工程->Properties->C/C++ General->Paths and Symbols

原 .NET/C# 反射的的性能数据,以及高性能开发建议(反射获取 Attribute 和反射调用方法)

大家都说反射耗性能,但是到底有多耗性能,哪些反射方法更耗性能:这些问题却没有统一的描述. 本文将用数据说明反射各个方法和替代方法的性能差异,并提供一些反射代码的编写建议.为了解决反射的性能问题,你可以遵循本文采用的各种方案. 本文内容 反射各方法的性能数据 反射的高性能开发建议 创建类型的实例 反射获取 Attribute 反射调用公共 / 私有方法 使用预编译框架 附本文性能测试所用的代码 所有反射相关方法 IsDefined 和 GetCustomAttribute 的专项比较 参考资料 反

自学ios开发-------Objective-c动态调用方法笔记

OC动态调用OC的函数调用是消息发送模式,即在运行时动态调用函数,OC在编译期可以调用任何函数,只要声明过这个函数,就不会报错,在真正运行的时候才会根据函数的名称找到对应的函数来调用[ASPerson SayHello] 编译时RunTime会将上述代码转化为objc_msgSend(ASPerson @selector(SayHello)) 所有定义的类型都继承自NSObject,NSObject中存在一个指向Class的指针 Class是指向objc_class结构的函数指针; struct

NDK开发,如何配置 debug环境

刚开始做NDK 开发的时候,Android Studio 还没提供了 native C/C++ 设置断点 调试,我们都是通过输出 日志来调试,这样费时耗力.Android Studio 应该是在 2.2 版本才提供的设置断点 debug 功能,同时在该版本也提供了 cmake 编译.     我目前在做 NDK 开发的时候,还是习惯用 NDK-Build(也就是设置 Android.mk) 来开发,我先简单说一下怎么用输出日志来调试: 1.首先在 Android.mk 设置MODULE 添加日志

android studio NDK 开发初探

android studio NDK 开发初探 环境配置 1)下载ndk 2)在android studio中配置ndk 路径 3)配置gradle 在gradle.properties中加入 android.useDeprecatedNdk=true配置 开启ndk 在开发过程中我们有时还会用到c++中到stl库这时我们就需要在build.gradle 中加入 defaultConfig { ndk { moduleName "jnitest" stl "stlport_s

Android NDK开发篇(五):Java与原生代码通信(数据操作)

尽管说使用NDK能够提高Android程序的运行效率,可是调用起来还是略微有点麻烦.NDK能够直接使用Java的原生数据类型,而引用类型,由于Java的引用类型的实如今NDK被屏蔽了,所以在NDK使用Java的引用类型则要做对应的处理. 一.对引用数据类型的操作 尽管Java的引用类型的实如今NDK被屏蔽了,JNI还是提供了一组API,通过JNIEnv接口指针提供原生方法改动和使用Java的引用类型. 1.字符串操作 JNI把Java的字符串当作引用来处理,在NDK中使用Java的字符串,须要相