说明:
在实际开发中,调用的本地方法不一定会在当前的类中,以此种形式,示例如下:
创建工程,指定布局文件(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();
}
页面更新:2024-05-09
本站资料均由网友自行发布提供,仅用于学习交流。如有版权问题,请与我联系,QQ:4156828
© CopyRight 2008-2024 All Rights Reserved. Powered By bs178.com 闽ICP备11008920号-3
闽公网安备35020302034844号