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;}