JNI、java native interface 。可以实现Java和C、C++之间的调用。
在Android开发中是必须要掌握的内容。
在应用开发中,编写JNI代码的注册可分为动态注册和静态注册
动态注册:
声明好方法、注意这些签名 在JNI_OnLoad中进行注册。
static const JNINativeMethod method[] = {
{"openUrl","(Ljava/lang/String;Ljava/lang/Object;I)I", (void*)playVideo},
{"InitView","(Ljava/lang/Object;)I", (void*)InitView},
{"start","()I", (void*) start},
{"getPauseStatus","()Z", (void*)getPauseStatus},
{"onRelease","()Z", (void*)onRelease},
{"stopVideo","()V", (void*)stopVideo},
{"seekTo","(D)V", (void*)changeSeek},
{"changeURL","(Ljava/lang/String;)V", (void*)changeURL},
{"setPause","(Z)V", (void*)setPause},
{"getSupportProcel","()Ljava/lang/String;", (void*)getSupportInfo}
};
static const char *mClassName = "com/mark/myapplication/player/core/PlayerCore";
int JNI_OnLoad(JavaVM *vm,void *re){
g_vm = vm;
IPlayerPorxy::Get()->Init(vm);
AndroidHelper::getInstance()->SetVM(g_vm);
//获得JNIEnv
JNIEnv *env = 0;
int r = vm->GetEnv((void**)&env,JNI_VERSION_1_6);
//小于0失败,等于0成功
if(r != JNI_OK){
return -1;
}
//获得class对象
jclass jcls = env->FindClass(mClassName);
//动态注册
env->RegisterNatives(jcls,method, sizeof(method)/ sizeof(JNINativeMethod));
return JNI_VERSION_1_6;
}
静态注册:
extern "C" JNIEXPORT jstring JNICALL
Java_com_mark_myapplication_MainActivity_stringFromJNI(
JNIEnv* env,
jobject /* this */) {
std::string hello = "Hello from C++";
return env->NewStringUTF(hello.c_str());
}
JNI函数签名
https://blog.csdn.net/weixin_75102992/article/details/130771941
全局引用&局部引用&弱全局引用
https://blog.csdn.net/huangjinjin520/article/details/123288292
系统中的JNI代码模块是在哪里被加载的呢。
在zygote启动时
frameworks/base/core/jni/AndroidRuntime.cpp
void AndroidRuntime::start(const char* className, const Vector<String8>& options, bool zygote)
{
......
JniInvocation jni_invocation;
jni_invocation.Init(NULL);
JNIEnv* env;
if (startVm(&mJavaVM, &env, zygote, primary_zygote) != 0) {
return;
}
onVmCreated(env);
/*
* Register android functions.注册JNI
*/
if (startReg(env) < 0) {
ALOGE("Unable to register all android natives\n");
return;
}
..............
}
注册了framework中使用的native代码,如果自己需要添加framework的JNI,需要在这里进行添加声明
static const RegJNIRec gRegJNI[] = {
REG_JNI(register_com_android_internal_os_RuntimeInit),
REG_JNI(register_com_android_internal_os_ZygoteInit_nativeZygoteInit),
REG_JNI(register_android_os_SystemClock),
REG_JNI(register_android_util_EventLog),
REG_JNI(register_android_util_Log),
REG_JNI(register_android_util_MemoryIntArray),
REG_JNI(register_android_app_admin_SecurityLog),
REG_JNI(register_android_content_AssetManager),
REG_JNI(register_android_content_StringBlock),
REG_JNI(register_android_content_XmlBlock),
..................
}
例如storage_StorageManager可以在storage_StorageManager.cpp可找到
//跟APP开发中的动态注册类似
static const JNINativeMethod gStorageManagerMethods[] = {
{"setQuotaProjectId", "(Ljava/lang/String;J)Z",
(void*)android_os_storage_StorageManager_setQuotaProjectId},
};
const char* const kStorageManagerPathName = "android/os/storage/StorageManager";
int register_android_os_storage_StorageManager(JNIEnv* env) {
return RegisterMethodsOrDie(env, kStorageManagerPathName, gStorageManagerMethods,
NELEM(gStorageManagerMethods));
}
}