C语言回调java代码

本文详细介绍了如何在Android NDK环境中,从C代码调用Java方法,包括调用空方法、带参数的方法以及传入String参数的方法。步骤包括创建本地方法、生成头文件、编写C代码、配置.mk文件、交叉编译及在Java层调用。通过示例代码展示了具体的实现过程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

说明:

在实际开发中,调用的本地方法不一定会在当前的类中,以此种形式,示例如下:

创建工程,指定布局文件(3个点击按钮),对应3个方法:

        一、c调用java空方法

        二、c调用java中带有两个int参数的方法

        三、c调用java中参数为String的方法

1、创建调用的方法

        在其他类中创建3个调用的方法【helloFromJava(); Add();printString()】

2、创建3个本地方法

        在其他类中创建本地方法:

        如在DataProvider类中:

        //本地方法

        public native void nativeCallback1();

        public native void nativeCallback2();

        public native void nativeCallback3();

3、生成头文件

        ①cd到当前工程文件src的目录中

        ②使用javah编译为.h文件,会在src目录下生成.h文件

        ③将.h文件拷贝到jni目录下,在jni中创建对应的.c文件

4、配置.mk文件

        ①Android.mk:

        LOCAL_PATH := $(call my-dir)

        include $(CLEAR_VARS)

        LOCAL_MODULE := Hello #在静态代码块加载数据链接库时的参数

        LOCAL_SRC_FILES := com_itheima20_ndk4_DataProvider.c

        LOCAL_LDLIBS += -llog

        include $(BUILD_SHARED_LIBRARY)

        ②Application.mk:

        APP_ABI := x86

5、加载数据链接库

        static{

        //加载链接库

        System.loadLibrary("Hello");

        }

6、写c代码,分别调用三个方法:

一)、调用空方法:

        1)、指定方法所在类的类名

        由于给linux系统查找的,是需要将点改为斜杠

        如:char* classname = "com/itheima/callback/DataProvider";

        2)、找到指定方法所在类

        //使用jclass (*FindClass)(JNIEnv* env, const char*)

        3)、在指定的类中找指定的方法

        使用jmethodID (*GetMethodID)(JNIEnv*, jclass, const char*, const char*);

        参数1:JNIEnv:jni上下文对象

        参数2:jclass:指定在哪个类中查找方法

        参数3:const char*:指定查找的方法名称

        参数4:const char*:方法签名

        返回值:imethodID:查询到的方法ID

        4)、执行方法

        使用方法:void (*CallVoidMthod)(JNIEnv*, jobject, jmethodID...)

        参数2:jobject:调用方法的java对象

        参数3:jmethodID:要执行的方法

        参数4:…..可变参数,根据V前括号中是否传递参数指定

Tips:

        其中的obj代表dataProvider对象,即调用本地方法的对象

        代码:

        //调用空方法

        JNIEXPORT void JNICALL Java_com_itheima_callback_DataProvider_nativeCallback1

                (JNIEnv * env, jobject obj){

                //1、指定方法所在类的类名

                char* classname = "com/itheima/callback/DataProvider";

                //2、找到指定方法所在类

                //使用jclass (*FindClass)(JNIEnv*, const char*)

                jclass clazz = (**env).FindClass(env, classname);

                //3、在指定的类中,查找指定的方法

                //使用jmethodID (*GetMethodID)(JNIEnv*, jclass, const char*, const char*);

                jmethodID method = (**env).GetMethodID(env, clazz, "helloFromJava", "()V");

                //4、执行方法

                //使用方法:void (*CallVoidMthod)(JNIEnv*, jobject, jmethodID...)

                (**env).CallVoidMethod(env, obj, method);

        }

二)、c调用java中带有两个int参数的方法

        使用的方法:jint (*CallIntMethod)(JNIEnv*, jobject, jmethodID, …)

        JNIEXPORT void JNICALL Java_com_itheima_callback_DataProvider_nativeCallback2

        (JNIEnv * env, jobject obj){

        //1、指定方法所在类的类名

        char* classname = "com/itheima/callback/DataProvider";

        //2、找到指定方法所在类

        //使用jclass (*FindClass)(JNIEnv*, const char*)

        jclass clazz = (**env).FindClass(env, classname);

        //3、在指定的类中,查找指定的方法

        //使用jmethodID (*GetMethodID)(JNIEnv*, jclass, const char*, const char*);

        jmethodID method = (**env).GetMethodID(env, clazz, "add", "(II)I");

        //4、执行方法

        //使用方法:void (*CallVoidMthod)(JNIEnv*, jobject, jmethodID...)

        int result = (**env).CallIntMethod(env, obj, method, 5, 20);

        LOGI("result = %d", result);

        }

