加载中 ...
首页 > 常见问题 正文

干货|JNI实现机制

2019-03-24 10:31:08 来源:沈阳软件公司 作者:沈阳软件开发

private static native String nativeLoad(String filename, ClassLoader loader, String librarySearchPath);

 

在代码中我们并没有看到相关加载nativeLoad这个当地要领的so,那么它又是用什么方式在什么时间被注册的呢?

 

许多系统的当地要领都是在应用汇海的时间通过显示注册的方式被注册的,下面我们来看下系统汇海后会做哪些事情。

 

汇海虚拟机历程app_process首先会执行app_main.cpp中的main要领

 

/frameworks/base/cmds/app_process/app_main.cpp

main() -> AndroidRuntime.start()

int main(int argc, char* const argv[])

{

//......

if (zygote) {

runtime.start("com.android.internal.os.ZygoteInit",

startSystemServer ? "start-system-server" : "");

} else if (className) {

// Remainder of args get passed to startup class main()

runtime.mClassName = className;

runtime.mArgC = argc - i;

runtime.mArgV = argv + i;

runtime.start("com.android.internal.os.RuntimeInit",

application ? "application" : "tool");

}

//......

}

/frameworks/base/core/jni/AndroidRuntime.cpp

start()->startVm()

void AndroidRuntime::start(const char* className, const char* options)

{

//......

/* start the virtual machine */

JniInvocation jni_invocation;

jni_invocation.Init(NULL);

JNIEnv* env;

if (startVm(&mJavaVM, &env) != 0) {//汇海vm

return;

}

}

 

int AndroidRuntime::startVm(JavaVM** pJavaVM, JNIEnv** pEnv)

{

 

//......

if (JNI_CreateJavaVM(pJavaVM, pEnv, &initArgs) < 0) {//创建vm

ALOGE("JNI_CreateJavaVM failedn");

goto bail;

}

//......

}

JNI_CreateJavaVM()在art和dalvik中都有相关实现,这里仅以dalvik为主线跟踪,art的实现在/art/runtime/jni_internal.cc中

/dalvik/vm/Jni.cpp

JNI_CreateJavaVM() -> Init.dvmStartUp()

jint JNI_CreateJavaVM(JavaVM** p_vm, JNIEnv** p_env, void* vm_args) {

//......

JNIEnvExt* pEnv = (JNIEnvExt*) dvmCreateJNIEnv(NULL);

/* Initialize VM. */

gDvm.initializing = true;

std::string status = dvmStartup(argc, argv.get(), args->ignoreUnrecognized, (JNIEnv*)pEnv);//初始化vm

//......

}

/dalvik/vm/Init.cpp

dvmStartUp()-> InternalNative.dvmInternalNativeStartup()

dvmStartUp()-> registerSystemNatives() -> jni.RegisterNatives()

std::string dvmStartup(int argc, const char* const argv[],

bool ignoreUnrecognized, JNIEnv* pEnv)

{

//......

if (!dvmNativeStartup()) {//初始化native

return "dvmNativeStartup failed";

}

if (!dvmInternalNativeStartup()) {//初始化内部native

return "dvmInternalNativeStartup failed";

}

if (!dvmJniStartup()) {//初始化jni

return "dvmJniStartup failed";

}

//......

if (!registerSystemNatives(pEnv)) {//注册系统当地要领

return "couldn't register system natives";

}

//......

return "";

}

 

static bool registerSystemNatives(JNIEnv* pEnv)

{

//......

JNIEXPORT jobject JNICALL Java_java_lang_Class_getDex(JNIEnv* env, jclass javaClass);

const JNINativeMethod Java_java_lang_Class[] = {

{ "getDex", "()Lcom/android/dex/Dex;", (void*) Java_java_lang_Class_getDex },

};

//注册Dex的getDex要领

if (pEnv->RegisterNatives(c, Java_java_lang_Class, 1) != JNI_OK) {

dvmAbort();

}

//加载javacore和nativehelper库

loadJniLibrary("javacore");

loadJniLibrary("nativehelper");

// Back to run mode.

self->status = THREAD_RUNNING;

return true;

}

/dalvik/vm/native/InternalNative.cpp

dvmInternalNativeStartup()

bool dvmInternalNativeStartup()

{

DalvikNativeClass* classPtr = gDvmNativeMethodSet;//遍历系统类结构体,并生存到gDvm的全局变量userDexFiles中

while (classPtr->classDescriptor != NULL) {

classPtr->classDescriptorHash =

dvmComputeUtf8Hash(classPtr->classDescriptor);

classPtr++;

}

gDvm.userDexFiles = dvmHashTableCreate(2, dvmFreeDexOrJar);

if (gDvm.userDexFiles == NULL)

return false;

return true;

}

 

//系统当地要领都存在这里

static DalvikNativeClass gDvmNativeMethodSet[] = {

{ "Ljava/lang/Object;", dvm_java_lang_Object, 0 },

{ "Ljava/lang/Class;", dvm_java_lang_Class, 0 },

//……

{ "Ljava/lang/Runtime;", dvm_java_lang_Runtime, 0 },

{ "Ljava/lang/String;", dvm_java_lang_String, 0 },

{ "Ljava/lang/System;", dvm_java_lang_System, 0 },

//……

{ "Ldalvik/system/DexFile;", dvm_dalvik_system_DexFile, 0 },

{ "Ldalvik/system/VMRuntime;", dvm_dalvik_system_VMRuntime, 0 },

“沈阳软件公司”的新闻页面文章、图片、音频、视频等稿件均为自媒体人、第三方机构发布或转载。如稿件涉及版权等问题,请与

我们联系删除或处理,客服QQ:55506560,稿件内容仅为传递更多信息之目的,不代表本网观点,亦不代表本网站赞同

其观点或证实其内容的真实性。

推荐阅读