ndk遇到的坑

ndk遇到的坑

ndk遇到的坑

目录

回调jobject时要注意

java->c 的时候传过来的jobject在方法调用完后就会没了

extern "C"
JNIEXPORT jlong JNICALL
Java_com_seekting_ndk2021_Clock_bind(JNIEnv *env, jobject thiz) {

if (!global_env) {
global_env = env;
}

Clock *clock = new Clock((intptr_t) &thiz, &onStateChange, &onClockChanged);//坑!这个对象会失效
LOGE("bind clock= %p,jobject= %p", clock, &thiz);
return (jlong) (clock);
}

如果想全局使用,可以借用NewGlobalRef来引用它

jobjectRef = env->NewGlobalRef(thiz);
env->DeleteGlobalRef(customObj);

异步线程无法使用JNIEnv

当*env传过来的时候,可以调用GetJavaVM把env存到g_jvm

JavaVM *g_jvm = NULL;
jobject g_obj = NULL;
void init(JNIEnv *env){

env->GetJavaVM(&g_jvm);
}

使用时 通过g_jvm->AttachCurrentThread

void onClockChanged(Clock *clock, string str) {
JNIEnv *env;
jclass cls;
jmethodID mid;

//Attach主线程
if(g_jvm->AttachCurrentThread(&env, NULL) != JNI_OK)
{
return;
}

异步线程无法FindClass

需要第一次传evn的时候提前find好,存成全局NewGlobalRef,方法Id也可以保存全局

jobject clockJClass;
jmethodID onStateChangeID;
jmethodID onClockChangedID;
void initClass(JNIEnv *env) {
jclass jclass = env->FindClass("com/seekting/ndk2021/Clock");
if (jclass == NULL) {
LOGE("#######not found class.\n");
return;
}
// 获取getLedId方法
onStateChangeID = env->GetMethodID(jclass, "onStateChange", "(JI)V");
if (onStateChangeID == NULL) {
LOGE("#######not found getLedId func.\n");
return;
}
// 获取getLedId方法
onClockChangedID = env->GetMethodID(jclass, "onClockChanged", "(JLjava/lang/String;)V");
if (onClockChangedID == NULL) {
LOGE("#######not found getLedId func.\n");
return;
}
clockJClass = env->NewGlobalRef(jclass);
}

使用时

void onClockChanged(Clock *clock, string str) {
JNIEnv *env;
//Attach主线程
if (g_jvm->AttachCurrentThread(&env, NULL) != JNI_OK) {
return;
}


jobject *jo = &(clock->object);//全局
long clock_jlong = reinterpret_cast<jlong>(clock);
// LOGE("clock=%p,jobject=%p,onStateChangeID=%p ", clock, jo, onClockChanged);
env->CallVoidMethod(*jo, onClockChangedID, clock_jlong,
env->NewStringUTF(str.c_str()));
}

函数指针实现方法回调

Clock(JNIEnv *env,jobject o, void (*onStateChange)(Clock *, int), void (*onClockChanged)(Clock *, string));
Clock::Clock(JNIEnv *env, jobject object, void(*onStateChange)(Clock *, int),
void(*onClockChanged)(Clock *, string)) {


}

不写方法返回还能编译通过

int test(){
//dosomething

}

以上代码能通过 run 编译通过;但是运行时就会报各种问题,但不会告诉你没有返回,你分析半天才知道没有返回

.c文件无法使用string

建议把文件改成.cpp

上一篇:Windows上右键git菜单出来的原因


下一篇:2021-03-11