/*
* env jni 环境
* thiz activity 的 native 对象
* str 跳转目标 activity 的 全路径 com.xxx.xxx.mainActivity
* // Intent a = new Intent();
* // getClassLoader().loadClass(str);
* // a.setClass(this, MainActivity.class);
* // startActivity(a);
*/
void xxxx(JNIEnv *env, jobject thiz, std::string str){
LOGD("MainActivity xxxx be called!!!!!%s ", str.c_str());
JavaVM *vm = NULL;
bool detatched = false;
int result = env->GetJavaVM(&vm);
if (!result) {
detatched = (vm->GetEnv((void **) &env, JNI_VERSION_1_6) == JNI_EDETACHED);
if (detatched) {
LOGD(" non-cpp thread. jni xxxx AttachCurrentThread ");
vm->AttachCurrentThread(&env, nullptr);
}
LOGD("detatched:%d", detatched);
}
jclass MainActivity = env->GetObjectClass(thiz);
// android.content.Intent
jclass tent_cls = env->FindClass("android/content/Intent");
// new intent
jmethodID tentConstructorMethodId = env->GetMethodID(tent_cls, "<init>", "()V");
jobject tent_ref = env->NewObject(tent_cls, tentConstructorMethodId);
jclass wrapper = env->FindClass("android/content/ContextWrapper");
if (wrapper == NULL) {
return;
}
jmethodID getClassLoader = env->GetMethodID(wrapper, "getClassLoader", "()Ljava/lang/ClassLoader;");
if(getClassLoader == 0)
return;
// 子类对象 调用父类方法
jobject cls = env->CallNonvirtualObjectMethod(thiz, wrapper, getClassLoader);
if(cls == 0)
return;
jclass classLoader = env->FindClass("java/lang/ClassLoader");
if(classLoader == 0)
return;
jmethodID findClass = env->GetMethodID(classLoader, "loadClass", "(Ljava/lang/String;)Ljava/lang/Class;");
if(findClass == 0)
return;
jstring intentString = env->NewStringUTF(str.c_str());
if(intentString == 0)
return;
jclass tact_cls = (jclass)env->CallObjectMethod(cls, findClass, intentString);
if(tact_cls == 0)
return;
jmethodID setcls = env->GetMethodID(tent_cls, "setClass", "(Landroid/content/Context;Ljava/lang/Class;)Landroid/content/Intent;");
env->CallObjectMethod(tent_ref, setcls, thiz, tact_cls);
jclass cls_cxt = env->FindClass("android/content/Context");
jmethodID start = env->GetMethodID(cls_cxt, "startActivity", "(Landroid/content/Intent;)V");
env->CallVoidMethod(thiz, start, tent_ref);
// env->CallNonvirtualVoidMethod(thiz, cls_cxt, start, tent_ref); // 也可以这样
// 检查JNI调用是否有引发异常
if (env->ExceptionCheck()) {
env->ExceptionDescribe();
env->ExceptionClear(); // 清除引发的异常,在Java层不会打印异常的堆栈信息
env->ThrowNew(env->FindClass("java/lang/Exception"),"JNI抛出的异常!");
//return;
}
}
参考:
1、https://blog.csdn.net/TyearLin/article/details/122337919 AttachCurrentThread & DetachCurrentThread
2、https://blog.csdn.net/u010281924/article/details/105858045 JNI native 通过intent启动一个新Activity
3、https://www.jianshu.com/p/942c61b30beb JNI 异常处理
4、https://blog.csdn.net/chenli_001/article/details/76422808 解决 android.content.ActivityNotFoundException: No Activity found to handle Intent 问题