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