我目前正在使用android studio开发Android应用程序,对于这个项目,我需要使用用c / c ++编写的自定义库。
所以我为了做到这一点,我需要使用NDK。 该库包含我需要实现的方法,以便访问android
中的特定功能我的问题是:如何在c中存在的方法中调用我的jni方法 这将调用java方法在android系统中存储会话密钥
所以对于一个实际的例子,因为它可能不清楚:
在一个名为lib_exemple.c的文件中,我有三种方法
第一个是对库的初始化调用(jni到库c) - >工作
JNIEXPORT void JNICALL
Java_com_example_libExemple_Libs_ExempleLib_lib_1Exemple_1init
(JNIEnv *env, jobject instance) {
lib_Example_init('0'); // c func of the library
}
然后第二个是调用java方法的jni(jni到java) - >工作
JNIEXPORT jint
JNICALL Java_com_example_libExemple_Libs_ExempleLib_lib_1Exemple_1store_1session_1key
(JNIEnv * env, jobject jobject1, jbyte jbyte1, jchar jchar1, jbyte jbyte2){
jclass clazz = (*env)->FindClass(env, "com/example/libExemple/Libs/ExempleLib");
jmethodID mCurrentActivityId = (*env)->GetMethodID(env, clazz, "KeyStoreSessionKey", "(BCB)I");
jint result = (*env)->CallIntMethod(env, jobject1, mCurrentActivityId, jbyte1, jchar1, jbyte2);
return result;
}
,第三种方法是库c中的方法(库C到jni)
int lib_Exemple_store_session_key(uint8_t Session, P_KEY_ST_T pKey, uint8_t keyType) {
//i want to call jni func here , so the librairy can access the native android function
return 0;
}
然后在名为ExempleLib.java的文件中配置ndk我已经定义了
static {
System.loadLibrary("LibExemple");
}
然后是库初始化的原型
public native void libExemple_init();
lib_exemple.c中第一个方法的原型
public native int lib_Exemple_store_session_key(byte pKey, char key_length, byte keyIndex);
和它调用的java函数
protected int KeyStoreSessionKey(byte pKey, char key_length, byte keyIndex) {
...
}
我的mainActivity包含
ExempleLib LibFunc = new ExempleLib();
Log.d(TAG, "init lib" );
LibFunc.lib_Exemple_init();
我的目标是在初始化我的库并调用init函数之后,它可以调用lib_exemple.c的第二个方法中的第一个方法(库中使用的方法)
感谢
编辑:
我的问题的解决方案是当我初始化lib时,我需要保存jvm 所以我可以直接访问库方法中的JNIenv
jobject Savedinstance = NULL;
static JavaVM *cachedJVM;
JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *jvm, void *reserved) {
cachedJVM = jvm;
return JNI_VERSION_1_6;
}
JNIEnv *AttachJava() {
JavaVMAttachArgs args = {JNI_VERSION_1_6, 0, 0};
JNIEnv *java;
(*cachedJVM)->AttachCurrentThread(cachedJVM, &java, &args);
return java;
}
JNIEXPORT jint JNICALL
Java_com_example_vgosselin_libExemple_Libs_ExempleLib_lib_1init(JNIEnv *env,
jobject instance) {
Savedinstance = instance;
void *element = 0;
jint result;
result = lib_Exemple_init_();
return result;
}
所以我可以在
中调用java方法int lib_Exemple_store_session_key(uint8_t Session, P_KEY_ST_T pKey, uint8_t keyType) {
JNIEnv *NewEnv = AttachJava();
jclass clazz = (*NewEnv)->FindClass(NewEnv,"com/example/vgosselin/libExemple/Libs/ExempleLib");
jmethodID mCurrentActivityId = (*NewEnv)->GetMethodID(NewEnv,clazz,"KeystoreStoreKey","([BCB)I");
jint result;
jbyteArray Data = 0;
jchar Key = 0;
jbyte Type = 0;
result = (*NewEnv)->CallIntMethod(NewEnv, Savedinstance, mCurrentActivityId, Data, Key, Type);
return result;
}
现在我不再需要jni语法中的方法
JNIEXPORT jint JNICALL Java_com_example_libExemple_Libs_ExempleLib_lib_1Exemple_1store_1session_1key