android JNI NDK

1:java 是如何和C /C++完成调用的

 通过  在java 层 定义 native 方法,然后在 用C 或者C++ 实现,打包成.so 文件 在java层调用

  示例:

 // 测试JAVA的NDK调用
    public native String  stringFromJNI();
   
    // 测试C/C++中对JAVA函数的静态回调
    public native static int jniStaticShowMessage(Context ctx, String strTitle, String strMessage);
   
    // 测试实例中C/C++中对JAVA类的函数的调用
    public native int jniShowMessage(Context ctx, String strTitle, String strMessage);
   
    // 测试创建新实例C/C++对JAVA类的函数的调用
    public native int jniInstanceShowMessage(Context ctx, String strTitle, String strMessage);
   
    static {
        System.loadLibrary("demo-jni");
    }
   

 这是方法定义:

-

 这个是用C 来实现的

#include <string.h>
#include <jni.h>

// 加载此动态库时系统自动首先加载
jint JNI_OnLoad(JavaVM* vm, void *reserved)
{
 JNIEnv *env;
 if((*vm)->GetEnv(vm, (void**)&env, JNI_VERSION_1_4) != JNI_OK)
 {
  return -1;
 }

 return JNI_VERSION_1_4;
}

jstring
Java_study_jnidemo_JniDemoActivity_stringFromJNI( JNIEnv* env,jobject thiz )
{
    return (*env)->NewStringUTF(env, "JniDemo, Hello from zhangggai ");
}

jstring
combine_jstring(JNIEnv* env, jstring str1, jstring str2)
{
 jboolean b_ret;
 const char *s1 = (*env)->GetStringUTFChars(env, str1, &b_ret);
 const char *s2 = (*env)->GetStringUTFChars(env, str2, &b_ret);
 int n1 = strlen(s1);
 int n2 = strlen(s2);
 char *new_str = (char *)malloc(n1+n2+1);
 memset(new_str, 0, n1+n2+1);
 strcat(new_str, s1);
 strcat(new_str, s2);
 jstring ret_str = (*env)->NewStringUTF(env,(const char *)new_str);
 free(new_str);

 return ret_str;
}

jint
Java_study_jnidemo_JniDemoActivity_jniStaticShowMessage(JNIEnv* env, jobject thiz,
  jobject ctx, jstring strTitle, jstring strMessage)
{
 jclass cls = (*env)->FindClass(env, "study/jnidemo/JniDemoActivity");
 if(cls != NULL)
 {
  jmethodID id = (*env)->GetStaticMethodID(env, cls,
    "staticShowMessage",
    "(Landroid/content/Context;Ljava/lang/String;Ljava/lang/String;)I");
  if(id != NULL)
  {
   return (*env)->CallStaticIntMethod(env, cls, id, ctx, strTitle, strMessage);
  }
 }

 return 1;
}

// 在当前已有的JAVA实例中调用
jint
Java_study_jnidemo_JniDemoActivity_jniShowMessage(JNIEnv* env, jobject thiz,
  jobject ctx, jstring strTitle, jstring strMessage)
{
 jclass cls = (*env)->GetObjectClass(env, thiz);
 if(cls != NULL)
 {
  jstring str;
  jmethodID strTest_id = (*env)->GetMethodID(env, cls, "getTestString",
    "()Ljava/lang/String;");
  if(strTest_id != NULL)
  {
   str = (*env)->CallObjectMethod(env, thiz, strTest_id);
  }

  jmethodID showMessage_id = (*env)->GetMethodID(env, cls, "showMessage",
    "(Landroid/content/Context;Ljava/lang/String;Ljava/lang/String;)I");

  if(showMessage_id != NULL)
  {
   return (*env)->CallIntMethod(env, thiz, showMessage_id, ctx,
     strTitle, combine_jstring(env, strMessage, str));
  }
 }
 return 1;
}

// 在新建JAVA实例中调用
jint
Java_study_jnidemo_JniDemoActivity_jniInstanceShowMessage(JNIEnv* env, jobject thiz,
  jobject ctx, jstring strTitle, jstring strMessage)
{
 jclass cls = (*env)->FindClass(env, "study/jnidemo/JniDemoActivity");
 if(cls != NULL)
 {
  // get instance
  jmethodID constuctor_id = (*env)->GetMethodID(env, cls, "<init>", "()V");
  if(constuctor_id != NULL)
  {
   jobject obj = (*env)->NewObject(env, cls, constuctor_id);
   if(obj != NULL)
   {
    jstring str;
    jmethodID strTest_id = (*env)->GetMethodID(env, cls, "getTestString",
      "()Ljava/lang/String;");

    if(strTest_id != NULL)
    {
     str = (*env)->CallObjectMethod(env, obj, strTest_id);
    }

    jmethodID showMessage_id = (*env)->GetMethodID(env, cls, "showMessage",
      "(Landroid/content/Context;Ljava/lang/String;Ljava/lang/String;)I");

    if(showMessage_id != NULL)
    {
     return (*env)->CallIntMethod(env, obj, showMessage_id, ctx,
       strTitle, combine_jstring(env, strMessage, str));
    }
   }
  }
 }

 return 1;
}

 

你可能感兴趣的:(android,jni,NDK)