承接上文 http://blog.csdn.net/yzzst/article/details/47829657
之前我们看过了app_main.cpp源码,知道了在其中,启动了XposedBridge.jar方法。那么,其中还做了些什么事情呢?
之前我们也看到了在app_main.cpp还有几处新增的逻辑。xposed::initialize和onVmCreated回调。下面我在仔细的阅读以下源码。
xposed::initialize初始化
对于xposed::initalize的初始化工作,我们能够在xposed.cpp中看到其具体的逻辑实现。
<code class="hljs cs has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-comment" style="color:#8800;box-sizing: border-box;">/** * 初始化xposed */</span> <span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">bool</span> initialize(<span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">bool</span> zygote, <span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">bool</span> startSystemServer, <span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">const</span> <span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">char</span>* className, <span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">int</span> argc, <span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">char</span>* <span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">const</span> argv[]) { <span class="hljs-preprocessor" style="color:#444444;box-sizing: border-box;">#<span class="hljs-keyword" style="color:#444444;box-sizing: border-box;">if</span> !defined(XPOSED_ENABLE_FOR_TOOLS)</span> <span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">if</span> (!zygote) <span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">return</span> <span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">false</span>; <span class="hljs-preprocessor" style="color:#444444;box-sizing: border-box;">#<span class="hljs-keyword" style="color:#444444;box-sizing: border-box;">endif</span></span> xposed->zygote = zygote; xposed->startSystemServer = startSystemServer; xposed->startClassName = className; xposed->xposedVersionInt = xposedVersionInt; <span class="hljs-preprocessor" style="color:#444444;box-sizing: border-box;">#<span class="hljs-keyword" style="color:#444444;box-sizing: border-box;">if</span> XPOSED_WITH_SELINUX</span> xposed->isSELinuxEnabled = is_selinux_enabled() == <span class="hljs-number" style="color:#06666;box-sizing: border-box;">1</span>; xposed->isSELinuxEnforcing = xposed->isSELinuxEnabled && security_getenforce() == <span class="hljs-number" style="color:#06666;box-sizing: border-box;">1</span>; <span class="hljs-preprocessor" style="color:#444444;box-sizing: border-box;">#<span class="hljs-keyword" style="color:#444444;box-sizing: border-box;">else</span></span> xposed->isSELinuxEnabled = <span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">false</span>; xposed->isSELinuxEnforcing = <span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">false</span>; <span class="hljs-preprocessor" style="color:#444444;box-sizing: border-box;">#<span class="hljs-keyword" style="color:#444444;box-sizing: border-box;">endif</span> // XPOSED_WITH_SELINUX</span> <span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">if</span> (startSystemServer) { xposed::logcat::start(); } <span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">else</span> <span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">if</span> (zygote) { <span class="hljs-comment" style="color:#8800;box-sizing: border-box;">// TODO Find a better solution for this</span> <span class="hljs-comment" style="color:#8800;box-sizing: border-box;">// Give the primary Zygote process a little time to start first.</span> <span class="hljs-comment" style="color:#8800;box-sizing: border-box;">// This also makes the log easier to read, as logs for the two Zygotes are not mixed up.</span> sleep(<span class="hljs-number" style="color:#06666;box-sizing: border-box;">10</span>); } <span class="hljs-comment" style="color:#8800;box-sizing: border-box;">// 打印rom信息</span> printRomInfo(); <span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">if</span> (startSystemServer) { <span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">if</span> (!xposed::service::startAll()) <span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">return</span> <span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">false</span>; <span class="hljs-preprocessor" style="color:#444444;box-sizing: border-box;">#<span class="hljs-keyword" style="color:#444444;box-sizing: border-box;">if</span> XPOSED_WITH_SELINUX</span> } <span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">else</span> <span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">if</span> (xposed->isSELinuxEnabled) { <span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">if</span> (!xposed::service::startMembased()) <span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">return</span> <span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">false</span>; <span class="hljs-preprocessor" style="color:#444444;box-sizing: border-box;">#<span class="hljs-keyword" style="color:#444444;box-sizing: border-box;">endif</span> // XPOSED_WITH_SELINUX</span> } <span class="hljs-comment" style="color:#8800;box-sizing: border-box;">// FIXME Zygote has no access to input devices, this would need to be check in system_server context</span> <span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">if</span> (zygote && !isSafemodeDisabled() && detectSafemodeTrigger(shouldSkipSafemodeDelay())) disableXposed(); <span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">if</span> (isDisabled() || (!zygote && shouldIgnoreCommand(argc, argv))) <span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">return</span> <span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">false</span>; <span class="hljs-comment" style="color:#8800;box-sizing: border-box;">// 将XposedBridge.jar的路径添加到环境变量classpath中</span> <span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">return</span> addJarToClasspath(); }</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li><li style="box-sizing: border-box; padding: 0px 5px;">18</li><li style="box-sizing: border-box; padding: 0px 5px;">19</li><li style="box-sizing: border-box; padding: 0px 5px;">20</li><li style="box-sizing: border-box; padding: 0px 5px;">21</li><li style="box-sizing: border-box; padding: 0px 5px;">22</li><li style="box-sizing: border-box; padding: 0px 5px;">23</li><li style="box-sizing: border-box; padding: 0px 5px;">24</li><li style="box-sizing: border-box; padding: 0px 5px;">25</li><li style="box-sizing: border-box; padding: 0px 5px;">26</li><li style="box-sizing: border-box; padding: 0px 5px;">27</li><li style="box-sizing: border-box; padding: 0px 5px;">28</li><li style="box-sizing: border-box; padding: 0px 5px;">29</li><li style="box-sizing: border-box; padding: 0px 5px;">30</li><li style="box-sizing: border-box; padding: 0px 5px;">31</li><li style="box-sizing: border-box; padding: 0px 5px;">32</li><li style="box-sizing: border-box; padding: 0px 5px;">33</li><li style="box-sizing: border-box; padding: 0px 5px;">34</li><li style="box-sizing: border-box; padding: 0px 5px;">35</li><li style="box-sizing: border-box; padding: 0px 5px;">36</li><li style="box-sizing: border-box; padding: 0px 5px;">37</li><li style="box-sizing: border-box; padding: 0px 5px;">38</li><li style="box-sizing: border-box; padding: 0px 5px;">39</li><li style="box-sizing: border-box; padding: 0px 5px;">40</li><li style="box-sizing: border-box; padding: 0px 5px;">41</li><li style="box-sizing: border-box; padding: 0px 5px;">42</li><li style="box-sizing: border-box; padding: 0px 5px;">43</li><li style="box-sizing: border-box; padding: 0px 5px;">44</li><li style="box-sizing: border-box; padding: 0px 5px;">45</li><li style="box-sizing: border-box; padding: 0px 5px;">46</li><li style="box-sizing: border-box; padding: 0px 5px;">47</li><li style="box-sizing: border-box; padding: 0px 5px;">48</li><li style="box-sizing: border-box; padding: 0px 5px;">49</li><li style="box-sizing: border-box; padding: 0px 5px;">50</li><li style="box-sizing: border-box; padding: 0px 5px;">51</li><li style="box-sizing: border-box; padding: 0px 5px;">52</li><li style="box-sizing: border-box; padding: 0px 5px;">53</li><li style="box-sizing: border-box; padding: 0px 5px;">54</li></ul>
* onVmCreated 初始化后的准备工作 *
其具体的逻辑如下所示:
<code class="hljs java has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-javadoc" style="color:#8800;box-sizing: border-box;">/** * 向当前的runtime中载入libxposed_*.so */</span> <span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">void</span> onVmCreated(JNIEnv* env) { <span class="hljs-comment" style="color:#8800;box-sizing: border-box;">// Determine the currently active runtime</span> <span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">const</span> <span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">char</span>* xposedLibPath = NULL; <span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">if</span> (!determineRuntime(&xposedLibPath)) { ALOGE(<span class="hljs-string" style="color:#0880;box-sizing: border-box;">"Could not determine runtime, not loading Xposed"</span>); <span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">return</span>; } <span class="hljs-comment" style="color:#8800;box-sizing: border-box;">// Load the suitable libxposed_*.so for it</span> <span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">const</span> <span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">char</span> *error; <span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">void</span>* xposedLibHandle = dlopen(xposedLibPath, RTLD_NOW); <span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">if</span> (!xposedLibHandle) { ALOGE(<span class="hljs-string" style="color:#0880;box-sizing: border-box;">"Could not load libxposed: %s"</span>, dlerror()); <span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">return</span>; } <span class="hljs-comment" style="color:#8800;box-sizing: border-box;">// Clear previous errors</span> dlerror(); <span class="hljs-comment" style="color:#8800;box-sizing: border-box;">// Initialize the library</span> bool (*xposedInitLib)(XposedShared* shared) = NULL; *(<span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">void</span> **) (&xposedInitLib) = dlsym(xposedLibHandle, <span class="hljs-string" style="color:#0880;box-sizing: border-box;">"xposedInitLib"</span>); <span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">if</span> (!xposedInitLib) { ALOGE(<span class="hljs-string" style="color:#0880;box-sizing: border-box;">"Could not find function xposedInitLib"</span>); <span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">return</span>; } #<span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">if</span> XPOSED_WITH_SELINUX xposed->zygoteservice_accessFile = &service::membased::accessFile; xposed->zygoteservice_statFile = &service::membased::statFile; xposed->zygoteservice_readFile = &service::membased::readFile; #endif <span class="hljs-comment" style="color:#8800;box-sizing: border-box;">// XPOSED_WITH_SELINUX</span> <span class="hljs-comment" style="color:#8800;box-sizing: border-box;">// 这里的xposed变量,其实是一个全局的XposedShare。</span> <span class="hljs-comment" style="color:#8800;box-sizing: border-box;">// 调用XposedShare的onVmCreated则会根据不同的vm架构针对不同的实现。</span> <span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">if</span> (xposedInitLib(xposed)) { xposed->onVmCreated(env); } }</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li><li style="box-sizing: border-box; padding: 0px 5px;">18</li><li style="box-sizing: border-box; padding: 0px 5px;">19</li><li style="box-sizing: border-box; padding: 0px 5px;">20</li><li style="box-sizing: border-box; padding: 0px 5px;">21</li><li style="box-sizing: border-box; padding: 0px 5px;">22</li><li style="box-sizing: border-box; padding: 0px 5px;">23</li><li style="box-sizing: border-box; padding: 0px 5px;">24</li><li style="box-sizing: border-box; padding: 0px 5px;">25</li><li style="box-sizing: border-box; padding: 0px 5px;">26</li><li style="box-sizing: border-box; padding: 0px 5px;">27</li><li style="box-sizing: border-box; padding: 0px 5px;">28</li><li style="box-sizing: border-box; padding: 0px 5px;">29</li><li style="box-sizing: border-box; padding: 0px 5px;">30</li><li style="box-sizing: border-box; padding: 0px 5px;">31</li><li style="box-sizing: border-box; padding: 0px 5px;">32</li><li style="box-sizing: border-box; padding: 0px 5px;">33</li><li style="box-sizing: border-box; padding: 0px 5px;">34</li><li style="box-sizing: border-box; padding: 0px 5px;">35</li><li style="box-sizing: border-box; padding: 0px 5px;">36</li><li style="box-sizing: border-box; padding: 0px 5px;">37</li><li style="box-sizing: border-box; padding: 0px 5px;">38</li><li style="box-sizing: border-box; padding: 0px 5px;">39</li><li style="box-sizing: border-box; padding: 0px 5px;">40</li><li style="box-sizing: border-box; padding: 0px 5px;">41</li><li style="box-sizing: border-box; padding: 0px 5px;">42</li></ul>
* libxposed_dalvik.cpp hook环境初始化*
<code class="hljs scala has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-javadoc" style="color:#8800;box-sizing: border-box;">/** Called by Xposed's app_process replacement. * 在被替换后的app_process中调用 */</span> bool xposedInitLib(xposed::XposedShared* shared) { xposed = shared; <span class="hljs-comment" style="color:#8800;box-sizing: border-box;">// 将自己的onVmCreated方法,指向onVmCreated方法</span> xposed->onVmCreated = &onVmCreated; <span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">return</span> <span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">true</span>; } <span class="hljs-javadoc" style="color:#8800;box-sizing: border-box;">/** Called very early during VM startup. * 在VM启动的时候调用,而且调用时机比较早 */</span> void onVmCreated(JNIEnv* env) { <span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">if</span> (!initMemberOffsets(env)) <span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">return</span>; <span class="hljs-comment" style="color:#8800;box-sizing: border-box;">// 找到小米系统的MIUI_RESOURCE做特殊处理</span> j<span class="hljs-class" style="box-sizing: border-box;"><span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">class</span> <span class="hljs-title" style="color:#66066;box-sizing: border-box;">classMiuiResources</span> = <span class="hljs-title" style="color:#66066;box-sizing: border-box;">env</span>-><span class="hljs-title" style="color:#66066;box-sizing: border-box;">FindClass</span><span class="hljs-params" style="color:#66066;box-sizing: border-box;">(CLASS_MIUI_RESOURCES)</span>;</span> <span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">if</span> (classMiuiResources != NULL) { ClassObject* clazz = (ClassObject*)dvmDecodeIndirectRef(dvmThreadSelf(), classMiuiResources); <span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">if</span> (dvmIsFinalClass(clazz)) { ALOGD(<span class="hljs-string" style="color:#0880;box-sizing: border-box;">"Removing final flag for class '%s'"</span>, CLASS_MIUI_RESOURCES); clazz->accessFlags &= ~ACC_FINAL; } } env->ExceptionClear(); j<span class="hljs-class" style="box-sizing: border-box;"><span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">class</span> <span class="hljs-title" style="color:#66066;box-sizing: border-box;">classXTypedArray</span> = <span class="hljs-title" style="color:#66066;box-sizing: border-box;">env</span>-><span class="hljs-title" style="color:#66066;box-sizing: border-box;">FindClass</span><span class="hljs-params" style="color:#66066;box-sizing: border-box;">(CLASS_XTYPED_ARRAY)</span>;</span> <span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">if</span> (classXTypedArray == NULL) { ALOGE(<span class="hljs-string" style="color:#0880;box-sizing: border-box;">"Error while loading XTypedArray class '%s':"</span>, CLASS_XTYPED_ARRAY); dvmLogExceptionStackTrace(); env->ExceptionClear(); <span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">return</span>; } prepareSubclassReplacement(classXTypedArray); <span class="hljs-comment" style="color:#8800;box-sizing: border-box;">// 获取到全局的XposedBridge</span> classXposedBridge = env->FindClass(CLASS_XPOSED_BRIDGE); classXposedBridge = reinterpret_cast<jclass>(env->NewGlobalRef(classXposedBridge)); <span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">if</span> (classXposedBridge == NULL) { ALOGE(<span class="hljs-string" style="color:#0880;box-sizing: border-box;">"Error while loading Xposed class '%s':"</span>, CLASS_XPOSED_BRIDGE); dvmLogExceptionStackTrace(); env->ExceptionClear(); <span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">return</span>; } <span class="hljs-comment" style="color:#8800;box-sizing: border-box;">// 注册一些 XposedBridge 的 native 方法</span> ALOGI(<span class="hljs-string" style="color:#0880;box-sizing: border-box;">"Found Xposed class '%s', now initializing"</span>, CLASS_XPOSED_BRIDGE); <span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">if</span> (register_natives_XposedBridge(env, classXposedBridge) != JNI_OK) { ALOGE(<span class="hljs-string" style="color:#0880;box-sizing: border-box;">"Could not register natives for '%s'"</span>, CLASS_XPOSED_BRIDGE); dvmLogExceptionStackTrace(); env->ExceptionClear(); <span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">return</span>; } xposedLoadedSuccessfully = <span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">true</span>; }</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li><li style="box-sizing: border-box; padding: 0px 5px;">18</li><li style="box-sizing: border-box; padding: 0px 5px;">19</li><li style="box-sizing: border-box; padding: 0px 5px;">20</li><li style="box-sizing: border-box; padding: 0px 5px;">21</li><li style="box-sizing: border-box; padding: 0px 5px;">22</li><li style="box-sizing: border-box; padding: 0px 5px;">23</li><li style="box-sizing: border-box; padding: 0px 5px;">24</li><li style="box-sizing: border-box; padding: 0px 5px;">25</li><li style="box-sizing: border-box; padding: 0px 5px;">26</li><li style="box-sizing: border-box; padding: 0px 5px;">27</li><li style="box-sizing: border-box; padding: 0px 5px;">28</li><li style="box-sizing: border-box; padding: 0px 5px;">29</li><li style="box-sizing: border-box; padding: 0px 5px;">30</li><li style="box-sizing: border-box; padding: 0px 5px;">31</li><li style="box-sizing: border-box; padding: 0px 5px;">32</li><li style="box-sizing: border-box; padding: 0px 5px;">33</li><li style="box-sizing: border-box; padding: 0px 5px;">34</li><li style="box-sizing: border-box; padding: 0px 5px;">35</li><li style="box-sizing: border-box; padding: 0px 5px;">36</li><li style="box-sizing: border-box; padding: 0px 5px;">37</li><li style="box-sizing: border-box; padding: 0px 5px;">38</li><li style="box-sizing: border-box; padding: 0px 5px;">39</li><li style="box-sizing: border-box; padding: 0px 5px;">40</li><li style="box-sizing: border-box; padding: 0px 5px;">41</li><li style="box-sizing: border-box; padding: 0px 5px;">42</li><li style="box-sizing: border-box; padding: 0px 5px;">43</li><li style="box-sizing: border-box; padding: 0px 5px;">44</li><li style="box-sizing: border-box; padding: 0px 5px;">45</li><li style="box-sizing: border-box; padding: 0px 5px;">46</li><li style="box-sizing: border-box; padding: 0px 5px;">47</li><li style="box-sizing: border-box; padding: 0px 5px;">48</li><li style="box-sizing: border-box; padding: 0px 5px;">49</li><li style="box-sizing: border-box; padding: 0px 5px;">50</li><li style="box-sizing: border-box; padding: 0px 5px;">51</li><li style="box-sizing: border-box; padding: 0px 5px;">52</li><li style="box-sizing: border-box; padding: 0px 5px;">53</li><li style="box-sizing: border-box; padding: 0px 5px;">54</li><li style="box-sizing: border-box; padding: 0px 5px;">55</li><li style="box-sizing: border-box; padding: 0px 5px;">56</li><li style="box-sizing: border-box; padding: 0px 5px;">57</li><li style="box-sizing: border-box; padding: 0px 5px;">58</li><li style="box-sizing: border-box; padding: 0px 5px;">59</li></ul>
JNI方法注册逻辑
这里注册的几个方法都是,Xposed核心的几个方法函数。
<code class="hljs vala has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"> <span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">int</span> register_natives_XposedBridge(JNIEnv* env, jclass clazz) { <span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">const</span> JNINativeMethod methods[] = { NATIVE_METHOD(XposedBridge, getStartClassName, <span class="hljs-string" style="color:#0880;box-sizing: border-box;">"()Ljava/lang/String;"</span>), <span class="hljs-comment" style="color:#8800;box-sizing: border-box;">// 获得Runtime</span> NATIVE_METHOD(XposedBridge, getRuntime, <span class="hljs-string" style="color:#0880;box-sizing: border-box;">"()I"</span>), <span class="hljs-comment" style="color:#8800;box-sizing: border-box;">// 启动SystemServer</span> NATIVE_METHOD(XposedBridge, startsSystemServer, <span class="hljs-string" style="color:#0880;box-sizing: border-box;">"()Z"</span>), <span class="hljs-comment" style="color:#8800;box-sizing: border-box;">// 获取Xposed的版本信息</span> NATIVE_METHOD(XposedBridge, getXposedVersion, <span class="hljs-string" style="color:#0880;box-sizing: border-box;">"()I"</span>), <span class="hljs-comment" style="color:#8800;box-sizing: border-box;">// 初始化navtive</span> NATIVE_METHOD(XposedBridge, initNative, <span class="hljs-string" style="color:#0880;box-sizing: border-box;">"()Z"</span>), <span class="hljs-comment" style="color:#8800;box-sizing: border-box;">// hook一个方法的native实现</span> NATIVE_METHOD(XposedBridge, hookMethodNative, <span class="hljs-string" style="color:#0880;box-sizing: border-box;">"(Ljava/lang/reflect/Member;Ljava/lang/Class;ILjava/lang/Object;)V"</span>), <span class="hljs-preprocessor" style="color:#444444;box-sizing: border-box;">#ifdef ART_TARGET</span> NATIVE_METHOD(XposedBridge, invokeOriginalMethodNative, <span class="hljs-string" style="color:#0880;box-sizing: border-box;">"(Ljava/lang/reflect/Member;I[Ljava/lang/Class;Ljava/lang/Class;Ljava/lang/Object;[Ljava/lang/Object;)Ljava/lang/Object;"</span>), <span class="hljs-preprocessor" style="color:#444444;box-sizing: border-box;">#endif</span> NATIVE_METHOD(XposedBridge, setObjectClassNative, <span class="hljs-string" style="color:#0880;box-sizing: border-box;">"(Ljava/lang/Object;Ljava/lang/Class;)V"</span>), NATIVE_METHOD(XposedBridge, dumpObjectNative, <span class="hljs-string" style="color:#0880;box-sizing: border-box;">"(Ljava/lang/Object;)V"</span>), NATIVE_METHOD(XposedBridge, cloneToSubclassNative, <span class="hljs-string" style="color:#0880;box-sizing: border-box;">"(Ljava/lang/Object;Ljava/lang/Class;)Ljava/lang/Object;"</span>), }; <span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">return</span> env->RegisterNatives(clazz, methods, NELEM(methods)); }</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li><li style="box-sizing: border-box; padding: 0px 5px;">18</li><li style="box-sizing: border-box; padding: 0px 5px;">19</li><li style="box-sizing: border-box; padding: 0px 5px;">20</li><li style="box-sizing: border-box; padding: 0px 5px;">21</li><li style="box-sizing: border-box; padding: 0px 5px;">22</li><li style="box-sizing: border-box; padding: 0px 5px;">23</li><li style="box-sizing: border-box; padding: 0px 5px;">24</li><li style="box-sizing: border-box; padding: 0px 5px;">25</li></ul>
我们看到RegisterNatives这个方法的时候不是很理解,这里做一个简介。
以前在jni中写本地方法时,都会写成 Java_com_example_hellojni_HelloJni_stringFromJNI的形式,函数名很长,而且当类名变了的时候,函数名必须一个一个的改,麻烦。
现在好了有了RegisterNatives,可以简化我们的书写
和传统方法相比,使用RegisterNatives的好处有三点:
1. C++中函数命名自由,不必像javah自动生成的函数声明那样,拘泥特定的命名方式;
2. 效率高。传统方式下,Java类call本地函数时,通常是依靠VM去动态寻找.so中的本地函数(因此它们才需要特定规则的命名格式),而使用RegisterNatives将本地函数向VM进行登记,可以让其更有效率的找到函数;
3. 运行时动态调整本地函数与Java函数值之间的映射关系,只需要多次call RegisterNatives()方法,并传入不同的映射表参数即可。
原文地址: http://blog.csdn.net/yzzst/article/details/47834077