项目中需要,写了一个android NDK c调用java的例子,现将大概步骤说明如下
1. 比如java层com.android.encrypt包下CommonEncrypt类有个方法encryptBASE64,要被c层调用
public static String encryptBASE64(byte[] str) {
try {
return com.android.encrypt.Base64.encode(str, "UTF-8");
} catch (UnsupportedEncodingException e) {
// TODO Auto-generated catch block
return "";
}
}
2. c层相应的代用代码为:
jstring base64_encode(JNIEnv *env,char* sIn) {
jmethodID encryptBASE64 = NULL;
if(env == NULL) {
return 0;
}
jclass CommonEncrypt = NULL;
if(CommonEncrypt == NULL) {
CommonEncrypt = env->FindClass("com/android/encrypt/CommonEncrypt");
if(CommonEncrypt == NULL){
return NULL;
}
}
jobject mCommonEncrypt = NULL;
if (mCommonEncrypt == NULL) {
jmethodID construction_id = env->GetMethodID(CommonEncrypt,
"<init>", "()V");
if (construction_id == 0) {
return NULL;
}
mCommonEncrypt = env->NewObject( CommonEncrypt,
construction_id);
if (mCommonEncrypt == NULL) {
env->DeleteLocalRef(CommonEncrypt);
return NULL;
}
if (encryptBASE64 == NULL) {
encryptBASE64 = env->GetStaticMethodID(CommonEncrypt, "encryptBASE64","([B)Ljava/lang/String;");
if (encryptBASE64 == NULL) {
env->DeleteLocalRef(CommonEncrypt);
env->DeleteLocalRef(mCommonEncrypt);
return NULL;
}
}
}
int srcLen = strlen(sIn);
jbyteArray encArray = env->NewByteArray(srcLen);
env->SetByteArrayRegion(encArray, 0, srcLen, (const jbyte *)sIn);
jstring jstr = NULL;
jstr = (jstring)env->CallStaticObjectMethod(CommonEncrypt, encryptBASE64,encArray);
return jstr;
}
3. 几点说明
1. env->FindClass("com/android/encrypt/CommonEncrypt")方法,是找到java类CommonEncrypt
2. env->GetStaticMethodID(CommonEncrypt, "encryptBASE64","([B)Ljava/lang/String;");找到相应类中的静态方法encryptBASE64,([B)Ljava/lang/String;是返回值和参数
([B):表示函数参数为byte数组,int数组用[I表示,比如方法参数有两个int参数,则输入为(II),
Ljava/lang/String;表示返回值类型
3. env->CallStaticObjectMethod(CommonEncrypt, encryptBASE64,encArray),是函数调用,第一个是类名,第二个是方法名,第三个是方法参数