三)、c调用java中参数为String的方法

        注意:中文乱码问题

        JNIEXPORT void JNICALL Java_com_itheima_callback_DataProvider_nativeCallback3

        (JNIEnv * env, jobject obj){

        //1、指定方法所在类的类名

        char* classname = "com/itheima/callback/DataProvider";

        //2、找到指定方法所在类

        jclass clazz = (**env).FindClass(env, classname);

        //3、在指定类中,查找指定的方法

        jmethodID method = (**env).GetMethodID(env, clazz, "printString", "(Ljava/lang/String;)V");

        //4、执行方法

        //将java字符串转换为C的字符串

        char* cstr = (**env).NewStringUTF(env, "C调用了java中的方法");

        (**env).CallVoidMethod(env, obj, method, cstr);

        }

7、交叉编译:ndk-build,刷新工程

8、创建提供本地方法的类的对象,调用其中的方法,执行

如:创建DataProvider对象,调用nativeCallback1方法

        @Override

        protected void onCreate(Bundle savedInstanceState) {

                super.onCreate(savedInstanceState);

                setContentView(R.layout.activity_main);

                provider = new DataProvider();

        }

        //C调用java空方法

        public void click1(View view){

        provider.nativeCallback1();

        }

        //C调用java中的带两个int参数的方法

        public void click2(View view){

        provider.nativeCallback2();

        }

        //C调用java中参数为string的方法

                public void click3(View view){

                provider.nativeCallback3();

        }

 

### 学习 C语言Java 的资料与对比 #### 资料推荐 对于初学者来说,无论是学习 C 语言还是 Java 都有许多优秀的资源可供选择。以下是针对两种语言的一些经典书籍和在线课程: 1. **C语言** - 经典教材《The C Programming Language》由 Brian W. Kernighan 和 Dennis M. Ritchie 编写,这本书被广泛认为是学习 C 语言的最佳起点[^1]。 - 在线平台如 Codecademy 提供交互式的 C 语言教程,适合希望快速上手实践的开发者。 2. **Java** - 推荐入门书目《Head First Java》,它以生动的方式讲解复杂的概念,非常适合新手理解抽象的知识点[^3]。 - Oracle 官方文档提供了详尽的技术指南和技术支持,这对于深入研究 Java 是不可或缺的参考资料[^2]。 #### 数据类型的差异 在数据类型方面,两者存在显著区别: - **C语言** 支持指针操作并允许定义自定义数据类型(如 `struct`),这使得内存管理更加灵活但也更复杂。 - **Java** 自动处理垃圾回收机制,并且所有的变量都属于某种类的对象实例;此外,Java 不提供显式指针的支持来增强安全性[^5]。 #### 输入输出方式的不同 关于程序中的基本 I/O 功能也有各自的特点: - 使用标准库函数完成文件读写的任务,在 C 中通常涉及 fopen() 系列方法调用; - 相较之下,Java IO 流框架更为强大且易于扩展,能够轻松应对网络通信等场景下的需求。 #### 运算符特性分析 尽管大部分常见运算符形式相同,但在某些细节之处仍需留意其行为上的变化: - 对于逻辑运算符 && (AND) 及 ||(OR),这两种语言均采用了“短路求值”的策略——即当左子句已经足以决定整个布尔表达式的最终结果时,则不会再去评估右子句的内容][^[^45]。 ```python # Python 示例展示短路效果 def test_short_circuit(): a = False and expensive_computation() # 此处不会执行expensive_computation() b = True or another_expensive_call() # 同样此处也不会触发another_expensive_call() test_short_circuit() ``` #### 总结 总体而言,虽然二者同属高级编程领域内的佼佼者,但由于设计理念上的侧重点各异,导致它们适用于不同的应用场景之中。掌握任何一种都将极大地促进对另一门的理解进程,因为许多核心理念是可以相互迁移应用的^。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

休以希

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值