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

  • 相关阅读:
    SQL 视图 局部变量 全局变量 条件语句 事务 触发器
    asp.net中的cookie
    Ajax 学习笔记
    接口与抽象类
    log4net日志组件
    StringBulider简单用法
    Web.Config文件详解
    性能优化之无阻塞加载脚步方法比较
    vue双向数据绑定原理探究(附demo)
    让你的JS更优雅的小技巧
  • 原文地址:https://www.cnblogs.com/lesten/p/16387869.html
Copyright © 2020-2023  润新知