NDK中编写C++线程

这篇博客探讨了如何在Android的NDK环境中使用C++编写线程。首先,介绍了在JNI中创建线程的方法,并引用了一个教程作为参考。接着,提到了Android 4.0及以上版本中垃圾收集器的变化,这些变化可能在C++线程编程时带来问题,作者引用了官方博客文章来说明这个问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.在Jni中写线程:

参考:http://android.wooyd.org/JNIExample/#NWD1sCYeT-C

#include <jni.h>
#include <string.h>
#include <stdio.h>
#include <android/log.h>
#include <linux/threads.h>
#include <pthread.h>

#define  LOG_TAG    "[NDK]"
#define  LOGI(...)  __android_log_print(ANDROID_LOG_INFO,LOG_TAG,__VA_ARGS__)
#define  LOGW(...)  __android_log_print(ANDROID_LOG_WARN,LOG_TAG,__VA_ARGS__)
#define  LOGE(...)  __android_log_print(ANDROID_LOG_ERROR,LOG_TAG,__VA_ARGS__)

static pthread_mutex_t thread_mutex;
static pthread_t thread;
static JNIEnv* jniENV;

void *threadLoop()
{
    int exiting;
    JavaVM* jvm;
    int gotVM = (*jniENV)->GetJavaVM(jniENV,&jvm);
    LOGI("Got JVM: %s", (gotVM ? "false" : "true") );
    jclass javaClass;
    jmethodID javaMethodId;
    int attached = (*jvm)->AttachCurrentThread(jvm, &jniENV,NULL);
    if(attached>0)
    {
        LOGE("Failed to attach thread to JavaVM");
        exiting = 1;
    }
    else{
        javaClass= (*jniENV)->FindClass(jniENV, "com/justinbuser/nativecore/NativeThread");
        javaMethodId= (*jniENV)->GetStaticMethodID(jniENV, javaClass, "javaMethodName", "()V");
    }
    while(!exiting)
    {
        pthread_mutex_lock(&thread_mutex);
        (*jniENV)->CallStaticVoidMethod(jniENV, javaClass, javaMethodId);
        pthread_mutex_unlock(&thread_mutex);
    }
    LOGE("Thread Loop Exiting");
    void* retval;
    pthread_exit(retval);
    return retval;
}

void start_thread(){
    if(thread < 1)
        {
            if(pthread_mutex_init(&thread_mutex, NULL) != 0)
            {
                LOGE( "Error initing mutex" );
            }
            if(pthread_create(&thread, NULL, threadLoop, NULL) == 0)
            {
                LOGI( "Started thread#: %d", thread);
                if(pthread_detach(thread)!=0)
                {
                    LOGE( "Error detaching thread" );
                }
            }
            else
            {
                LOGE( "Error starting thread" );
            }
        }
}

JNIEXPORT void JNICALL
Java_com_justinbuser_nativecore_NativeMethods_startThread(JNIEnv * env, jobject this){
    jniENV = env;
    start_thread();
}


2.由于Android 4.0的垃圾收集器被改变。现在,它移动的垃圾收集过程中周围的物体,这可能会导致很多问题。

参考:http://android-developers.blogspot.cz/2011/11/jni-local-reference-changes-in-ics.html

出现如下错误:

 E/dalvikvm(30944): JNI ERROR (app bug): accessed stale local reference 0xbc00021 (index 8 in a table of size 8)
 E/dalvikvm(30944): VM aborting
 A/libc(30944): Fatal signal 11 (SIGSEGV) at 0xdeadd00d (code=1), thread 30944 
解决方法:

//错误代码
static jclass myClass;
JNIEXPORT jint JNICALL JNI_OnLoad (JavaVM* vm,void* reserved){  
    myClass = env->FindClass("com/example/company/MyClass");return JNI_VERSION_1_6;}

//正确代码
static jclass myClass;
JNIEXPORT jint JNICALL JNI_OnLoad (JavaVM* vm,void* reserved){  
    jclass tmp = env->FindClass("com/example/company/MyClass");  
    myClass =(jclass)env->NewGlobalRef(tmp);return JNI_VERSION_1_6;}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值