首页 > 编程知识 正文

android组件化面试,安卓native层

时间:2023-05-04 20:20:40 阅读:137431 作者:2480

前言:在跨平台开发过程中,通常会在平面层/C之间创建native线程。 如果创建的native线程执行的代码在Java层接口中调用,则转到AttachCurrentThread。 native线程终止时需要调整DetachCurrentThread否方遇到JNI经典崩溃问题— Native thread exited without calling DetachCurrentThread,如果Deatch的处理逻辑写得不好,则JNI崩溃(在这种情况下,java的线程发生了错误的检测! )

解决方案1 .每个线程缓存自己的Env每个线程缓存自己的Env是指从线程的最初attach到JVM时缓存Env实例,在等待线程结束/废弃的过程中进行deattach操作实例功能必须依赖于三个接口和一个线程来存储变量/TSD(pthread_key_t变量) : 变量名称是全局变量,但每个线程都有自己的内存空间。)

创建//key实例并绑定释放key实例时的回调函数。 也就是说,线程结束后所有的key都会被清理,同时调用绑定在key实例上的回调函数! (请特别注意这个回调函数。 稍后再用。 (intPthread_key_create ) Pthread_key_t*key,void* ) destructor ) void* ) )。 保存与//key实例对应的值,并使用hashmap int pthread _ set specific (pthread _ key _ tkey,const void *value ); 获得与//key相对应的值void * pthread _ get specific (pthread _ key _ tkey ); 可以参考cocos2d的jni的功能系cocos2d JinHelper和webtrc的jvm.cc,抄写,带来主义。 JinHelper缓存env的重要实现是getEnv中的cacheEnv函数

JNI env * JNI helper :3360 getenv () /线程存储cache到jnienv*_env=(jnienv* ) pthread_getspecific ) g_key ) if(env==nullptr ) env=JNI helper 3360: cache env (PS javavm ); return _env; } JNI env * JNI helper 33603360 cache env (javavm * JVM ) { JNIEnv* _env=nullptr; //getjnienvironmentjintret=JVM-getenv ((void * * ) _env,JNI_VERSION_1_4); switch(ret ) { case JNI_OK : //Success! 另外,已经进行了attch,并存在于线程存储器中(在本例中为调用java并回调至java层时) (pthread_setspecific ) g_key,_env ); return _env; 对于case JNI _ edetached ://threadnotattached、detached,将另一个if (JVM-attachcurrentthread (_ env,nullptr ) 0附加为attach } else {//success 3360 attachedandobtainedjnienv! thread_setspecific(g_key,_env ); return _env; } case JNI _ e version ://cannotrecoverfromthiserrorloge (jniinterfaceversion 1.4 not supported ); 默认: loge (' failedtogettheenvironmentusinggetenv () ); return nullptr; } voidjnihelper 33603360 set javavm (javavm * javavm ) pthread _ tthis thread=pthread _ self ); //logd (JNI helper 33603360 set JavaVM (% p ),pthread_self )=%ld ',javavm,thisthread ); _psJavaVM=javaVM; 通过绑定回收//key时的回调函数_detachCurrentThread (如何将DetachCurrentThread放入其中),线程结束时的detachjvmpthread _ key _ key 可以实现_ deeathread } void _ detachcurrentthread (void * a ) cocos2d : JNI helper 33603360 get javavm (-detachcurrent }2.一次性Env一次性Env是指从attch向JVM获取Env,每次使用Env时对JVM进行attch。 维持attch和eattch的配对! 这个方法有点简单,但有点暴力! (可能有性能问题)

示例代码如下所示

JNIEnv* env=nullptr; intresult=g_JVM-getenv((void** ) env,JNI_VERSION_1_6); bool shouldDetach=false; result==JNI _ edetached ) jintattachresult=JVM-attachcurrentthread (jenv,NULL ); 附加结果=0(if ) shouldDetach=true; }//使用env、调整java的接口连接. if(shoulddetach ) { g_jvm-DetachCurrentThread ); } env=nullptr; 参考资料JNI多线程调用的主要汇总线程特定数据(Thread Specific Data ) pthread_key_t和pthread_key_create ) coco S2 dandroidjniwebrtcorte

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。