在Android开发中通过AndroidStudio相关代码提示即可调用C或者C++。但在C或者C++中进行相关调用则相对复杂一些如下面简单的代码
src/main/java/top/foxhome/demo/myapplication/MainActivity.java
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
binding = ActivityMainBinding.inflate(getLayoutInflater());
setContentView(binding.getRoot());
tv = binding.sampleText;
loadDate();
}
/**
* 调用cpp方法。然后cpp再回调java方法
*/
public native void loadDate();
public void onDateCallBack(String date) {
tv.setText(date);
}
src/main/cpp/native-lib.cpp
#include <jni.h>
#include <string>
extern "C"
JNIEXPORT void JNICALL
Java_top_foxhome_demo_myapplication_MainActivity_loadDate(JNIEnv *env, jobject thiz) {
char *dates = "hello,word mmm";
// 反射得到Class类型
jclass mJclass = env->GetObjectClass(thiz);
jmethodID methodID = env->GetMethodID(mJclass, "onDateCallBack",
"(Ljava/lang/String;)V");
jstring mData = env->NewStringUTF(dates);
env->CallVoidMethod(thiz, methodID, mData);
}
其中调用逻辑如下:
因此我们可以得知大致流程如下:
获取jclass
也可通过以下方式实现:
jclass c = (*env)->FindClass(env,"com/xxx/xxx/类名");
获取static java方法
jmethodID methodID = env->GetStaticMethodID(mJclass, "方法名称","函数签名")
实例化对象,如实例化一个String
jclass mStringClass = env->FindClass("java/lang/String");
jmethodID mStringNewObjectMethod = env->GetMethodID(mStringClass, "<init>","(Ljava/lang/String;)V");
jstring mJstring = env->NewStringUTF("hello,foxhome!");
jobject mStringObj= env->NewObject(mStringClass,mStringNewObjectMethod,mJstring);
注意Java的函数签名可以通过Android studio的智能提示进行自动填写。也可生成class文件后执行javap -p -s XXX.class
获取。