package com.ndk.cjava.exchange;
import java.io.Serializable;
import android.util.Log;
public class UserEntity implements Serializable {
private static final long serialVersionUID = -8623782232814941002L;
private static final String TAG_NAME = "UserEntity";
private String name;
private String id;
public native UserEntity copyUserEntity();
public native static UserEntity newUserEntity(String id,String name);
public native void update(String id,String name);
public void setName(String name)
{
this.name = name;
}
public String getName()
{
return name;
}
public static String tag()
{
return UserEntity.class.getName();
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
@Override
public String toString() {
return "UserEntity [name=" + name + ", id=" + id + "]";
}
private void throwNewException()
{
throw new NullPointerException("Null Pointer");
}
//对象的引用
public native void referenceUnit();
//本地方法
public native void mainThread();
public native void setJNIEnv();
//由JNI中的线程回调
private static void fromJNI(int i)
{
Log.v("Java------>", ""+i);
}
static{
System.loadLibrary("NDK_Exchange");
}
}
-----实现类-------
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<pthread.h>
#include <android/log.h>
#define LOGI(...) ((void)__android_log_print(ANDROID_LOG_INFO, "native-activity", __VA_ARGS__))
#define LOGW(...) ((void)__android_log_print(ANDROID_LOG_WARN, "native-activity", __VA_ARGS__))
#define LOGE(...) ((void)__android_log_print(ANDROID_LOG_ERROR, "native-activity", __VA_ARGS__))
//全局引用对象
jclass globalJclazz = NULL;
jclass weakclass = NULL;
//线程数
#define NUMTHREADS 5
//全局变量
JavaVM *g_jvm = NULL;
jobject g_obj = NULL;
/*
* Class: com_ndk_cjava_exchange_UserEntity
* Method: copyUserEntity
* Signature: ()Lcom/ndk/cjava/exchange/UserEntity;
*/
JNIEXPORT jobject JNICALL Java_com_ndk_cjava_exchange_UserEntity_copyUserEntity
(JNIEnv *env, jobject thiz)
{
jclass jclazz = env->GetObjectClass(thiz);
jmethodID jConstructor= env->GetMethodID(jclazz,"<init>","()V");
jobject newInstance = env->NewObject(jclazz,jConstructor);
jfieldID nameField = env->GetFieldID(jclazz,"name","Ljava/lang/String;");
jfieldID idField = env->GetFieldID(jclazz,"id","Ljava/lang/String;");
env->SetObjectField(newInstance,nameField,env->GetObjectField(thiz,nameField));
env->SetObjectField(newInstance,idField,env->GetObjectField(thiz,idField));
return newInstance;
}
/*
* Class: com_ndk_cjava_exchange_UserEntity
* Method: newUserEntity
* Signature: (Ljava/lang/String;Ljava/lang/String;)Lcom/ndk/cjava/exchange/UserEntity;
*/
JNIEXPORT jobject JNICALL Java_com_ndk_cjava_exchange_UserEntity_newUserEntity
(JNIEnv * env, jclass clazz, jstring id, jstring name)
{
jmethodID jConstructor= env->GetMethodID(clazz,"<init>","()V");
jobject newInstance = env->NewObject(clazz,jConstructor);
jfieldID nameField = env->GetFieldID(clazz,"name","Ljava/lang/String;");
jfieldID idField = env->GetFieldID(clazz,"id","Ljava/lang/String;");
env->SetObjectField(newInstance,nameField,name);
env->SetObjectField(newInstance,idField,id);
return newInstance;
}
/*
* Class: com_ndk_cjava_exchange_UserEntity
* Method: update
* Signature: (Ljava/lang/String;Ljava/lang/String;)V
*/
JNIEXPORT void JNICALL Java_com_ndk_cjava_exchange_UserEntity_update
(JNIEnv * env, jobject thiz, jstring id, jstring name)
{
jclass jclz = env->GetObjectClass(thiz);
jmethodID setNameMethod = env->GetMethodID(jclz,"setName","(Ljava/lang/String;)V");
jmethodID setIdMethod = env->GetMethodID(jclz,"setId","(Ljava/lang/String;)V");
env->CallVoidMethod(thiz,setNameMethod,name);
env->CallVoidMethod(thiz,setIdMethod,id);
jmethodID getNameMethod = env->GetMethodID(jclz,"getName","()Ljava/lang/String;");
jmethodID getIdMethod = env->GetMethodID(jclz,"getId","()Ljava/lang/String;");
jstring mName = (jstring)(env->CallObjectMethod(thiz,getNameMethod));
jstring mId = (jstring)(env->CallObjectMethod(thiz,getIdMethod));
jmethodID sTagMethod = env->GetStaticMethodID(jclz,"tag","()Ljava/lang/String;");
jstring jtag = (jstring)(env->CallStaticObjectMethod(jclz,sTagMethod));
jboolean isCopy;
const char * chName = env->GetStringUTFChars(mName,&isCopy);
const char * chId = env->GetStringUTFChars(mId,&isCopy);
const char * chTag = env->GetStringUTFChars(jtag,&isCopy);
jfieldID TagNamefiledId = env->GetStaticFieldID(jclz,"TAG_NAME","Ljava/lang/String;");
jstring jtagName = (jstring)(env->GetStaticObjectField(jclz,TagNamefiledId));
const char * chTagName = env->GetStringUTFChars(jtagName,&isCopy);
__android_log_print(ANDROID_LOG_ERROR,chTag,"TAG_NAME=%s,name=%s,id=%s",chTagName,chName,chId);
//异常处理---java代码抛出的异常导致jvm shut down
/**
jmethodID throwNewExceptionMethodID = env->GetMethodID(jclz,"throwNewException","()V");
env->CallCharMethod(thiz,throwNewExceptionMethodID);
jthrowable tr = env->ExceptionOccurred();
if(tr!=NULL)
{
env->ExceptionClear();
}
**/
//主动抛出异常---c抛出的异常程序不会停止
env->ThrowNew(jclz,"主动抛出的异常");
jthrowable tr = env->ExceptionOccurred();
if(tr!=NULL)
{
env->ExceptionClear();
env->DeleteLocalRef(jclz);
}
}
/*
* Class: com_ndk_cjava_exchange_UserEntity
* Method: referenceUnit
* Signature: ()V
*/
JNIEXPORT void JNICALL Java_com_ndk_cjava_exchange_UserEntity_referenceUnit
(JNIEnv * env, jobject thiz)
{
/*if(globalJclazz==NULL)
{
__android_log_print(ANDROID_LOG_INFO,"REF","--1-->");
globalJclazz = (jclass)(env->NewGlobalRef(env->GetObjectClass(thiz)));
}else{
__android_log_print(ANDROID_LOG_INFO,"REF","--2-->");
env->DeleteGlobalRef(globalJclazz);
globalJclazz = NULL;
}*/
//
if(weakclass==NULL || (env->IsSameObject(weakclass,NULL))==JNI_TRUE)
{
jclass jclzz = env->GetObjectClass(thiz);
weakclass = (jclass)(env->NewWeakGlobalRef(jclzz));
}else{
env->DeleteWeakGlobalRef(weakclass);
weakclass = NULL;
}
}
/****---------------------------------------多线程---------------------------------------***/
void *thread_fun(void* arg)
{
JNIEnv * env = NULL;
jclass cls = NULL;
jmethodID mid = NULL;
//Attach主线程
if(g_jvm->AttachCurrentThread( &env, NULL) != JNI_OK)
{
LOGE("%s: AttachCurrentThread() failed", __FUNCTION__);
return NULL;
}
//找到对应的类
cls = env->GetObjectClass(g_obj);
if(cls == NULL)
{
LOGE("FindClass() Error.....");
goto error;
}
//再获得类中的方法
mid = env->GetStaticMethodID( cls, "fromJNI", "(I)V");
if (mid == NULL)
{
LOGE("GetMethodID() Error.....");
goto error;
}
//最后调用java中的静态方法
env->CallStaticVoidMethod( cls, mid ,(int)arg);
error:
//Detach主线程
if(g_jvm->DetachCurrentThread() != JNI_OK)
{
LOGE("%s: DetachCurrentThread() failed", __FUNCTION__);
}
pthread_exit(0);
}
JNIEXPORT void JNICALL Java_com_ndk_cjava_exchange_UserEntity_mainThread
(JNIEnv * env, jobject thiz)
{
int i;
pthread_t pt[NUMTHREADS];
for (i = 0; i < NUMTHREADS; i++)
{ //创建子线程
pthread_create(&pt[i], NULL, &thread_fun, (void *)i);
}
}
JNIEXPORT void JNICALL Java_com_ndk_cjava_exchange_UserEntity_setJNIEnv
(JNIEnv * env, jobject thiz)
{
//保存全局JVM以便在子线程中使用
env->GetJavaVM(&g_jvm);
//不能直接赋值(g_obj = obj)
g_obj = env->NewGlobalRef(thiz);//变为全局变量
}
//当动态库被加载时这个函数被系统调用
JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void *reserved)
{
LOGE("JNI_OnLoad");
JNIEnv* env = NULL;
jint result = -1;
//获取JNI版本
if (vm->GetEnv((void**)&env, JNI_VERSION_1_4) != JNI_OK)
{
LOGE("GetEnv failed!");
return result;
}
return JNI_VERSION_1_4;
}
//当动态库被卸载时这个函数被系统调用
JNIEXPORT void JNICALL JNI_OnUnload(JavaVM* vm, void* reserved)
{
LOGE("JNI_OnUnload");
}