JNI native 启动 Activity
/*
* 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 问题
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现