<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ThinkChat2.0新版上線,更智能更精彩,支持會話、畫圖、視頻、閱讀、搜索等,送10W Token,即刻開啟你的AI之旅 廣告
                原文出處——>[Xposed源碼剖析——Xposed初始化](http://blog.csdn.net/yzzst/article/details/47834077) 承接上文[Xposed源碼剖析——app_process作用詳解](http://blog.csdn.net/yzzst/article/details/47829657) 之前我們看過了app_main.cpp源碼,知道了在其中,啟動了XposedBridge.jar方法。那么,其中還做了些什么事情呢? 之前我們也看到了在app_main.cpp還有幾處新增的邏輯。xposed::initialize和onVmCreated回調。下面我在仔細的閱讀以下源碼。 **xposed::initialize初始化** ![](http://img.blog.csdn.net/20150821150755538) 對于xposed::initalize的初始化工作,我們能夠在xposed.cpp中看到其具體的邏輯實現。 ~~~ /** * 初始化xposed */ bool initialize(bool zygote, bool startSystemServer, const char* className, int argc, char* const argv[]) { #if !defined(XPOSED_ENABLE_FOR_TOOLS) if (!zygote) return false; #endif xposed->zygote = zygote; xposed->startSystemServer = startSystemServer; xposed->startClassName = className; xposed->xposedVersionInt = xposedVersionInt; #if XPOSED_WITH_SELINUX xposed->isSELinuxEnabled = is_selinux_enabled() == 1; xposed->isSELinuxEnforcing = xposed->isSELinuxEnabled && security_getenforce() == 1; #else xposed->isSELinuxEnabled = false; xposed->isSELinuxEnforcing = false; #endif // XPOSED_WITH_SELINUX if (startSystemServer) { xposed::logcat::start(); } else if (zygote) { // TODO Find a better solution for this // Give the primary Zygote process a little time to start first. // This also makes the log easier to read, as logs for the two Zygotes are not mixed up. sleep(10); } // 打印rom信息 printRomInfo(); if (startSystemServer) { if (!xposed::service::startAll()) return false; #if XPOSED_WITH_SELINUX } else if (xposed->isSELinuxEnabled) { if (!xposed::service::startMembased()) return false; #endif // XPOSED_WITH_SELINUX } // FIXME Zygote has no access to input devices, this would need to be check in system_server context if (zygote && !isSafemodeDisabled() && detectSafemodeTrigger(shouldSkipSafemodeDelay())) disableXposed(); if (isDisabled() || (!zygote && shouldIgnoreCommand(argc, argv))) return false; // 將XposedBridge.jar的路徑添加到環境變量classpath中 return addJarToClasspath(); } ~~~ **onVmCreated 初始化后的準備工作 ** ![](http://img.blog.csdn.net/20150821093405424) 其具體的邏輯如下所示: ~~~ /** * 向當前的runtime中載入libxposed_*.so */ void onVmCreated(JNIEnv* env) { // Determine the currently active runtime const char* xposedLibPath = NULL; if (!determineRuntime(&xposedLibPath)) { ALOGE("Could not determine runtime, not loading Xposed"); return; } // Load the suitable libxposed_*.so for it const char *error; void* xposedLibHandle = dlopen(xposedLibPath, RTLD_NOW); if (!xposedLibHandle) { ALOGE("Could not load libxposed: %s", dlerror()); return; } // Clear previous errors dlerror(); // Initialize the library bool (*xposedInitLib)(XposedShared* shared) = NULL; *(void **) (&xposedInitLib) = dlsym(xposedLibHandle, "xposedInitLib"); if (!xposedInitLib) { ALOGE("Could not find function xposedInitLib"); return; } #if XPOSED_WITH_SELINUX xposed->zygoteservice_accessFile = &service::membased::accessFile; xposed->zygoteservice_statFile = &service::membased::statFile; xposed->zygoteservice_readFile = &service::membased::readFile; #endif // XPOSED_WITH_SELINUX // 這里的xposed變量,其實是一個全局的XposedShare。 // 調用XposedShare的onVmCreated則會根據不同的vm架構針對不同的實現。 if (xposedInitLib(xposed)) { xposed->onVmCreated(env); } } ~~~ **libxposed_dalvik.cpp hook環境初始化** ~~~ /** Called by Xposed's app_process replacement. * 在被替換后的app_process中調用 */ bool xposedInitLib(xposed::XposedShared* shared) { xposed = shared; // 將自己的onVmCreated方法,指向onVmCreated方法 xposed->onVmCreated = &onVmCreated; return true; } /** Called very early during VM startup. * 在VM啟動的時候調用,而且調用時機比較早 */ void onVmCreated(JNIEnv* env) { if (!initMemberOffsets(env)) return; // 找到小米系統的MIUI_RESOURCE做特殊處理 jclass classMiuiResources = env->FindClass(CLASS_MIUI_RESOURCES); if (classMiuiResources != NULL) { ClassObject* clazz = (ClassObject*)dvmDecodeIndirectRef(dvmThreadSelf(), classMiuiResources); if (dvmIsFinalClass(clazz)) { ALOGD("Removing final flag for class '%s'", CLASS_MIUI_RESOURCES); clazz->accessFlags &= ~ACC_FINAL; } } env->ExceptionClear(); jclass classXTypedArray = env->FindClass(CLASS_XTYPED_ARRAY); if (classXTypedArray == NULL) { ALOGE("Error while loading XTypedArray class '%s':", CLASS_XTYPED_ARRAY); dvmLogExceptionStackTrace(); env->ExceptionClear(); return; } prepareSubclassReplacement(classXTypedArray); // 獲取到全局的XposedBridge classXposedBridge = env->FindClass(CLASS_XPOSED_BRIDGE); classXposedBridge = reinterpret_cast<jclass>(env->NewGlobalRef(classXposedBridge)); if (classXposedBridge == NULL) { ALOGE("Error while loading Xposed class '%s':", CLASS_XPOSED_BRIDGE); dvmLogExceptionStackTrace(); env->ExceptionClear(); return; } // 注冊一些 XposedBridge 的 native 方法 ALOGI("Found Xposed class '%s', now initializing", CLASS_XPOSED_BRIDGE); if (register_natives_XposedBridge(env, classXposedBridge) != JNI_OK) { ALOGE("Could not register natives for '%s'", CLASS_XPOSED_BRIDGE); dvmLogExceptionStackTrace(); env->ExceptionClear(); return; } xposedLoadedSuccessfully = true; } ~~~ **JNI方法注冊邏輯** 這里注冊的幾個方法都是,Xposed核心的幾個方法函數。 ~~~ int register_natives_XposedBridge(JNIEnv* env, jclass clazz) { const JNINativeMethod methods[] = { NATIVE_METHOD(XposedBridge, getStartClassName, "()Ljava/lang/String;"), // 獲得Runtime NATIVE_METHOD(XposedBridge, getRuntime, "()I"), // 啟動SystemServer NATIVE_METHOD(XposedBridge, startsSystemServer, "()Z"), // 獲取Xposed的版本信息 NATIVE_METHOD(XposedBridge, getXposedVersion, "()I"), // 初始化navtive NATIVE_METHOD(XposedBridge, initNative, "()Z"), // hook一個方法的native實現 NATIVE_METHOD(XposedBridge, hookMethodNative, "(Ljava/lang/reflect/Member;Ljava/lang/Class;ILjava/lang/Object;)V"), #ifdef ART_TARGET NATIVE_METHOD(XposedBridge, invokeOriginalMethodNative, "(Ljava/lang/reflect/Member;I[Ljava/lang/Class;Ljava/lang/Class;Ljava/lang/Object;[Ljava/lang/Object;)Ljava/lang/Object;"), #endif NATIVE_METHOD(XposedBridge, setObjectClassNative, "(Ljava/lang/Object;Ljava/lang/Class;)V"), NATIVE_METHOD(XposedBridge, dumpObjectNative, "(Ljava/lang/Object;)V"), NATIVE_METHOD(XposedBridge, cloneToSubclassNative, "(Ljava/lang/Object;Ljava/lang/Class;)Ljava/lang/Object;"), }; return env->RegisterNatives(clazz, methods, NELEM(methods)); } ~~~ > 我們看到RegisterNatives這個方法的時候不是很理解,這里做一個簡介。 > 以前在jni中寫本地方法時,都會寫成 Java_com_example_hellojni_HelloJni_stringFromJNI的形式,函數名很長,而且當類名變了的時候,函數名必須一個一個的改,麻煩。 > 現在好了有了RegisterNatives,可以簡化我們的書寫 > 和傳統方法相比,使用RegisterNatives的好處有三點: > 1. C++中函數命名自由,不必像javah自動生成的函數聲明那樣,拘泥特定的命名方式; > 2. 效率高。傳統方式下,Java類call本地函數時,通常是依靠VM去動態尋找.so中的本地函數(因此它們才需要特定規則的命名格式),而使用RegisterNatives將本地函數向VM進行登記,可以讓其更有效率的找到函數; > 3. 運行時動態調整本地函數與Java函數值之間的映射關系,只需要多次call RegisterNatives()方法,并傳入不同的映射表參數即可。
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看