android jni C++ java 相互调用

来源:互联网 发布:清北学霸 知乎 编辑:程序博客网 时间:2024/05/19 02:24

android jni  C++ java 相互调用

最近回顾下android jni相关接口使用,现在总结一下相关接口,希望对初学者有所帮助。

1. jni 层数据 与java层的数据结构对应关系

     这个表的对应关系一定要对住,否则会出现一些莫名其秒的错误。

2. jni层 的 方法对应的 关系

基本有两种方式对应,第一种是给予javah 后边跟一些参数,把java包里的接口生成一些头文件然后在去编写代码。
第二种通过映射的方式去书写接口,我比较喜欢第二种方式,本文着重讲解第二种情况。
首先构造 java接口
public class Tool {    Bitmap mSrcBitmap = null;    private long add(long a, long b)    {        return a + b;    }    private  long CreatBitmap(int width, int height, int data[]){        if (width < 0  || height < 0 || data == null)            return -1;        mSrcBitmap = Bitmap.createBitmap(data, width, height, Bitmap.Config.ARGB_8888);        if (mSrcBitmap == null)            return -1;        return 0;    }    public native long nativeAdd(long a, long b);    public native void nativeTest( );    public native long nativeCreatBitmap(int width, int height, int[]data);    // 加载 JNI 库文件;    static {        System.loadLibrary("tool");    }}

然后处理jni 处理对应的接口
1)构造映射数组
JNINativeMethod gMethods[] = {{ "native_add", "(JJ)J;", (void*)jni_add },//绑定{ "nativeTest", "()V", (void*)Java_util_Tool_nativeTest },//绑定{ "nativeAdd", "(JJ)J", (void*)jni_add },{ "nativeCreatBitmap", "(II[I)J", (void*)jni_CreateBitmap },};
2) 书写上边对应的方法
JNIEXPORT jlong JNICALL jni_add(JNIEnv *env, jobject cls, jlong a, jlong b){jclass clazz = env->FindClass((char *)JNIREG_CLASS);jmethodID add = env->GetMethodID(clazz, "add", "(JJ)J");return  env->CallLongMethod(cls, add, a, b);}JNIEXPORT jlong JNICALL jni_CreateBitmap(JNIEnv *env, jobject cls,int width, int height, jintArray data){    jclass clazz = env->FindClass((char *)JNIREG_CLASS);    jmethodID CreateBitmap = env->GetMethodID(clazz, "CreatBitmap", "(II[I)J");    //申明一个object数组    jintArray array = 0;    int *pData = (int *)malloc(width * height * sizeof(int));     //新建object数组    array = (env)->NewIntArray(width * height);    pData[0] = 1;    pData[1] = 2;    pData[2] = 3;    env->SetIntArrayRegion(array, 0, width * height, pData);    return env->CallLongMethod(cls, CreateBitmap, width, height, array);}JNIEXPORT void JNICALL Java_util_Tool_nativeTest(JNIEnv *env, jobject clazz){    jclass Bitmap = env->FindClass("android.graphic.Bitmap");return;}
3) 加载jni接口
/** Register several native methods for one class.*/jint Register_JNI(JNIEnv * env, char* className, JNINativeMethod* methods, jint methodsCnt){    jclass clazz = env->FindClass(className);    if (clazz == NULL)    {    return -1;    }    jint res = env->RegisterNatives(clazz, methods, methodsCnt);    if (res < 0)    {    env->DeleteLocalRef(clazz);    return -1;    }    env->DeleteLocalRef(clazz);    return 0;}/** Set some test stuff up.** Returns the JNI version on success, -1 on failure.*/JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM* vm, void* reserved){JNIEnv* env = NULL;jint result = -1;if (vm->GetEnv( (void**) &env, JNI_VERSION_1_6) != JNI_OK) {return -1;}assert(env != NULL);if (Register_JNI(env, JNIREG_CLASS, gMethods,                                  sizeof(gMethods) / sizeof(gMethods[0])))return JNI_FALSE;/* success -- return valid version number */result = JNI_VERSION_1_6;return result;}

4) 释放接口
jint Unregister_JNI(JNIEnv* env, char* className){    jclass clazz = env->FindClass(className);    if (NULL == clazz)    {    return JNI_ERR;    }    env->UnregisterNatives(clazz);    env->DeleteLocalRef(clazz);    return JNI_OK;}JNIEXPORT  void JNICALL JNI_OnUnload(JavaVM *vm, void *reserved){    JNIEnv* env = NULL;    if (vm->GetEnv((void**)&env, JNI_VERSION_1_6) != JNI_OK)    {    return;    }    Unregister_JNI(env, JNIREG_CLASS);}
这样就完成上边java与jni对应关系。另外分享几个其他博客对这方面介绍也挺好的。
讲解c++ 数据结构与 java数据结构关系
http://www.cnblogs.com/daniel-shen/archive/2006/10/16/530587.html
http://zhiweiofli.iteye.com/blog/1830321
jni接口中文解释
http://www.ceeger.com/Script/AndroidJNI/AndroidJNI.CallLongMethod.html
源代码:http://download.csdn.net/download/c553110519/10049211
原创粉丝点击