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 问题

posted @   lesten  阅读(285)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现
点击右上角即可分享
微信分享提示