Files
YukiHookAPI/assets/reflection.html-BZdJSVZS.js
github-actions[bot] aac9e42e84 Deploy to GitHub pages
2025-08-02 18:17:09 +00:00

823 lines
239 KiB
JavaScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import{_ as c,r as e,o as t,c as r,b as s,d as n,e as a,a as o}from"./app-BpUB8-Q8.js";const i={},d=s("h1",{id:"字节码与反射扩展-已迁移",tabindex:"-1"},[s("a",{class:"header-anchor",href:"#字节码与反射扩展-已迁移","aria-hidden":"true"},"#"),n(" 字节码与反射扩展 (已迁移)")],-1),A=s("blockquote",null,[s("p",null,[s("code",null,"YukiHookAPI"),n(" 为开发者封装了一套接近零反射写法的反射 API它几乎可以完全取代原生 Java 的反射 API 相关用法。")])],-1),y={href:"https://github.com/HighCapable/YukiReflection",target:"_blank",rel:"noopener noreferrer"},D=o("<p><s>现在 <code>YukiReflection</code> 作为核心依赖集成于 <code>YukiHookAPI</code>。</s></p><p><s><code>YukiHookAPI</code> 在 <code>YukiReflection</code> 的基础上加入了针对 Hook 功能的相关扩展,使用 <code>YukiHookAPI</code> 无需引入此依赖。</s></p>",2),B={class:"custom-container warning"},C=s("p",{class:"custom-container-title"},"注意",-1),u=s("code",null,"1.3.0",-1),v=s("code",null,"YukiHookAPI",-1),m={href:"https://github.com/HighCapable/KavaRef",target:"_blank",rel:"noopener noreferrer"},b=s("code",null,"YukiHookAPI",-1),F=s("p",null,[s("code",null,"YukiReflection"),n(" 项目由于很多未能解决的黑盒问题已被弃用,我们不再推荐任何人使用它。")],-1),k=s("code",null,"YukiHookAPI",-1),h={href:"https://highcapable.github.io/KavaRef/zh-cn/config/migration",target:"_blank",rel:"noopener noreferrer"},g=s("code",null,"KavaRef",-1),q={style:{opacity:"0.35"}},T=o(`<h2 id="class-扩展" tabindex="-1"><a class="header-anchor" href="#class-扩展" aria-hidden="true">#</a> Class 扩展</h2><blockquote><p>这里是 <strong>Class</strong> 对象自身相关的扩展功能。</p></blockquote><h3 id="对象转换" tabindex="-1"><a class="header-anchor" href="#对象转换" aria-hidden="true">#</a> 对象转换</h3><p>假设我们要得到一个不能直接调用的 <code>Class</code>,通常情况下,我们可以使用标准的反射 API 去查找这个 <code>Class</code>。</p><blockquote><p>示例如下</p></blockquote><div class="language-kotlin line-numbers-mode" data-ext="kt"><pre class="shiki github-dark-dimmed" style="background-color:#22272e;" tabindex="0"><code><span class="line"><span style="color:#768390;">// 默认 ClassLoader 环境下的 Class</span></span>
<span class="line"><span style="color:#F47067;">var</span><span style="color:#ADBAC7;"> instance </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> Class.</span><span style="color:#DCBDFB;">forName</span><span style="color:#ADBAC7;">(</span><span style="color:#96D0FF;">&quot;com.demo.Test&quot;</span><span style="color:#ADBAC7;">)</span></span>
<span class="line"><span style="color:#768390;">// 指定 ClassLoader 环境下的 Class</span></span>
<span class="line"><span style="color:#F47067;">val</span><span style="color:#ADBAC7;"> customClassLoader: </span><span style="color:#F69D50;">ClassLoader</span><span style="color:#ADBAC7;">? </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> </span><span style="color:#F47067;">..</span><span style="color:#ADBAC7;">. </span><span style="color:#768390;">// 假设这个就是你的 ClassLoader</span></span>
<span class="line"><span style="color:#F47067;">var</span><span style="color:#ADBAC7;"> instance </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> customClassLoader?.</span><span style="color:#DCBDFB;">loadClass</span><span style="color:#ADBAC7;">(</span><span style="color:#96D0FF;">&quot;com.demo.Test&quot;</span><span style="color:#ADBAC7;">)</span></span>
<span class="line"></span></code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p>这种写法大概不是很友好,此时 <code>YukiHookAPI</code> 就为你提供了一个可在任意地方使用的语法糖。</p><p>以上写法换做 <code>YukiHookAPI</code> 可写作如下形式。</p><blockquote><p>示例如下</p></blockquote><div class="language-kotlin line-numbers-mode" data-ext="kt"><pre class="shiki github-dark-dimmed" style="background-color:#22272e;" tabindex="0"><code><span class="line"><span style="color:#768390;">// 直接得到这个 Class</span></span>
<span class="line"><span style="color:#768390;">// 如果当前正处于 PackageParam 环境,那么你可以不需要考虑 ClassLoader</span></span>
<span class="line"><span style="color:#F47067;">var</span><span style="color:#ADBAC7;"> instance </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> </span><span style="color:#96D0FF;">&quot;com.demo.Test&quot;</span><span style="color:#ADBAC7;">.</span><span style="color:#DCBDFB;">toClass</span><span style="color:#ADBAC7;">()</span></span>
<span class="line"><span style="color:#768390;">// 自定义 Class 所在的 ClassLoader</span></span>
<span class="line"><span style="color:#F47067;">val</span><span style="color:#ADBAC7;"> customClassLoader: </span><span style="color:#F69D50;">ClassLoader</span><span style="color:#ADBAC7;">? </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> </span><span style="color:#F47067;">..</span><span style="color:#ADBAC7;">. </span><span style="color:#768390;">// 假设这个就是你的 ClassLoader</span></span>
<span class="line"><span style="color:#F47067;">var</span><span style="color:#ADBAC7;"> instance </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> </span><span style="color:#96D0FF;">&quot;com.demo.Test&quot;</span><span style="color:#ADBAC7;">.</span><span style="color:#DCBDFB;">toClass</span><span style="color:#ADBAC7;">(customClassLoader)</span></span>
<span class="line"></span></code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p>如果当前 <code>Class</code> 并不存在,使用上述方法会抛出异常,如果你不确定 <code>Class</code> 是否存在,可以参考下面的解决方案。</p><blockquote><p>示例如下</p></blockquote><div class="language-kotlin line-numbers-mode" data-ext="kt"><pre class="shiki github-dark-dimmed" style="background-color:#22272e;" tabindex="0"><code><span class="line"><span style="color:#768390;">// 直接得到这个 Class</span></span>
<span class="line"><span style="color:#768390;">// 如果当前正处于 PackageParam 环境,那么你可以不需要考虑 ClassLoader</span></span>
<span class="line"><span style="color:#768390;">// 得不到时结果会为 null 但不会抛出异常</span></span>
<span class="line"><span style="color:#F47067;">var</span><span style="color:#ADBAC7;"> instance </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> </span><span style="color:#96D0FF;">&quot;com.demo.Test&quot;</span><span style="color:#ADBAC7;">.</span><span style="color:#DCBDFB;">toClassOrNull</span><span style="color:#ADBAC7;">()</span></span>
<span class="line"><span style="color:#768390;">// 自定义 Class 所在的 ClassLoader</span></span>
<span class="line"><span style="color:#F47067;">val</span><span style="color:#ADBAC7;"> customClassLoader: </span><span style="color:#F69D50;">ClassLoader</span><span style="color:#ADBAC7;">? </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> </span><span style="color:#F47067;">..</span><span style="color:#ADBAC7;">. </span><span style="color:#768390;">// 假设这个就是你的 ClassLoader</span></span>
<span class="line"><span style="color:#768390;">// 得不到时结果会为 null 但不会抛出异常</span></span>
<span class="line"><span style="color:#F47067;">var</span><span style="color:#ADBAC7;"> instance </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> </span><span style="color:#96D0FF;">&quot;com.demo.Test&quot;</span><span style="color:#ADBAC7;">.</span><span style="color:#DCBDFB;">toClassOrNull</span><span style="color:#ADBAC7;">(customClassLoader)</span></span>
<span class="line"></span></code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p>我们还可以通过映射来得到一个存在的 <code>Class</code> 对象。</p><blockquote><p>示例如下</p></blockquote><div class="language-kotlin line-numbers-mode" data-ext="kt"><pre class="shiki github-dark-dimmed" style="background-color:#22272e;" tabindex="0"><code><span class="line"><span style="color:#768390;">// 假设这个 Class 是能够被直接得到的</span></span>
<span class="line"><span style="color:#F47067;">var</span><span style="color:#ADBAC7;"> instance </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> </span><span style="color:#DCBDFB;">classOf</span><span style="color:#ADBAC7;">&lt;</span><span style="color:#F69D50;">Test</span><span style="color:#ADBAC7;">&gt;()</span></span>
<span class="line"><span style="color:#768390;">// 我们同样可以自定义 Class 所在的 ClassLoader这对于 stub 来说非常有效</span></span>
<span class="line"><span style="color:#F47067;">val</span><span style="color:#ADBAC7;"> customClassLoader: </span><span style="color:#F69D50;">ClassLoader</span><span style="color:#ADBAC7;">? </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> </span><span style="color:#F47067;">..</span><span style="color:#ADBAC7;">. </span><span style="color:#768390;">// 假设这个就是你的 ClassLoader</span></span>
<span class="line"><span style="color:#F47067;">var</span><span style="color:#ADBAC7;"> instance </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> </span><span style="color:#DCBDFB;">classOf</span><span style="color:#ADBAC7;">&lt;</span><span style="color:#F69D50;">Test</span><span style="color:#ADBAC7;">&gt;(customClassLoader)</span></span>
<span class="line"></span></code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><div class="custom-container tip"><p class="custom-container-title">小提示</p><p>更多功能请参考 <a href="../public/com/highcapable/yukihookapi/hook/factory/ReflectionFactory#classof-method">classOf</a>、<a href="../public/com/highcapable/yukihookapi/hook/factory/ReflectionFactory#string-toclass-ext-method">String.toClass</a>、<a href="../public/com/highcapable/yukihookapi/hook/factory/ReflectionFactory#string-toclassornull-ext-method">String.toClassOrNull</a>、<a href="../public/com/highcapable/yukihookapi/hook/param/PackageParam#string-variousclass-toclass-i-ext-method">PackageParam → String+VariousClass.toClass</a>、<a href="../public/com/highcapable/yukihookapi/hook/param/PackageParam#string-variousclass-toclassornull-i-ext-method">PackageParam → String+VariousClass.toClassOrNull</a> 方法。</p></div><h3 id="延迟装载" tabindex="-1"><a class="header-anchor" href="#延迟装载" aria-hidden="true">#</a> 延迟装载</h3><p>假设我们要得到一个不能直接调用的 <code>Class</code>,但是我们也不是立刻就需要这个 <code>Class</code>。</p><p>这个时候,你可以使用 <code>lazyClass</code> 来完成这个功能。</p><blockquote><p>示例如下</p></blockquote><div class="language-kotlin line-numbers-mode" data-ext="kt"><pre class="shiki github-dark-dimmed" style="background-color:#22272e;" tabindex="0"><code><span class="line"><span style="color:#768390;">// 延迟装载这个 Class</span></span>
<span class="line"><span style="color:#768390;">// 如果当前正处于 PackageParam 环境,那么你可以不需要考虑 ClassLoader</span></span>
<span class="line"><span style="color:#F47067;">val</span><span style="color:#ADBAC7;"> instance </span><span style="color:#F47067;">by</span><span style="color:#ADBAC7;"> </span><span style="color:#DCBDFB;">lazyClass</span><span style="color:#ADBAC7;">(</span><span style="color:#96D0FF;">&quot;com.demo.Test&quot;</span><span style="color:#ADBAC7;">)</span></span>
<span class="line"><span style="color:#768390;">// 自定义 Class 所在的 ClassLoader</span></span>
<span class="line"><span style="color:#F47067;">val</span><span style="color:#ADBAC7;"> customClassLoader: </span><span style="color:#F69D50;">ClassLoader</span><span style="color:#ADBAC7;">? </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> </span><span style="color:#F47067;">..</span><span style="color:#ADBAC7;">. </span><span style="color:#768390;">// 假设这个就是你的 ClassLoader</span></span>
<span class="line"><span style="color:#F47067;">val</span><span style="color:#ADBAC7;"> instance </span><span style="color:#F47067;">by</span><span style="color:#ADBAC7;"> </span><span style="color:#DCBDFB;">lazyClass</span><span style="color:#ADBAC7;">(</span><span style="color:#96D0FF;">&quot;com.demo.Test&quot;</span><span style="color:#ADBAC7;">) { customClassLoader }</span></span>
<span class="line"><span style="color:#768390;">// 在适当的时候调用这个 Class</span></span>
<span class="line"><span style="color:#ADBAC7;">instance.</span><span style="color:#DCBDFB;">method</span><span style="color:#ADBAC7;"> { </span></span>
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#768390;">// ... </span></span>
<span class="line"><span style="color:#ADBAC7;">}</span></span>
<span class="line"></span></code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p>如果当前 <code>Class</code> 并不存在,使用上述方法会抛出异常,如果你不确定 <code>Class</code> 是否存在,可以参考下面的解决方案。</p><blockquote><p>示例如下</p></blockquote><div class="language-kotlin line-numbers-mode" data-ext="kt"><pre class="shiki github-dark-dimmed" style="background-color:#22272e;" tabindex="0"><code><span class="line"><span style="color:#768390;">// 延迟装载这个 Class</span></span>
<span class="line"><span style="color:#768390;">// 如果当前正处于 PackageParam 环境,那么你可以不需要考虑 ClassLoader</span></span>
<span class="line"><span style="color:#768390;">// 得不到时结果会为 null 但不会抛出异常</span></span>
<span class="line"><span style="color:#F47067;">val</span><span style="color:#ADBAC7;"> instance </span><span style="color:#F47067;">by</span><span style="color:#ADBAC7;"> </span><span style="color:#DCBDFB;">lazyClassOrNull</span><span style="color:#ADBAC7;">(</span><span style="color:#96D0FF;">&quot;com.demo.Test&quot;</span><span style="color:#ADBAC7;">)</span></span>
<span class="line"><span style="color:#768390;">// 自定义 Class 所在的 ClassLoader</span></span>
<span class="line"><span style="color:#F47067;">val</span><span style="color:#ADBAC7;"> customClassLoader: </span><span style="color:#F69D50;">ClassLoader</span><span style="color:#ADBAC7;">? </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> </span><span style="color:#F47067;">..</span><span style="color:#ADBAC7;">. </span><span style="color:#768390;">// 假设这个就是你的 ClassLoader</span></span>
<span class="line"><span style="color:#768390;">// 得不到时结果会为 null 但不会抛出异常</span></span>
<span class="line"><span style="color:#F47067;">val</span><span style="color:#ADBAC7;"> instance </span><span style="color:#F47067;">by</span><span style="color:#ADBAC7;"> </span><span style="color:#DCBDFB;">lazyClassOrNull</span><span style="color:#ADBAC7;">(</span><span style="color:#96D0FF;">&quot;com.demo.Test&quot;</span><span style="color:#ADBAC7;">) { customClassLoader }</span></span>
<span class="line"><span style="color:#768390;">// 在适当的时候调用这个 Class</span></span>
<span class="line"><span style="color:#ADBAC7;">instance?.</span><span style="color:#DCBDFB;">method</span><span style="color:#ADBAC7;"> { </span></span>
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#768390;">// ... </span></span>
<span class="line"><span style="color:#ADBAC7;">}</span></span>
<span class="line"></span></code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><div class="custom-container tip"><p class="custom-container-title">小提示</p><p>更多功能请参考 <a href="../public/com/highcapable/yukihookapi/hook/factory/ReflectionFactory#lazyclass-method">lazyClass</a>、<a href="../public/com/highcapable/yukihookapi/hook/factory/ReflectionFactory#lazyclassornull-method">lazyClassOrNull</a>、<a href="../public/com/highcapable/yukihookapi/hook/param/PackageParam#lazyclass-method">PackageParam → lazyClass</a>、<a href="../public/com/highcapable/yukihookapi/hook/param/PackageParam#lazyclassornull-method">PackageParam → lazyClassOrNull</a> 方法。</p></div><h3 id="存在判断" tabindex="-1"><a class="header-anchor" href="#存在判断" aria-hidden="true">#</a> 存在判断</h3><p>假设我们要判断一个 <code>Class</code> 是否存在,通常情况下,我们可以使用标准的反射 API 去查找这个 <code>Class</code> 通过异常来判断是否存在。</p><blockquote><p>示例如下</p></blockquote><div class="language-kotlin line-numbers-mode" data-ext="kt"><pre class="shiki github-dark-dimmed" style="background-color:#22272e;" tabindex="0"><code><span class="line"><span style="color:#768390;">// 默认 ClassLoader 环境下的 Class</span></span>
<span class="line"><span style="color:#F47067;">var</span><span style="color:#ADBAC7;"> isExist </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> </span><span style="color:#F47067;">try</span><span style="color:#ADBAC7;"> {</span></span>
<span class="line"><span style="color:#ADBAC7;"> Class.</span><span style="color:#DCBDFB;">forName</span><span style="color:#ADBAC7;">(</span><span style="color:#96D0FF;">&quot;com.demo.Test&quot;</span><span style="color:#ADBAC7;">)</span></span>
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#6CB6FF;">true</span></span>
<span class="line"><span style="color:#ADBAC7;">} </span><span style="color:#F47067;">catch</span><span style="color:#ADBAC7;"> (_: </span><span style="color:#F69D50;">Throwable</span><span style="color:#ADBAC7;">) {</span></span>
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#6CB6FF;">false</span></span>
<span class="line"><span style="color:#ADBAC7;">}</span></span>
<span class="line"><span style="color:#768390;">// 指定 ClassLoader 环境下的 Class</span></span>
<span class="line"><span style="color:#F47067;">val</span><span style="color:#ADBAC7;"> customClassLoader: </span><span style="color:#F69D50;">ClassLoader</span><span style="color:#ADBAC7;">? </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> </span><span style="color:#F47067;">..</span><span style="color:#ADBAC7;">. </span><span style="color:#768390;">// 假设这个就是你的 ClassLoader</span></span>
<span class="line"><span style="color:#F47067;">var</span><span style="color:#ADBAC7;"> isExist </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> </span><span style="color:#F47067;">try</span><span style="color:#ADBAC7;"> {</span></span>
<span class="line"><span style="color:#ADBAC7;"> customClassLoader?.</span><span style="color:#DCBDFB;">loadClass</span><span style="color:#ADBAC7;">(</span><span style="color:#96D0FF;">&quot;com.demo.Test&quot;</span><span style="color:#ADBAC7;">)</span></span>
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#6CB6FF;">true</span></span>
<span class="line"><span style="color:#ADBAC7;">} </span><span style="color:#F47067;">catch</span><span style="color:#ADBAC7;"> (_: </span><span style="color:#F69D50;">Throwable</span><span style="color:#ADBAC7;">) {</span></span>
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#6CB6FF;">false</span></span>
<span class="line"><span style="color:#ADBAC7;">}</span></span>
<span class="line"></span></code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p>这种写法大概不是很友好,此时 <code>YukiHookAPI</code> 就为你提供了一个可在任意地方使用的语法糖。</p><p>以上写法换做 <code>YukiHookAPI</code> 可写作如下形式。</p><blockquote><p>示例如下</p></blockquote><div class="language-kotlin line-numbers-mode" data-ext="kt"><pre class="shiki github-dark-dimmed" style="background-color:#22272e;" tabindex="0"><code><span class="line"><span style="color:#768390;">// 判断这个 Class 是否存在</span></span>
<span class="line"><span style="color:#768390;">// 如果当前正处于 PackageParam 环境,那么你可以不需要考虑 ClassLoader</span></span>
<span class="line"><span style="color:#F47067;">var</span><span style="color:#ADBAC7;"> isExist </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> </span><span style="color:#96D0FF;">&quot;com.demo.Test&quot;</span><span style="color:#ADBAC7;">.</span><span style="color:#DCBDFB;">hasClass</span><span style="color:#ADBAC7;">()</span></span>
<span class="line"><span style="color:#768390;">// 自定义 Class 所在的 ClassLoader</span></span>
<span class="line"><span style="color:#F47067;">val</span><span style="color:#ADBAC7;"> customClassLoader: </span><span style="color:#F69D50;">ClassLoader</span><span style="color:#ADBAC7;">? </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> </span><span style="color:#F47067;">..</span><span style="color:#ADBAC7;">. </span><span style="color:#768390;">// 假设这个就是你的 ClassLoader</span></span>
<span class="line"><span style="color:#F47067;">var</span><span style="color:#ADBAC7;"> isExist </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> </span><span style="color:#96D0FF;">&quot;com.demo.Test&quot;</span><span style="color:#ADBAC7;">.</span><span style="color:#DCBDFB;">hasClass</span><span style="color:#ADBAC7;">(customClassLoader)</span></span>
<span class="line"></span></code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><div class="custom-container tip"><p class="custom-container-title">小提示</p><p>更多功能请参考 <a href="../public/com/highcapable/yukihookapi/hook/factory/ReflectionFactory#string-hasclass-ext-method">String.hasClass</a>、<a href="../public/com/highcapable/yukihookapi/hook/param/PackageParam#string-hasclass-i-ext-method">PackageParam → String.hasClass</a> 方法。</p></div>`,35),x={id:"模糊查找",tabindex:"-1"},f=s("a",{class:"header-anchor",href:"#模糊查找","aria-hidden":"true"},"#",-1),P=o('<p>在 R8 等工具混淆后的宿主 <strong>Dex</strong> 中的 <code>Class</code> 名称将会难以分辨,且不确定其正确位置,不能直接通过 <a href="#%E5%AF%B9%E8%B1%A1%E8%BD%AC%E6%8D%A2">对象转换</a> 来得到。</p><p>此时就有了 <code>DexClassFinder</code>,它的作用是通过需要查找的 <code>Class</code> 中的字节码特征来确定这个 <code>Class</code> 的实例。</p><div class="custom-container warning"><p class="custom-container-title">注意</p><p>目前 <strong>DexClassFinder</strong> 的功能尚在实验阶段,由于仅通过 Java 层实现查找功能,在宿主 <strong>Class</strong> 过多时性能可能不能达到最佳水平,如果发生查找不到、定位有误的问题欢迎向我们反馈。</p><p>由于是反射层面的 API目前它只能通过<strong>类与成员</strong>的特征来定位指定的 <strong>Class</strong>,不能通过指定字节码中的字符串和方法内容特征来进行定位。</p><p>查找 <strong>Class</strong> 的速度取决于当前设备的性能,目前主流的移动端处理器在 <strong>10~15w</strong> 数量的 <strong>Class</strong> 中条件不算复杂的情况下大概在 <strong>3~10s</strong> 区间,条件稍微复杂的情况下最快速度能达到 <strong>25s</strong> 以内,匹配到的同类型 <strong>Class</strong> 越多速度越慢。</p></div>',3),S={class:"custom-container danger"},_=s("p",{class:"custom-container-title"},"特别注意",-1),j=s("strong",null,"YukiHookAPI",-1),I=s("strong",null,"2.0.0",-1),L={href:"https://github.com/HighCapable/YukiReflection",target:"_blank",rel:"noopener noreferrer"},H={href:"https://github.com/LuckyPray/DexKit",target:"_blank",rel:"noopener noreferrer"},R=s("strong",null,"Dex",-1),Y=o(`<h4 id="开始使用" tabindex="-1"><a class="header-anchor" href="#开始使用" aria-hidden="true">#</a> 开始使用</h4><p>下面是一个简单的用法示例。</p><p>假设下面这个 <code>Class</code> 是我们想要得到的,其中的名称经过了混淆,在每个版本可能都不一样。</p><blockquote><p>示例如下</p></blockquote><div class="language-java" data-ext="java"><pre class="shiki github-dark-dimmed" style="background-color:#22272e;" tabindex="0"><code><span class="line"><span style="color:#F47067;">package</span><span style="color:#ADBAC7;"> com.demo;</span></span>
<span class="line"></span>
<span class="line"><span style="color:#F47067;">public</span><span style="color:#ADBAC7;"> </span><span style="color:#F47067;">class</span><span style="color:#ADBAC7;"> </span><span style="color:#F69D50;">a</span><span style="color:#ADBAC7;"> </span><span style="color:#F47067;">extends</span><span style="color:#ADBAC7;"> </span><span style="color:#6CB6FF;">Activity</span><span style="color:#ADBAC7;"> </span><span style="color:#F47067;">implements</span><span style="color:#ADBAC7;"> </span><span style="color:#6CB6FF;">Serializable</span><span style="color:#ADBAC7;"> {</span></span>
<span class="line"></span>
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#F47067;">public</span><span style="color:#ADBAC7;"> </span><span style="color:#DCBDFB;">a</span><span style="color:#ADBAC7;">(String </span><span style="color:#F69D50;">var1</span><span style="color:#ADBAC7;">) {</span></span>
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#768390;">// ...</span></span>
<span class="line"><span style="color:#ADBAC7;"> }</span></span>
<span class="line"></span>
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#F47067;">private</span><span style="color:#ADBAC7;"> String</span><span style="color:#F69D50;"> </span><span style="color:#ADBAC7;">a;</span></span>
<span class="line"></span>
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#F47067;">private</span><span style="color:#ADBAC7;"> String</span><span style="color:#F69D50;"> </span><span style="color:#ADBAC7;">b;</span></span>
<span class="line"></span>
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#F47067;">private</span><span style="color:#ADBAC7;"> </span><span style="color:#F47067;">boolean</span><span style="color:#F69D50;"> </span><span style="color:#ADBAC7;">a;</span></span>
<span class="line"></span>
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#F47067;">protected</span><span style="color:#ADBAC7;"> </span><span style="color:#F47067;">void</span><span style="color:#ADBAC7;"> </span><span style="color:#DCBDFB;">onCreate</span><span style="color:#ADBAC7;">(Bundle </span><span style="color:#F69D50;">var1</span><span style="color:#ADBAC7;">) {</span></span>
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#768390;">// ...</span></span>
<span class="line"><span style="color:#ADBAC7;"> }</span></span>
<span class="line"></span>
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#F47067;">private</span><span style="color:#ADBAC7;"> </span><span style="color:#F47067;">static</span><span style="color:#ADBAC7;"> </span><span style="color:#F47067;">void</span><span style="color:#ADBAC7;"> </span><span style="color:#DCBDFB;">a</span><span style="color:#ADBAC7;">(String </span><span style="color:#F69D50;">var1</span><span style="color:#ADBAC7;">) {</span></span>
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#768390;">// ...</span></span>
<span class="line"><span style="color:#ADBAC7;"> }</span></span>
<span class="line"></span>
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#F47067;">private</span><span style="color:#ADBAC7;"> String </span><span style="color:#DCBDFB;">a</span><span style="color:#ADBAC7;">(</span><span style="color:#F47067;">boolean</span><span style="color:#ADBAC7;"> </span><span style="color:#F69D50;">var1</span><span style="color:#ADBAC7;">, String </span><span style="color:#F69D50;">var2</span><span style="color:#ADBAC7;">) {</span></span>
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#768390;">// ...</span></span>
<span class="line"><span style="color:#ADBAC7;"> }</span></span>
<span class="line"></span>
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#F47067;">private</span><span style="color:#ADBAC7;"> </span><span style="color:#F47067;">void</span><span style="color:#ADBAC7;"> </span><span style="color:#DCBDFB;">a</span><span style="color:#ADBAC7;">() {</span></span>
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#768390;">// ...</span></span>
<span class="line"><span style="color:#ADBAC7;"> }</span></span>
<span class="line"></span>
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#F47067;">public</span><span style="color:#ADBAC7;"> </span><span style="color:#F47067;">void</span><span style="color:#ADBAC7;"> </span><span style="color:#DCBDFB;">a</span><span style="color:#ADBAC7;">(</span><span style="color:#F47067;">boolean</span><span style="color:#ADBAC7;"> </span><span style="color:#F69D50;">var1</span><span style="color:#ADBAC7;">, </span><span style="color:#F69D50;">a</span><span style="color:#ADBAC7;"> </span><span style="color:#F69D50;">var2</span><span style="color:#ADBAC7;">, </span><span style="color:#F69D50;">b</span><span style="color:#ADBAC7;"> </span><span style="color:#F69D50;">var3</span><span style="color:#ADBAC7;">, String </span><span style="color:#F69D50;">var4</span><span style="color:#ADBAC7;">) {</span></span>
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#768390;">// ...</span></span>
<span class="line"><span style="color:#ADBAC7;"> }</span></span>
<span class="line"><span style="color:#ADBAC7;">}</span></span>
<span class="line"></span></code></pre></div><p>此时,我们想得到这个 <code>Class</code>,可以直接使用 <code>ClassLoader.searchClass</code> 方法。</p><p>在 <code>PackageParam</code> 中,你可以直接使用 <code>searchClass</code> 方法,它将自动指定 <code>appClassLoader</code>。</p><p>下方演示的条件中每一个都是可选的,条件越复杂定位越精确,同时性能也会越差。</p><blockquote><p>示例如下</p></blockquote><div class="language-kotlin line-numbers-mode" data-ext="kt"><pre class="shiki github-dark-dimmed" style="background-color:#22272e;" tabindex="0"><code><span class="line"><span style="color:#DCBDFB;">searchClass</span><span style="color:#ADBAC7;"> {</span></span>
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#768390;">// 从指定的包名范围开始查找,实际使用时,你可以同时指定多个包名范围</span></span>
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#DCBDFB;">from</span><span style="color:#ADBAC7;">(</span><span style="color:#96D0FF;">&quot;com.demo&quot;</span><span style="color:#ADBAC7;">)</span></span>
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#768390;">// 指定当前 Class 的 getSimpleName 的结果,你可以直接对这个字符串进行逻辑判断</span></span>
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#768390;">// 这里我们不确定它的名称是不是 a可以只判断字符串长度</span></span>
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#DCBDFB;">simpleName</span><span style="color:#ADBAC7;"> { it.length </span><span style="color:#F47067;">==</span><span style="color:#ADBAC7;"> </span><span style="color:#6CB6FF;">1</span><span style="color:#ADBAC7;"> }</span></span>
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#768390;">// 指定继承的父类对象,如果是存在的 stub可以直接用泛型表示</span></span>
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#DCBDFB;">extends</span><span style="color:#ADBAC7;">&lt;</span><span style="color:#F69D50;">Activity</span><span style="color:#ADBAC7;">&gt;()</span></span>
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#768390;">// 指定继承的父类对象,可以直接写为完整类名,你还可以同时指定多个</span></span>
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#DCBDFB;">extends</span><span style="color:#ADBAC7;">(</span><span style="color:#96D0FF;">&quot;android.app.Activity&quot;</span><span style="color:#ADBAC7;">)</span></span>
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#768390;">// 指定实现的接口,如果是存在的 stub可以直接用泛型表示</span></span>
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#DCBDFB;">implements</span><span style="color:#ADBAC7;">&lt;</span><span style="color:#F69D50;">Serializable</span><span style="color:#ADBAC7;">&gt;()</span></span>
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#768390;">// 指定实现的接口,可以直接写为完整类名,你还可以同时指定多个</span></span>
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#DCBDFB;">implements</span><span style="color:#ADBAC7;">(</span><span style="color:#96D0FF;">&quot;java.io.Serializable&quot;</span><span style="color:#ADBAC7;">)</span></span>
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#768390;">// 指定构造方法的类型与样式,以及在当前类中存在的个数 count</span></span>
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#DCBDFB;">constructor</span><span style="color:#ADBAC7;"> { </span><span style="color:#DCBDFB;">param</span><span style="color:#ADBAC7;">(StringClass) }.</span><span style="color:#DCBDFB;">count</span><span style="color:#ADBAC7;">(num </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> </span><span style="color:#6CB6FF;">1</span><span style="color:#ADBAC7;">)</span></span>
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#768390;">// 指定变量的类型与样式,以及在当前类中存在的个数 count</span></span>
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#F47067;">field</span><span style="color:#ADBAC7;"> { type </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> StringClass }.</span><span style="color:#DCBDFB;">count</span><span style="color:#ADBAC7;">(num </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> </span><span style="color:#6CB6FF;">2</span><span style="color:#ADBAC7;">)</span></span>
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#768390;">// 指定变量的类型与样式,以及在当前类中存在的个数 count</span></span>
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#F47067;">field</span><span style="color:#ADBAC7;"> { type </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> BooleanType }.</span><span style="color:#DCBDFB;">count</span><span style="color:#ADBAC7;">(num </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> </span><span style="color:#6CB6FF;">1</span><span style="color:#ADBAC7;">)</span></span>
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#768390;">// 直接指定所有变量在当前类中存在的个数 count</span></span>
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#F47067;">field</span><span style="color:#ADBAC7;">().</span><span style="color:#DCBDFB;">count</span><span style="color:#ADBAC7;">(num </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> </span><span style="color:#6CB6FF;">3</span><span style="color:#ADBAC7;">)</span></span>
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#768390;">// 如果你认为变量的个数是不确定的,还可以使用如下自定义条件</span></span>
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#F47067;">field</span><span style="color:#ADBAC7;">().</span><span style="color:#DCBDFB;">count</span><span style="color:#ADBAC7;">(</span><span style="color:#6CB6FF;">1</span><span style="color:#F47067;">..</span><span style="color:#6CB6FF;">3</span><span style="color:#ADBAC7;">)</span></span>
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#F47067;">field</span><span style="color:#ADBAC7;">().</span><span style="color:#DCBDFB;">count</span><span style="color:#ADBAC7;"> { it </span><span style="color:#F47067;">&gt;=</span><span style="color:#ADBAC7;"> </span><span style="color:#6CB6FF;">3</span><span style="color:#ADBAC7;"> }</span></span>
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#768390;">// 指定方法的类型与样式,以及在当前类中存在的个数 count</span></span>
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#DCBDFB;">method</span><span style="color:#ADBAC7;"> {</span></span>
<span class="line"><span style="color:#ADBAC7;"> name </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> </span><span style="color:#96D0FF;">&quot;onCreate&quot;</span></span>
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#DCBDFB;">param</span><span style="color:#ADBAC7;">(BundleClass)</span></span>
<span class="line"><span style="color:#ADBAC7;"> }.</span><span style="color:#DCBDFB;">count</span><span style="color:#ADBAC7;">(num </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> </span><span style="color:#6CB6FF;">1</span><span style="color:#ADBAC7;">)</span></span>
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#768390;">// 指定方法的类型与样式,同时指定修饰符,以及在当前类中存在的个数 count</span></span>
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#DCBDFB;">method</span><span style="color:#ADBAC7;"> {</span></span>
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#DCBDFB;">modifiers</span><span style="color:#ADBAC7;"> { isStatic </span><span style="color:#F47067;">&amp;&amp;</span><span style="color:#ADBAC7;"> isPrivate }</span></span>
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#DCBDFB;">param</span><span style="color:#ADBAC7;">(StringClass)</span></span>
<span class="line"><span style="color:#ADBAC7;"> returnType </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> UnitType</span></span>
<span class="line"><span style="color:#ADBAC7;"> }.</span><span style="color:#DCBDFB;">count</span><span style="color:#ADBAC7;">(num </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> </span><span style="color:#6CB6FF;">1</span><span style="color:#ADBAC7;">)</span></span>
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#768390;">// 指定方法的类型与样式,同时指定修饰符,以及在当前类中存在的个数 count</span></span>
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#DCBDFB;">method</span><span style="color:#ADBAC7;"> {</span></span>
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#DCBDFB;">modifiers</span><span style="color:#ADBAC7;"> { isPrivate </span><span style="color:#F47067;">&amp;&amp;</span><span style="color:#ADBAC7;"> isStatic.</span><span style="color:#DCBDFB;">not</span><span style="color:#ADBAC7;">() }</span></span>
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#DCBDFB;">param</span><span style="color:#ADBAC7;">(BooleanType, StringClass)</span></span>
<span class="line"><span style="color:#ADBAC7;"> returnType </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> StringClass</span></span>
<span class="line"><span style="color:#ADBAC7;"> }.</span><span style="color:#DCBDFB;">count</span><span style="color:#ADBAC7;">(num </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> </span><span style="color:#6CB6FF;">1</span><span style="color:#ADBAC7;">)</span></span>
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#768390;">// 指定方法的类型与样式,同时指定修饰符,以及在当前类中存在的个数 count</span></span>
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#DCBDFB;">method</span><span style="color:#ADBAC7;"> {</span></span>
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#DCBDFB;">modifiers</span><span style="color:#ADBAC7;"> { isPrivate </span><span style="color:#F47067;">&amp;&amp;</span><span style="color:#ADBAC7;"> isStatic.</span><span style="color:#DCBDFB;">not</span><span style="color:#ADBAC7;">() }</span></span>
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#DCBDFB;">emptyParam</span><span style="color:#ADBAC7;">()</span></span>
<span class="line"><span style="color:#ADBAC7;"> returnType </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> UnitType</span></span>
<span class="line"><span style="color:#ADBAC7;"> }.</span><span style="color:#DCBDFB;">count</span><span style="color:#ADBAC7;">(num </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> </span><span style="color:#6CB6FF;">1</span><span style="color:#ADBAC7;">)</span></span>
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#768390;">// 指定方法的类型与样式,同时指定修饰符和模糊类型 VagueType以及在当前类中存在的个数 count</span></span>
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#DCBDFB;">method</span><span style="color:#ADBAC7;"> {</span></span>
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#DCBDFB;">modifiers</span><span style="color:#ADBAC7;"> { isPrivate </span><span style="color:#F47067;">&amp;&amp;</span><span style="color:#ADBAC7;"> isStatic.</span><span style="color:#DCBDFB;">not</span><span style="color:#ADBAC7;">() }</span></span>
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#DCBDFB;">param</span><span style="color:#ADBAC7;">(BooleanType, VagueType, VagueType, StringClass)</span></span>
<span class="line"><span style="color:#ADBAC7;"> returnType </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> UnitType</span></span>
<span class="line"><span style="color:#ADBAC7;"> }.</span><span style="color:#DCBDFB;">count</span><span style="color:#ADBAC7;">(num </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> </span><span style="color:#6CB6FF;">1</span><span style="color:#ADBAC7;">)</span></span>
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#768390;">// 直接指定所有方法在当前类中存在的个数 count</span></span>
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#DCBDFB;">method</span><span style="color:#ADBAC7;">().</span><span style="color:#DCBDFB;">count</span><span style="color:#ADBAC7;">(num </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> </span><span style="color:#6CB6FF;">5</span><span style="color:#ADBAC7;">)</span></span>
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#768390;">// 如果你认为方法的个数是不确定的,还可以使用如下自定义条件</span></span>
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#DCBDFB;">method</span><span style="color:#ADBAC7;">().</span><span style="color:#DCBDFB;">count</span><span style="color:#ADBAC7;">(</span><span style="color:#6CB6FF;">1</span><span style="color:#F47067;">..</span><span style="color:#6CB6FF;">5</span><span style="color:#ADBAC7;">)</span></span>
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#DCBDFB;">method</span><span style="color:#ADBAC7;">().</span><span style="color:#DCBDFB;">count</span><span style="color:#ADBAC7;"> { it </span><span style="color:#F47067;">&gt;=</span><span style="color:#ADBAC7;"> </span><span style="color:#6CB6FF;">5</span><span style="color:#ADBAC7;"> }</span></span>
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#768390;">// 直接指定所有成员 (Member) 在当前类中存在的个数 count</span></span>
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#768390;">// 成员包括Field (变量)、Method (方法)、Constructor (构造方法)</span></span>
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#DCBDFB;">member</span><span style="color:#ADBAC7;">().</span><span style="color:#DCBDFB;">count</span><span style="color:#ADBAC7;">(num </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> </span><span style="color:#6CB6FF;">9</span><span style="color:#ADBAC7;">)</span></span>
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#768390;">// 所有成员中一定存在一个 static 修饰符,可以这样加入此条件</span></span>
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#DCBDFB;">member</span><span style="color:#ADBAC7;"> {</span></span>
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#DCBDFB;">modifiers</span><span style="color:#ADBAC7;"> { isStatic }</span></span>
<span class="line"><span style="color:#ADBAC7;"> }</span></span>
<span class="line"><span style="color:#ADBAC7;">}.</span><span style="color:#DCBDFB;">get</span><span style="color:#ADBAC7;">() </span><span style="color:#768390;">// 得到这个 Class 本身的实例,找不到会返回 null</span></span>
<span class="line"></span></code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><div class="custom-container tip"><p class="custom-container-title">小提示</p><p>上述用法中对于 <strong>Field</strong>、<strong>Method</strong>、<strong>Constructor</strong> 的条件用法与 <a href="#member-%E6%89%A9%E5%B1%95">Member 扩展</a> 中的相关用法是一致的,仅有小部分区别。</p><p>更多功能请参考 <a href="../public/com/highcapable/yukihookapi/hook/core/finder/classes/rules/MemberRules">MemberRules</a>、<a href="../public/com/highcapable/yukihookapi/hook/core/finder/classes/rules/FieldRules">FieldRules</a>、<a href="../public/com/highcapable/yukihookapi/hook/core/finder/classes/rules/MethodRules">MethodRules</a>、<a href="../public/com/highcapable/yukihookapi/hook/core/finder/classes/rules/ConstructorRules">ConstructorRules</a>。</p></div><h4 id="异步查找" tabindex="-1"><a class="header-anchor" href="#异步查找" aria-hidden="true">#</a> 异步查找</h4><p>默认情况下 <code>DexClassFinder</code> 会使用同步方式查找 <code>Class</code>,会阻塞当前线程直到找到或找不到发生异常为止,若查找消耗的时间过长,可能会导致宿主发生 <strong>ANR</strong> 问题。</p><p>针对上述问题,我们可以启用异步,只需要加入参数 <code>async = true</code>这将不需要你再次启动一个线程API 已帮你处理好相关问题。</p><div class="custom-container warning"><p class="custom-container-title">注意</p><p>对于异步情况下你需要使用 <strong>wait</strong> 方法来得到结果,<strong>get</strong> 方法将不再起作用。</p></div><blockquote><p>示例如下</p></blockquote><div class="language-kotlin line-numbers-mode" data-ext="kt"><pre class="shiki github-dark-dimmed" style="background-color:#22272e;" tabindex="0"><code><span class="line"><span style="color:#DCBDFB;">searchClass</span><span style="color:#ADBAC7;">(async </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> </span><span style="color:#6CB6FF;">true</span><span style="color:#ADBAC7;">) {</span></span>
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#768390;">// ...</span></span>
<span class="line"><span style="color:#ADBAC7;">}.</span><span style="color:#DCBDFB;">wait</span><span style="color:#ADBAC7;"> { class1 </span><span style="color:#F47067;">-&gt;</span></span>
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#768390;">// 得到异步结果</span></span>
<span class="line"><span style="color:#ADBAC7;">}</span></span>
<span class="line"><span style="color:#DCBDFB;">searchClass</span><span style="color:#ADBAC7;">(async </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> </span><span style="color:#6CB6FF;">true</span><span style="color:#ADBAC7;">) {</span></span>
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#768390;">// ...</span></span>
<span class="line"><span style="color:#ADBAC7;">}.</span><span style="color:#DCBDFB;">wait</span><span style="color:#ADBAC7;"> { class2 </span><span style="color:#F47067;">-&gt;</span></span>
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#768390;">// 得到异步结果</span></span>
<span class="line"><span style="color:#ADBAC7;">}</span></span>
<span class="line"></span></code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p>这样我们的查找过程就是异步运行了,它将不会阻塞主线程,每个查找都将在单独的线程同时进行,可达到并行任务的效果。</p><h4 id="本地缓存" tabindex="-1"><a class="header-anchor" href="#本地缓存" aria-hidden="true">#</a> 本地缓存</h4><p>由于每次重新打开宿主都会重新进行查找,在宿主版本不变的情况下这是一种重复性能浪费。</p><p>此时我们可以通过指定 <code>name</code> 参数来对当前宿主版本的查找结果进行本地缓存,下一次将直接从本地缓存中读取查找到的类名。</p><p>本地缓存使用的是 <code>SharedPreferences</code>,它将被保存到宿主的数据目录中,在宿主版本更新后会重新进行缓存。</p><p>启用本地缓存后,将同时设置 <code>async = true</code>,你可以不需要再手动进行设置。</p><blockquote><p>示例如下</p></blockquote><div class="language-kotlin line-numbers-mode" data-ext="kt"><pre class="shiki github-dark-dimmed" style="background-color:#22272e;" tabindex="0"><code><span class="line"><span style="color:#DCBDFB;">searchClass</span><span style="color:#ADBAC7;">(name </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> </span><span style="color:#96D0FF;">&quot;com.demo.class1&quot;</span><span style="color:#ADBAC7;">) {</span></span>
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#768390;">// ...</span></span>
<span class="line"><span style="color:#ADBAC7;">}.</span><span style="color:#DCBDFB;">wait</span><span style="color:#ADBAC7;"> { class1 </span><span style="color:#F47067;">-&gt;</span></span>
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#768390;">// 得到异步结果</span></span>
<span class="line"><span style="color:#ADBAC7;">}</span></span>
<span class="line"><span style="color:#DCBDFB;">searchClass</span><span style="color:#ADBAC7;">(name </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> </span><span style="color:#96D0FF;">&quot;com.demo.class2&quot;</span><span style="color:#ADBAC7;">) {</span></span>
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#768390;">// ...</span></span>
<span class="line"><span style="color:#ADBAC7;">}.</span><span style="color:#DCBDFB;">wait</span><span style="color:#ADBAC7;"> { class2 </span><span style="color:#F47067;">-&gt;</span></span>
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#768390;">// 得到异步结果</span></span>
<span class="line"><span style="color:#ADBAC7;">}</span></span>
<span class="line"></span></code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p>如果你想手动清除本地缓存,可以使用如下方法清除当前版本的宿主缓存。</p><blockquote><p>示例如下</p></blockquote><div class="language-kotlin line-numbers-mode" data-ext="kt"><pre class="shiki github-dark-dimmed" style="background-color:#22272e;" tabindex="0"><code><span class="line"><span style="color:#768390;">// 直接调用,在宿主的 appContext 为空时可能会失败,失败会打印警告信息</span></span>
<span class="line"><span style="color:#ADBAC7;">DexClassFinder.</span><span style="color:#DCBDFB;">clearCache</span><span style="color:#ADBAC7;">()</span></span>
<span class="line"><span style="color:#768390;">// 监听宿主的生命周期后调用</span></span>
<span class="line"><span style="color:#DCBDFB;">onAppLifecycle</span><span style="color:#ADBAC7;"> {</span></span>
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#DCBDFB;">onCreate</span><span style="color:#ADBAC7;"> {</span></span>
<span class="line"><span style="color:#ADBAC7;"> DexClassFinder.</span><span style="color:#DCBDFB;">clearCache</span><span style="color:#ADBAC7;">(context </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> </span><span style="color:#6CB6FF;">this</span><span style="color:#ADBAC7;">)</span></span>
<span class="line"><span style="color:#ADBAC7;"> }</span></span>
<span class="line"><span style="color:#ADBAC7;">}</span></span>
<span class="line"></span></code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p>你还可以清除指定版本的宿主缓存。</p><blockquote><p>示例如下</p></blockquote><div class="language-kotlin line-numbers-mode" data-ext="kt"><pre class="shiki github-dark-dimmed" style="background-color:#22272e;" tabindex="0"><code><span class="line"><span style="color:#768390;">// 直接调用,在宿主的 appContext 为空时可能会失败,失败会打印警告信息</span></span>
<span class="line"><span style="color:#ADBAC7;">DexClassFinder.</span><span style="color:#DCBDFB;">clearCache</span><span style="color:#ADBAC7;">(versionName </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> </span><span style="color:#96D0FF;">&quot;1.0&quot;</span><span style="color:#ADBAC7;">, versionCode </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> </span><span style="color:#6CB6FF;">1</span><span style="color:#ADBAC7;">)</span></span>
<span class="line"><span style="color:#768390;">// 监听宿主的生命周期后调用</span></span>
<span class="line"><span style="color:#DCBDFB;">onAppLifecycle</span><span style="color:#ADBAC7;"> {</span></span>
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#DCBDFB;">onCreate</span><span style="color:#ADBAC7;"> {</span></span>
<span class="line"><span style="color:#ADBAC7;"> DexClassFinder.</span><span style="color:#DCBDFB;">clearCache</span><span style="color:#ADBAC7;">(context </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> </span><span style="color:#6CB6FF;">this</span><span style="color:#ADBAC7;">, versionName </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> </span><span style="color:#96D0FF;">&quot;1.0&quot;</span><span style="color:#ADBAC7;">, versionCode </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> </span><span style="color:#6CB6FF;">1</span><span style="color:#ADBAC7;">)</span></span>
<span class="line"><span style="color:#ADBAC7;"> }</span></span>
<span class="line"><span style="color:#ADBAC7;">}</span></span>
<span class="line"></span></code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><h4 id="多重查找" tabindex="-1"><a class="header-anchor" href="#多重查找" aria-hidden="true">#</a> 多重查找</h4><p>如果你需要使用固定的条件同时查找一组 <code>Class</code>,那么你只需要使用 <code>all</code> 或 <code>waitAll</code> 方法来得到结果。</p><div class="language-kotlin line-numbers-mode" data-ext="kt"><pre class="shiki github-dark-dimmed" style="background-color:#22272e;" tabindex="0"><code><span class="line"><span style="color:#768390;">// 同步查找,使用 all 得到条件全部查找到的结果</span></span>
<span class="line"><span style="color:#DCBDFB;">searchClass</span><span style="color:#ADBAC7;"> {</span></span>
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#768390;">// ...</span></span>
<span class="line"><span style="color:#ADBAC7;">}.</span><span style="color:#DCBDFB;">all</span><span style="color:#ADBAC7;">().</span><span style="color:#DCBDFB;">forEach</span><span style="color:#ADBAC7;"> { clazz </span><span style="color:#F47067;">-&gt;</span></span>
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#768390;">// 得到每个结果</span></span>
<span class="line"><span style="color:#ADBAC7;">}</span></span>
<span class="line"><span style="color:#768390;">// 同步查找,使用 all { ... } 遍历每个结果</span></span>
<span class="line"><span style="color:#DCBDFB;">searchClass</span><span style="color:#ADBAC7;"> {</span></span>
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#768390;">// ...</span></span>
<span class="line"><span style="color:#ADBAC7;">}.</span><span style="color:#DCBDFB;">all</span><span style="color:#ADBAC7;"> { clazz </span><span style="color:#F47067;">-&gt;</span></span>
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#768390;">// 得到每个结果</span></span>
<span class="line"><span style="color:#ADBAC7;">}</span></span>
<span class="line"><span style="color:#768390;">// 异步查找,使用 waitAll 得到条件全部查找到的结果</span></span>
<span class="line"><span style="color:#DCBDFB;">searchClass</span><span style="color:#ADBAC7;">(async </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> </span><span style="color:#6CB6FF;">true</span><span style="color:#ADBAC7;">) {</span></span>
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#768390;">// ...</span></span>
<span class="line"><span style="color:#ADBAC7;">}.</span><span style="color:#DCBDFB;">waitAll</span><span style="color:#ADBAC7;"> { classes </span><span style="color:#F47067;">-&gt;</span></span>
<span class="line"><span style="color:#ADBAC7;"> classes.</span><span style="color:#DCBDFB;">forEach</span><span style="color:#ADBAC7;"> {</span></span>
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#768390;">// 得到每个结果</span></span>
<span class="line"><span style="color:#ADBAC7;"> }</span></span>
<span class="line"><span style="color:#ADBAC7;">}</span></span>
<span class="line"></span></code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><div class="custom-container tip"><p class="custom-container-title">小提示</p><p>更多功能请参考 <a href="../public/com/highcapable/yukihookapi/hook/factory/ReflectionFactory#classloader-searchclass-ext-method">ClassLoader.searchClass</a>、<a href="../public/com/highcapable/yukihookapi/hook/param/PackageParam#searchclass-method">PackageParam.searchClass</a> 方法。</p></div><h2 id="member-扩展" tabindex="-1"><a class="header-anchor" href="#member-扩展" aria-hidden="true">#</a> Member 扩展</h2><blockquote><p>这里是 <strong>Class</strong> 字节码成员变量 <strong>Field</strong>、<strong>Method</strong>、<strong>Constructor</strong> 相关的扩展功能。</p></blockquote><div class="custom-container tip"><p class="custom-container-title">小提示</p><p><strong>Member</strong> 是 <strong>Field</strong>、<strong>Method</strong>、<strong>Constructor</strong> 的接口描述对象,它在 Java 反射中为 <strong>Class</strong> 中字节码成员的总称。</p></div><p>假设有一个这样的 <code>Class</code>。</p><blockquote><p>示例如下</p></blockquote><div class="language-java" data-ext="java"><pre class="shiki github-dark-dimmed" style="background-color:#22272e;" tabindex="0"><code><span class="line"><span style="color:#F47067;">package</span><span style="color:#ADBAC7;"> com.demo;</span></span>
<span class="line"></span>
<span class="line"><span style="color:#F47067;">public</span><span style="color:#ADBAC7;"> </span><span style="color:#F47067;">class</span><span style="color:#ADBAC7;"> </span><span style="color:#F69D50;">BaseTest</span><span style="color:#ADBAC7;"> {</span></span>
<span class="line"></span>
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#F47067;">public</span><span style="color:#ADBAC7;"> </span><span style="color:#DCBDFB;">BaseTest</span><span style="color:#ADBAC7;">() {</span></span>
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#768390;">// ...</span></span>
<span class="line"><span style="color:#ADBAC7;"> }</span></span>
<span class="line"></span>
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#F47067;">public</span><span style="color:#ADBAC7;"> </span><span style="color:#DCBDFB;">BaseTest</span><span style="color:#ADBAC7;">(</span><span style="color:#F47067;">boolean</span><span style="color:#ADBAC7;"> </span><span style="color:#F69D50;">isInit</span><span style="color:#ADBAC7;">) {</span></span>
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#768390;">// ...</span></span>
<span class="line"><span style="color:#ADBAC7;"> }</span></span>
<span class="line"></span>
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#F47067;">private</span><span style="color:#ADBAC7;"> </span><span style="color:#F47067;">void</span><span style="color:#ADBAC7;"> </span><span style="color:#DCBDFB;">doBaseTask</span><span style="color:#ADBAC7;">(String </span><span style="color:#F69D50;">taskName</span><span style="color:#ADBAC7;">) {</span></span>
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#768390;">// ...</span></span>
<span class="line"><span style="color:#ADBAC7;"> }</span></span>
<span class="line"><span style="color:#ADBAC7;">}</span></span>
<span class="line"></span></code></pre></div><div class="language-java" data-ext="java"><pre class="shiki github-dark-dimmed" style="background-color:#22272e;" tabindex="0"><code><span class="line"><span style="color:#F47067;">package</span><span style="color:#ADBAC7;"> com.demo;</span></span>
<span class="line"></span>
<span class="line"><span style="color:#F47067;">public</span><span style="color:#ADBAC7;"> </span><span style="color:#F47067;">class</span><span style="color:#ADBAC7;"> </span><span style="color:#F69D50;">Test</span><span style="color:#ADBAC7;"> </span><span style="color:#F47067;">extends</span><span style="color:#ADBAC7;"> </span><span style="color:#6CB6FF;">BaseTest</span><span style="color:#ADBAC7;"> {</span></span>
<span class="line"></span>
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#F47067;">public</span><span style="color:#ADBAC7;"> </span><span style="color:#DCBDFB;">Test</span><span style="color:#ADBAC7;">() {</span></span>
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#768390;">// ...</span></span>
<span class="line"><span style="color:#ADBAC7;"> }</span></span>
<span class="line"></span>
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#F47067;">public</span><span style="color:#ADBAC7;"> </span><span style="color:#DCBDFB;">Test</span><span style="color:#ADBAC7;">(</span><span style="color:#F47067;">boolean</span><span style="color:#ADBAC7;"> </span><span style="color:#F69D50;">isInit</span><span style="color:#ADBAC7;">) {</span></span>
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#768390;">// ...</span></span>
<span class="line"><span style="color:#ADBAC7;"> }</span></span>
<span class="line"></span>
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#F47067;">private</span><span style="color:#ADBAC7;"> </span><span style="color:#F47067;">static</span><span style="color:#ADBAC7;"> TAG </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> </span><span style="color:#96D0FF;">&quot;Test&quot;</span><span style="color:#ADBAC7;">;</span></span>
<span class="line"></span>
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#F47067;">private</span><span style="color:#ADBAC7;"> BaseTest</span><span style="color:#F69D50;"> </span><span style="color:#ADBAC7;">baseInstance;</span></span>
<span class="line"></span>
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#F47067;">private</span><span style="color:#ADBAC7;"> String</span><span style="color:#F69D50;"> </span><span style="color:#ADBAC7;">a;</span></span>
<span class="line"></span>
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#F47067;">private</span><span style="color:#ADBAC7;"> </span><span style="color:#F47067;">boolean</span><span style="color:#F69D50;"> </span><span style="color:#ADBAC7;">a;</span></span>
<span class="line"></span>
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#F47067;">private</span><span style="color:#ADBAC7;"> </span><span style="color:#F47067;">boolean</span><span style="color:#F69D50;"> </span><span style="color:#ADBAC7;">isTaskRunning</span><span style="color:#F69D50;"> </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> </span><span style="color:#6CB6FF;">false</span><span style="color:#ADBAC7;">;</span></span>
<span class="line"></span>
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#F47067;">private</span><span style="color:#ADBAC7;"> </span><span style="color:#F47067;">static</span><span style="color:#ADBAC7;"> </span><span style="color:#F47067;">void</span><span style="color:#ADBAC7;"> </span><span style="color:#DCBDFB;">init</span><span style="color:#ADBAC7;">() {</span></span>
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#768390;">// ...</span></span>
<span class="line"><span style="color:#ADBAC7;"> }</span></span>
<span class="line"></span>
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#F47067;">private</span><span style="color:#ADBAC7;"> </span><span style="color:#F47067;">void</span><span style="color:#ADBAC7;"> </span><span style="color:#DCBDFB;">doTask</span><span style="color:#ADBAC7;">(String </span><span style="color:#F69D50;">taskName</span><span style="color:#ADBAC7;">) {</span></span>
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#768390;">// ...</span></span>
<span class="line"><span style="color:#ADBAC7;"> }</span></span>
<span class="line"></span>
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#F47067;">private</span><span style="color:#ADBAC7;"> </span><span style="color:#F47067;">void</span><span style="color:#ADBAC7;"> </span><span style="color:#DCBDFB;">release</span><span style="color:#ADBAC7;">(String </span><span style="color:#F69D50;">taskName</span><span style="color:#ADBAC7;">, Function&lt;</span><span style="color:#F47067;">boolean</span><span style="color:#ADBAC7;">, </span><span style="color:#F47067;">String</span><span style="color:#ADBAC7;">&gt; </span><span style="color:#F69D50;">task</span><span style="color:#ADBAC7;">, </span><span style="color:#F47067;">boolean</span><span style="color:#ADBAC7;"> </span><span style="color:#F69D50;">isFinish</span><span style="color:#ADBAC7;">) {</span></span>
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#768390;">// ...</span></span>
<span class="line"><span style="color:#ADBAC7;"> }</span></span>
<span class="line"></span>
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#F47067;">private</span><span style="color:#ADBAC7;"> </span><span style="color:#F47067;">void</span><span style="color:#ADBAC7;"> </span><span style="color:#DCBDFB;">stop</span><span style="color:#ADBAC7;">() {</span></span>
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#768390;">// ...</span></span>
<span class="line"><span style="color:#ADBAC7;"> }</span></span>
<span class="line"></span>
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#F47067;">private</span><span style="color:#ADBAC7;"> String </span><span style="color:#DCBDFB;">getName</span><span style="color:#ADBAC7;">() {</span></span>
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#768390;">// ...</span></span>
<span class="line"><span style="color:#ADBAC7;"> }</span></span>
<span class="line"></span>
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#F47067;">private</span><span style="color:#ADBAC7;"> </span><span style="color:#F47067;">void</span><span style="color:#ADBAC7;"> </span><span style="color:#DCBDFB;">b</span><span style="color:#ADBAC7;">() {</span></span>
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#768390;">// ...</span></span>
<span class="line"><span style="color:#ADBAC7;"> }</span></span>
<span class="line"></span>
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#F47067;">private</span><span style="color:#ADBAC7;"> </span><span style="color:#F47067;">void</span><span style="color:#ADBAC7;"> </span><span style="color:#DCBDFB;">b</span><span style="color:#ADBAC7;">(String </span><span style="color:#F69D50;">a</span><span style="color:#ADBAC7;">) {</span></span>
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#768390;">// ...</span></span>
<span class="line"><span style="color:#ADBAC7;"> }</span></span>
<span class="line"><span style="color:#ADBAC7;">}</span></span>
<span class="line"></span></code></pre></div><h3 id="查找与反射调用" tabindex="-1"><a class="header-anchor" href="#查找与反射调用" aria-hidden="true">#</a> 查找与反射调用</h3><p>假设我们要得到 <code>Test</code>(以下统称“当前 <code>Class</code>”)的 <code>doTask</code> 方法并执行,通常情况下,我们可以使用标准的反射 API 去查找这个方法。</p><blockquote><p>示例如下</p></blockquote><div class="language-kotlin line-numbers-mode" data-ext="kt"><pre class="shiki github-dark-dimmed" style="background-color:#22272e;" tabindex="0"><code><span class="line"><span style="color:#768390;">// 假设这就是这个 Class 的实例</span></span>
<span class="line"><span style="color:#F47067;">val</span><span style="color:#ADBAC7;"> instance </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> </span><span style="color:#DCBDFB;">Test</span><span style="color:#ADBAC7;">()</span></span>
<span class="line"><span style="color:#768390;">// 使用反射 API 调用并执行</span></span>
<span class="line"><span style="color:#ADBAC7;">Test::</span><span style="color:#DCBDFB;">class</span><span style="color:#ADBAC7;">.java</span></span>
<span class="line"><span style="color:#ADBAC7;"> .</span><span style="color:#DCBDFB;">getDeclaredMethod</span><span style="color:#ADBAC7;">(</span><span style="color:#96D0FF;">&quot;doTask&quot;</span><span style="color:#ADBAC7;">, String::</span><span style="color:#DCBDFB;">class</span><span style="color:#ADBAC7;">.java)</span></span>
<span class="line"><span style="color:#ADBAC7;"> .</span><span style="color:#DCBDFB;">apply</span><span style="color:#ADBAC7;"> { isAccessible </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> </span><span style="color:#6CB6FF;">true</span><span style="color:#ADBAC7;"> }</span></span>
<span class="line"><span style="color:#ADBAC7;"> .</span><span style="color:#DCBDFB;">invoke</span><span style="color:#ADBAC7;">(instance, </span><span style="color:#96D0FF;">&quot;task_name&quot;</span><span style="color:#ADBAC7;">)</span></span>
<span class="line"></span></code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p>这种写法大概不是很友好,此时 <code>YukiHookAPI</code> 就为你提供了一个可在任意地方使用的语法糖。</p><p>以上写法换做 <code>YukiHookAPI</code> 可写作如下形式。</p><blockquote><p>示例如下</p></blockquote><div class="language-kotlin line-numbers-mode" data-ext="kt"><pre class="shiki github-dark-dimmed" style="background-color:#22272e;" tabindex="0"><code><span class="line"><span style="color:#768390;">// 假设这就是这个 Class 的实例</span></span>
<span class="line"><span style="color:#F47067;">val</span><span style="color:#ADBAC7;"> instance </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> </span><span style="color:#DCBDFB;">Test</span><span style="color:#ADBAC7;">()</span></span>
<span class="line"><span style="color:#768390;">// 使用 YukiHookAPI 调用并执行</span></span>
<span class="line"><span style="color:#ADBAC7;">Test::</span><span style="color:#DCBDFB;">class</span><span style="color:#ADBAC7;">.java.</span><span style="color:#DCBDFB;">method</span><span style="color:#ADBAC7;"> {</span></span>
<span class="line"><span style="color:#ADBAC7;"> name </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> </span><span style="color:#96D0FF;">&quot;doTask&quot;</span></span>
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#DCBDFB;">param</span><span style="color:#ADBAC7;">(StringClass)</span></span>
<span class="line"><span style="color:#ADBAC7;">}.</span><span style="color:#DCBDFB;">get</span><span style="color:#ADBAC7;">(instance).</span><span style="color:#DCBDFB;">call</span><span style="color:#ADBAC7;">(</span><span style="color:#96D0FF;">&quot;task_name&quot;</span><span style="color:#ADBAC7;">)</span></span>
<span class="line"></span></code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><div class="custom-container tip"><p class="custom-container-title">小提示</p><p>更多功能请参考 <a href="../public/com/highcapable/yukihookapi/hook/core/finder/members/MethodFinder">MethodFinder</a>。</p></div><p>同样地,我们需要得到 <code>isTaskRunning</code> 变量也可以写作如下形式。</p><blockquote><p>示例如下</p></blockquote><div class="language-kotlin line-numbers-mode" data-ext="kt"><pre class="shiki github-dark-dimmed" style="background-color:#22272e;" tabindex="0"><code><span class="line"><span style="color:#768390;">// 假设这就是这个 Class 的实例</span></span>
<span class="line"><span style="color:#F47067;">val</span><span style="color:#ADBAC7;"> instance </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> </span><span style="color:#DCBDFB;">Test</span><span style="color:#ADBAC7;">()</span></span>
<span class="line"><span style="color:#768390;">// 使用 YukiHookAPI 调用并执行</span></span>
<span class="line"><span style="color:#ADBAC7;">Test::</span><span style="color:#DCBDFB;">class</span><span style="color:#ADBAC7;">.java.</span><span style="color:#DCBDFB;">field</span><span style="color:#ADBAC7;"> {</span></span>
<span class="line"><span style="color:#ADBAC7;"> name </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> </span><span style="color:#96D0FF;">&quot;isTaskRunning&quot;</span></span>
<span class="line"><span style="color:#ADBAC7;"> type </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> BooleanType</span></span>
<span class="line"><span style="color:#ADBAC7;">}.</span><span style="color:#DCBDFB;">get</span><span style="color:#ADBAC7;">(instance).</span><span style="color:#DCBDFB;">any</span><span style="color:#ADBAC7;">() </span><span style="color:#768390;">// any 为 Field 的任意类型实例化对象</span></span>
<span class="line"></span></code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><div class="custom-container tip"><p class="custom-container-title">小提示</p><p>更多功能请参考 <a href="../public/com/highcapable/yukihookapi/hook/core/finder/members/FieldFinder">FieldFinder</a>。</p></div><p>也许你还想得到当前 <code>Class</code> 的构造方法,同样可以实现。</p><blockquote><p>示例如下</p></blockquote><div class="language-kotlin line-numbers-mode" data-ext="kt"><pre class="shiki github-dark-dimmed" style="background-color:#22272e;" tabindex="0"><code><span class="line"><span style="color:#ADBAC7;">Test::</span><span style="color:#DCBDFB;">class</span><span style="color:#ADBAC7;">.java.</span><span style="color:#DCBDFB;">constructor</span><span style="color:#ADBAC7;"> {</span></span>
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#DCBDFB;">param</span><span style="color:#ADBAC7;">(BooleanType)</span></span>
<span class="line"><span style="color:#ADBAC7;">}.</span><span style="color:#DCBDFB;">get</span><span style="color:#ADBAC7;">().</span><span style="color:#DCBDFB;">call</span><span style="color:#ADBAC7;">(</span><span style="color:#6CB6FF;">true</span><span style="color:#ADBAC7;">) </span><span style="color:#768390;">// 可创建一个新的实例</span></span>
<span class="line"></span></code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p>若想得到的是 <code>Class</code> 的无参构造方法,可写作如下形式。</p><blockquote><p>示例如下</p></blockquote><div class="language-kotlin line-numbers-mode" data-ext="kt"><pre class="shiki github-dark-dimmed" style="background-color:#22272e;" tabindex="0"><code><span class="line"><span style="color:#ADBAC7;">Test::</span><span style="color:#DCBDFB;">class</span><span style="color:#ADBAC7;">.java.</span><span style="color:#DCBDFB;">constructor</span><span style="color:#ADBAC7;">().</span><span style="color:#DCBDFB;">get</span><span style="color:#ADBAC7;">().</span><span style="color:#DCBDFB;">call</span><span style="color:#ADBAC7;">() </span><span style="color:#768390;">// 可创建一个新的实例</span></span>
<span class="line"></span></code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div></div></div><div class="custom-container tip"><p class="custom-container-title">小提示</p><p>更多功能请参考 <a href="../public/com/highcapable/yukihookapi/hook/core/finder/members/ConstructorFinder">ConstructorFinder</a>。</p></div><h3 id="可选的查找条件" tabindex="-1"><a class="header-anchor" href="#可选的查找条件" aria-hidden="true">#</a> 可选的查找条件</h3><p>假设我们要得到 <code>Class</code> 中的 <code>getName</code> 方法,可以使用如下实现。</p><blockquote><p>示例如下</p></blockquote><div class="language-kotlin line-numbers-mode" data-ext="kt"><pre class="shiki github-dark-dimmed" style="background-color:#22272e;" tabindex="0"><code><span class="line"><span style="color:#768390;">// 假设这就是这个 Class 的实例</span></span>
<span class="line"><span style="color:#F47067;">val</span><span style="color:#ADBAC7;"> instance </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> </span><span style="color:#DCBDFB;">Test</span><span style="color:#ADBAC7;">()</span></span>
<span class="line"><span style="color:#768390;">// 使用 YukiHookAPI 调用并执行</span></span>
<span class="line"><span style="color:#ADBAC7;">Test::</span><span style="color:#DCBDFB;">class</span><span style="color:#ADBAC7;">.java.</span><span style="color:#DCBDFB;">method</span><span style="color:#ADBAC7;"> {</span></span>
<span class="line"><span style="color:#ADBAC7;"> name </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> </span><span style="color:#96D0FF;">&quot;getName&quot;</span></span>
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#DCBDFB;">emptyParam</span><span style="color:#ADBAC7;">()</span></span>
<span class="line"><span style="color:#ADBAC7;"> returnType </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> StringClass</span></span>
<span class="line"><span style="color:#ADBAC7;">}.</span><span style="color:#DCBDFB;">get</span><span style="color:#ADBAC7;">(instance).</span><span style="color:#DCBDFB;">string</span><span style="color:#ADBAC7;">() </span><span style="color:#768390;">// 得到方法的结果</span></span>
<span class="line"></span></code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p>通过观察发现,这个 <code>Class</code> 中只有一个名为 <code>getName</code> 的方法,那我们可不可以再简单一点呢?</p><blockquote><p>示例如下</p></blockquote><div class="language-kotlin line-numbers-mode" data-ext="kt"><pre class="shiki github-dark-dimmed" style="background-color:#22272e;" tabindex="0"><code><span class="line"><span style="color:#768390;">// 假设这就是这个 Class 的实例</span></span>
<span class="line"><span style="color:#F47067;">val</span><span style="color:#ADBAC7;"> instance </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> </span><span style="color:#DCBDFB;">Test</span><span style="color:#ADBAC7;">()</span></span>
<span class="line"><span style="color:#768390;">// 使用 YukiHookAPI 调用并执行</span></span>
<span class="line"><span style="color:#ADBAC7;">Test::</span><span style="color:#DCBDFB;">class</span><span style="color:#ADBAC7;">.java.</span><span style="color:#DCBDFB;">method</span><span style="color:#ADBAC7;"> {</span></span>
<span class="line"><span style="color:#ADBAC7;"> name </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> </span><span style="color:#96D0FF;">&quot;getName&quot;</span></span>
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#DCBDFB;">emptyParam</span><span style="color:#ADBAC7;">()</span></span>
<span class="line"><span style="color:#ADBAC7;">}.</span><span style="color:#DCBDFB;">get</span><span style="color:#ADBAC7;">(instance).</span><span style="color:#DCBDFB;">string</span><span style="color:#ADBAC7;">() </span><span style="color:#768390;">// 得到方法的结果</span></span>
<span class="line"></span></code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p>是的,对于确切不会变化的方法,你可以精简查找条件。</p><p>在只使用 <code>get</code> 或 <code>wait</code> 方法得到结果时 <code>YukiHookAPI</code> <strong>会默认按照字节码顺序匹配第一个查找到的结果</strong>。</p><p>问题又来了,这个 <code>Class</code> 中有一个 <code>release</code> 方法,但是它的方法参数很长,而且部分类型可能无法直接得到。</p><p>通常情况下我们会使用 <code>param(...)</code> 来查找这个方法,但是有没有更简单的方法呢。</p><p>此时,在确定方法唯一性后,你可以使用 <code>paramCount</code> 来查找到这个方法。</p><blockquote><p>示例如下</p></blockquote><div class="language-kotlin line-numbers-mode" data-ext="kt"><pre class="shiki github-dark-dimmed" style="background-color:#22272e;" tabindex="0"><code><span class="line"><span style="color:#768390;">// 假设这就是这个 Class 的实例</span></span>
<span class="line"><span style="color:#F47067;">val</span><span style="color:#ADBAC7;"> instance </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> </span><span style="color:#DCBDFB;">Test</span><span style="color:#ADBAC7;">()</span></span>
<span class="line"><span style="color:#768390;">// 使用 YukiHookAPI 调用并执行</span></span>
<span class="line"><span style="color:#ADBAC7;">Test::</span><span style="color:#DCBDFB;">class</span><span style="color:#ADBAC7;">.java.</span><span style="color:#DCBDFB;">method</span><span style="color:#ADBAC7;"> {</span></span>
<span class="line"><span style="color:#ADBAC7;"> name </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> </span><span style="color:#96D0FF;">&quot;release&quot;</span></span>
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#768390;">// 此时我们不必确定方法参数具体类型,写个数就好</span></span>
<span class="line"><span style="color:#ADBAC7;"> paramCount </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> </span><span style="color:#6CB6FF;">3</span></span>
<span class="line"><span style="color:#ADBAC7;">}.</span><span style="color:#DCBDFB;">get</span><span style="color:#ADBAC7;">(instance) </span><span style="color:#768390;">// 得到这个方法</span></span>
<span class="line"></span></code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p>上述示例虽然能够匹配成功,但是不精确,此时你还可以使用 <code>VagueType</code> 来填充你不想填写的方法参数类型。</p><blockquote><p>示例如下</p></blockquote><div class="language-kotlin line-numbers-mode" data-ext="kt"><pre class="shiki github-dark-dimmed" style="background-color:#22272e;" tabindex="0"><code><span class="line"><span style="color:#768390;">// 假设这就是这个 Class 的实例</span></span>
<span class="line"><span style="color:#F47067;">val</span><span style="color:#ADBAC7;"> instance </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> </span><span style="color:#DCBDFB;">Test</span><span style="color:#ADBAC7;">()</span></span>
<span class="line"><span style="color:#768390;">// 使用 YukiHookAPI 调用并执行</span></span>
<span class="line"><span style="color:#ADBAC7;">Test::</span><span style="color:#DCBDFB;">class</span><span style="color:#ADBAC7;">.java.</span><span style="color:#DCBDFB;">method</span><span style="color:#ADBAC7;"> {</span></span>
<span class="line"><span style="color:#ADBAC7;"> name </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> </span><span style="color:#96D0FF;">&quot;release&quot;</span></span>
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#768390;">// 使用 VagueType 来填充不想填写的类型,同时保证其它类型能够匹配</span></span>
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#DCBDFB;">param</span><span style="color:#ADBAC7;">(StringClass, VagueType, BooleanType)</span></span>
<span class="line"><span style="color:#ADBAC7;">}.</span><span style="color:#DCBDFB;">get</span><span style="color:#ADBAC7;">(instance) </span><span style="color:#768390;">// 得到这个方法</span></span>
<span class="line"></span></code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p>如果你并不确定每一个参数的类型,你可以通过 <code>param { ... }</code> 方法来创建一个条件方法体。</p><blockquote><p>示例如下</p></blockquote><div class="language-kotlin line-numbers-mode" data-ext="kt"><pre class="shiki github-dark-dimmed" style="background-color:#22272e;" tabindex="0"><code><span class="line"><span style="color:#768390;">// 假设这就是这个 Class 的实例</span></span>
<span class="line"><span style="color:#F47067;">val</span><span style="color:#ADBAC7;"> instance </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> </span><span style="color:#DCBDFB;">Test</span><span style="color:#ADBAC7;">()</span></span>
<span class="line"><span style="color:#768390;">// 使用 YukiHookAPI 调用并执行</span></span>
<span class="line"><span style="color:#ADBAC7;">Test::</span><span style="color:#DCBDFB;">class</span><span style="color:#ADBAC7;">.java.</span><span style="color:#DCBDFB;">method</span><span style="color:#ADBAC7;"> {</span></span>
<span class="line"><span style="color:#ADBAC7;"> name </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> </span><span style="color:#96D0FF;">&quot;release&quot;</span></span>
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#768390;">// 得到 it (Class) 方法参数类型数组实例来仅判断已知的类型和它的位置</span></span>
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#DCBDFB;">param</span><span style="color:#ADBAC7;"> { it[</span><span style="color:#6CB6FF;">0</span><span style="color:#ADBAC7;">] </span><span style="color:#F47067;">==</span><span style="color:#ADBAC7;"> StringClass </span><span style="color:#F47067;">&amp;&amp;</span><span style="color:#ADBAC7;"> it[</span><span style="color:#6CB6FF;">2</span><span style="color:#ADBAC7;">] </span><span style="color:#F47067;">==</span><span style="color:#ADBAC7;"> BooleanType }</span></span>
<span class="line"><span style="color:#ADBAC7;">}.</span><span style="color:#DCBDFB;">get</span><span style="color:#ADBAC7;">(instance) </span><span style="color:#768390;">// 得到这个方法</span></span>
<span class="line"></span></code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><div class="custom-container tip"><p class="custom-container-title">小提示</p><p>使用 <strong>param { ... }</strong> 创建一个条件方法体,其中的变量 <strong>it</strong> 即当前方法参数的 <strong>Class</strong> 类型数组实例,此时你就可以自由使用 <strong>Class</strong> 中的所有对象及其方法。</p><p>方法体末尾条件需要返回一个 <strong>Boolean</strong>,即最终的条件判断结果。</p><p>更多功能请参考 <a href="../public/com/highcapable/yukihookapi/hook/core/finder/members/FieldFinder#type-method-1">FieldFinder.type</a>、<a href="../public/com/highcapable/yukihookapi/hook/core/finder/members/MethodFinder#param-method-1">MethodFinder.param</a>、<a href="../public/com/highcapable/yukihookapi/hook/core/finder/members/MethodFinder#returntype-method-1">MethodFinder.returnType</a>、<a href="../public/com/highcapable/yukihookapi/hook/core/finder/members/ConstructorFinder#param-method-1">ConstructorFinder.param</a> 方法。</p></div><h3 id="在父类查找" tabindex="-1"><a class="header-anchor" href="#在父类查找" aria-hidden="true">#</a> 在父类查找</h3><p>你会注意到 <code>Test</code> 继承于 <code>BaseTest</code>,现在我们想得到 <code>BaseTest</code> 的 <code>doBaseTask</code> 方法,在不知道父类名称的情况下,要怎么做呢?</p><p>参照上面的查找条件,我们只需要在查找条件中加入一个 <code>superClass</code> 即可实现这个功能。</p><blockquote><p>示例如下</p></blockquote><div class="language-kotlin line-numbers-mode" data-ext="kt"><pre class="shiki github-dark-dimmed" style="background-color:#22272e;" tabindex="0"><code><span class="line"><span style="color:#768390;">// 假设这就是这个 Class 的实例</span></span>
<span class="line"><span style="color:#F47067;">val</span><span style="color:#ADBAC7;"> instance </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> </span><span style="color:#DCBDFB;">Test</span><span style="color:#ADBAC7;">()</span></span>
<span class="line"><span style="color:#768390;">// 使用 YukiHookAPI 调用并执行</span></span>
<span class="line"><span style="color:#ADBAC7;">Test::</span><span style="color:#DCBDFB;">class</span><span style="color:#ADBAC7;">.java.</span><span style="color:#DCBDFB;">method</span><span style="color:#ADBAC7;"> {</span></span>
<span class="line"><span style="color:#ADBAC7;"> name </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> </span><span style="color:#96D0FF;">&quot;doBaseTask&quot;</span></span>
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#DCBDFB;">param</span><span style="color:#ADBAC7;">(StringClass)</span></span>
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#768390;">// 只需要添加这个条件</span></span>
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#DCBDFB;">superClass</span><span style="color:#ADBAC7;">()</span></span>
<span class="line"><span style="color:#ADBAC7;">}.</span><span style="color:#DCBDFB;">get</span><span style="color:#ADBAC7;">(instance).</span><span style="color:#DCBDFB;">call</span><span style="color:#ADBAC7;">(</span><span style="color:#96D0FF;">&quot;task_name&quot;</span><span style="color:#ADBAC7;">)</span></span>
<span class="line"></span></code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p>这个时候我们就可以在父类中取到这个方法了。</p><p><code>superClass</code> 有一个参数为 <code>isOnlySuperClass</code>,设置为 <code>true</code> 后,可以跳过当前 <code>Class</code> 仅查找当前 <code>Class</code> 的父类。</p><p>由于我们现在已知 <code>doBaseTask</code> 方法只存在于父类,可以加上这个条件节省查找时间。</p><blockquote><p>示例如下</p></blockquote><div class="language-kotlin line-numbers-mode" data-ext="kt"><pre class="shiki github-dark-dimmed" style="background-color:#22272e;" tabindex="0"><code><span class="line"><span style="color:#768390;">// 假设这就是这个 Class 的实例</span></span>
<span class="line"><span style="color:#F47067;">val</span><span style="color:#ADBAC7;"> instance </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> </span><span style="color:#DCBDFB;">Test</span><span style="color:#ADBAC7;">()</span></span>
<span class="line"><span style="color:#768390;">// 使用 YukiHookAPI 调用并执行</span></span>
<span class="line"><span style="color:#ADBAC7;">Test::</span><span style="color:#DCBDFB;">class</span><span style="color:#ADBAC7;">.java.</span><span style="color:#DCBDFB;">method</span><span style="color:#ADBAC7;"> {</span></span>
<span class="line"><span style="color:#ADBAC7;"> name </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> </span><span style="color:#96D0FF;">&quot;doBaseTask&quot;</span></span>
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#DCBDFB;">param</span><span style="color:#ADBAC7;">(StringClass)</span></span>
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#768390;">// 加入一个查找条件</span></span>
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#DCBDFB;">superClass</span><span style="color:#ADBAC7;">(isOnlySuperClass </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> </span><span style="color:#6CB6FF;">true</span><span style="color:#ADBAC7;">)</span></span>
<span class="line"><span style="color:#ADBAC7;">}.</span><span style="color:#DCBDFB;">get</span><span style="color:#ADBAC7;">(instance).</span><span style="color:#DCBDFB;">call</span><span style="color:#ADBAC7;">(</span><span style="color:#96D0FF;">&quot;task_name&quot;</span><span style="color:#ADBAC7;">)</span></span>
<span class="line"></span></code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p>这个时候我们同样可以得到父类中的这个方法。</p><p><code>superClass</code> 一旦设置就会自动循环向后查找全部继承的父类中是否有这个方法,直到查找到目标没有父类(继承关系为 <code>java.lang.Object</code>)为止。</p><div class="custom-container tip"><p class="custom-container-title">小提示</p><p>更多功能请参考 <a href="../public/com/highcapable/yukihookapi/hook/core/finder/members/MethodFinder#superclass-method">MethodFinder.superClass</a>、<a href="../public/com/highcapable/yukihookapi/hook/core/finder/members/ConstructorFinder#superclass-method">ConstructorFinder.superClass</a>、<a href="../public/com/highcapable/yukihookapi/hook/core/finder/members/FieldFinder#superclass-method">FieldFinder.superClass</a> 方法。</p></div><div class="custom-container danger"><p class="custom-container-title">特别注意</p><p>当前查找的 <strong>Method</strong> 除非指定 <strong>superClass</strong> 条件,否则只能查找到当前 <strong>Class</strong> 的 <strong>Method</strong>,这是 Java 反射 API 的默认行为。</p></div><h3 id="模糊查找-1" tabindex="-1"><a class="header-anchor" href="#模糊查找-1" aria-hidden="true">#</a> 模糊查找</h3><p>如果我们想查找一个方法名称,但是又不确定它在每个版本中是否发生变化,此时我们就可以使用模糊查找功能。</p><p>假设我们要得到 <code>Class</code> 中的 <code>doTask</code> 方法,可以使用如下实现。</p><blockquote><p>示例如下</p></blockquote><div class="language-kotlin line-numbers-mode" data-ext="kt"><pre class="shiki github-dark-dimmed" style="background-color:#22272e;" tabindex="0"><code><span class="line"><span style="color:#768390;">// 假设这就是这个 Class 的实例</span></span>
<span class="line"><span style="color:#F47067;">val</span><span style="color:#ADBAC7;"> instance </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> </span><span style="color:#DCBDFB;">Test</span><span style="color:#ADBAC7;">()</span></span>
<span class="line"><span style="color:#768390;">// 使用 YukiHookAPI 调用并执行</span></span>
<span class="line"><span style="color:#ADBAC7;">Test::</span><span style="color:#DCBDFB;">class</span><span style="color:#ADBAC7;">.java.</span><span style="color:#DCBDFB;">method</span><span style="color:#ADBAC7;"> {</span></span>
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#DCBDFB;">name</span><span style="color:#ADBAC7;"> {</span></span>
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#768390;">// 设置名称不区分大小写</span></span>
<span class="line"><span style="color:#ADBAC7;"> it.</span><span style="color:#DCBDFB;">equals</span><span style="color:#ADBAC7;">(</span><span style="color:#96D0FF;">&quot;dotask&quot;</span><span style="color:#ADBAC7;">, isIgnoreCase </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> </span><span style="color:#6CB6FF;">true</span><span style="color:#ADBAC7;">)</span></span>
<span class="line"><span style="color:#ADBAC7;"> }</span></span>
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#DCBDFB;">param</span><span style="color:#ADBAC7;">(StringClass)</span></span>
<span class="line"><span style="color:#ADBAC7;">}.</span><span style="color:#DCBDFB;">get</span><span style="color:#ADBAC7;">(instance).</span><span style="color:#DCBDFB;">call</span><span style="color:#ADBAC7;">(</span><span style="color:#96D0FF;">&quot;task_name&quot;</span><span style="color:#ADBAC7;">)</span></span>
<span class="line"></span></code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p>已知当前 <code>Class</code> 中仅有一个 <code>doTask</code> 方法,我们还可以判断方法名称仅包含其中指定的字符。</p><blockquote><p>示例如下</p></blockquote><div class="language-kotlin line-numbers-mode" data-ext="kt"><pre class="shiki github-dark-dimmed" style="background-color:#22272e;" tabindex="0"><code><span class="line"><span style="color:#768390;">// 假设这就是这个 Class 的实例</span></span>
<span class="line"><span style="color:#F47067;">val</span><span style="color:#ADBAC7;"> instance </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> </span><span style="color:#DCBDFB;">Test</span><span style="color:#ADBAC7;">()</span></span>
<span class="line"><span style="color:#768390;">// 使用 YukiHookAPI 调用并执行</span></span>
<span class="line"><span style="color:#ADBAC7;">Test::</span><span style="color:#DCBDFB;">class</span><span style="color:#ADBAC7;">.java.</span><span style="color:#DCBDFB;">method</span><span style="color:#ADBAC7;"> {</span></span>
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#DCBDFB;">name</span><span style="color:#ADBAC7;"> {</span></span>
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#768390;">// 仅包含 oTas</span></span>
<span class="line"><span style="color:#ADBAC7;"> it.</span><span style="color:#DCBDFB;">contains</span><span style="color:#ADBAC7;">(</span><span style="color:#96D0FF;">&quot;oTas&quot;</span><span style="color:#ADBAC7;">)</span></span>
<span class="line"><span style="color:#ADBAC7;"> }</span></span>
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#DCBDFB;">param</span><span style="color:#ADBAC7;">(StringClass)</span></span>
<span class="line"><span style="color:#ADBAC7;">}.</span><span style="color:#DCBDFB;">get</span><span style="color:#ADBAC7;">(instance).</span><span style="color:#DCBDFB;">call</span><span style="color:#ADBAC7;">(</span><span style="color:#96D0FF;">&quot;task_name&quot;</span><span style="color:#ADBAC7;">)</span></span>
<span class="line"></span></code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p>我们还可以根据首尾字符串进行判断。</p><blockquote><p>示例如下</p></blockquote><div class="language-kotlin line-numbers-mode" data-ext="kt"><pre class="shiki github-dark-dimmed" style="background-color:#22272e;" tabindex="0"><code><span class="line"><span style="color:#768390;">// 假设这就是这个 Class 的实例</span></span>
<span class="line"><span style="color:#F47067;">val</span><span style="color:#ADBAC7;"> instance </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> </span><span style="color:#DCBDFB;">Test</span><span style="color:#ADBAC7;">()</span></span>
<span class="line"><span style="color:#768390;">// 使用 YukiHookAPI 调用并执行</span></span>
<span class="line"><span style="color:#ADBAC7;">Test::</span><span style="color:#DCBDFB;">class</span><span style="color:#ADBAC7;">.java.</span><span style="color:#DCBDFB;">method</span><span style="color:#ADBAC7;"> {</span></span>
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#DCBDFB;">name</span><span style="color:#ADBAC7;"> {</span></span>
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#768390;">// 开头包含 do结尾包含 Task</span></span>
<span class="line"><span style="color:#ADBAC7;"> it.</span><span style="color:#DCBDFB;">startsWith</span><span style="color:#ADBAC7;">(</span><span style="color:#96D0FF;">&quot;do&quot;</span><span style="color:#ADBAC7;">) </span><span style="color:#F47067;">&amp;&amp;</span><span style="color:#ADBAC7;"> it.</span><span style="color:#DCBDFB;">endsWith</span><span style="color:#ADBAC7;">(</span><span style="color:#96D0FF;">&quot;Task&quot;</span><span style="color:#ADBAC7;">)</span></span>
<span class="line"><span style="color:#ADBAC7;"> }</span></span>
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#DCBDFB;">param</span><span style="color:#ADBAC7;">(StringClass)</span></span>
<span class="line"><span style="color:#ADBAC7;">}.</span><span style="color:#DCBDFB;">get</span><span style="color:#ADBAC7;">(instance).</span><span style="color:#DCBDFB;">call</span><span style="color:#ADBAC7;">(</span><span style="color:#96D0FF;">&quot;task_name&quot;</span><span style="color:#ADBAC7;">)</span></span>
<span class="line"></span></code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p>通过观察发现这个方法名称中只包含字母,我们还可以再增加一个精确的查找条件。</p><blockquote><p>示例如下</p></blockquote><div class="language-kotlin line-numbers-mode" data-ext="kt"><pre class="shiki github-dark-dimmed" style="background-color:#22272e;" tabindex="0"><code><span class="line"><span style="color:#768390;">// 假设这就是这个 Class 的实例</span></span>
<span class="line"><span style="color:#F47067;">val</span><span style="color:#ADBAC7;"> instance </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> </span><span style="color:#DCBDFB;">Test</span><span style="color:#ADBAC7;">()</span></span>
<span class="line"><span style="color:#768390;">// 使用 YukiHookAPI 调用并执行</span></span>
<span class="line"><span style="color:#ADBAC7;">Test::</span><span style="color:#DCBDFB;">class</span><span style="color:#ADBAC7;">.java.</span><span style="color:#DCBDFB;">method</span><span style="color:#ADBAC7;"> {</span></span>
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#DCBDFB;">name</span><span style="color:#ADBAC7;"> {</span></span>
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#768390;">// 开头包含 do结尾包含 Task仅包含字母</span></span>
<span class="line"><span style="color:#ADBAC7;"> it.</span><span style="color:#DCBDFB;">startsWith</span><span style="color:#ADBAC7;">(</span><span style="color:#96D0FF;">&quot;do&quot;</span><span style="color:#ADBAC7;">) </span><span style="color:#F47067;">&amp;&amp;</span><span style="color:#ADBAC7;"> it.</span><span style="color:#DCBDFB;">endsWith</span><span style="color:#ADBAC7;">(</span><span style="color:#96D0FF;">&quot;Task&quot;</span><span style="color:#ADBAC7;">) </span><span style="color:#F47067;">&amp;&amp;</span><span style="color:#ADBAC7;"> it.</span><span style="color:#DCBDFB;">isOnlyLetters</span><span style="color:#ADBAC7;">()</span></span>
<span class="line"><span style="color:#ADBAC7;"> }</span></span>
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#DCBDFB;">param</span><span style="color:#ADBAC7;">(StringClass)</span></span>
<span class="line"><span style="color:#ADBAC7;">}.</span><span style="color:#DCBDFB;">get</span><span style="color:#ADBAC7;">(instance).</span><span style="color:#DCBDFB;">call</span><span style="color:#ADBAC7;">(</span><span style="color:#96D0FF;">&quot;task_name&quot;</span><span style="color:#ADBAC7;">)</span></span>
<span class="line"></span></code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><div class="custom-container tip"><p class="custom-container-title">小提示</p><p>使用 <strong>name { ... }</strong> 创建一个条件方法体,其中的变量 <strong>it</strong> 即当前名称的字符串,此时你就可以在 <strong>NameRules</strong> 的扩展方法中自由使用其中的功能。</p><p>方法体末尾条件需要返回一个 <strong>Boolean</strong>,即最终的条件判断结果。</p><p>更多功能请参考 <a href="../public/com/highcapable/yukihookapi/hook/core/finder/members/FieldFinder#name-method-1">FieldFinder.name</a>、<a href="../public/com/highcapable/yukihookapi/hook/core/finder/members/MethodFinder#name-method-1">MethodFinder.name</a> 方法以及 <a href="../public/com/highcapable/yukihookapi/hook/core/finder/base/rules/NameRules">NameRules</a>。</p></div><h3 id="多重查找-1" tabindex="-1"><a class="header-anchor" href="#多重查找-1" aria-hidden="true">#</a> 多重查找</h3><p>有些时候,我们可能需要查找一个 <code>Class</code> 中具有相同特征的一组方法、构造方法、变量,此时,我们就可以利用相对条件匹配来完成。</p><p>在查找条件结果的基础上,我们只需要把 <code>get</code> 换为 <code>all</code> 即可得到匹配条件的全部字节码。</p><p>假设这次我们要得到 <code>Class</code> 中方法参数个数范围在 <code>1..3</code> 的全部方法,可以使用如下实现。</p><blockquote><p>示例如下</p></blockquote><div class="language-kotlin line-numbers-mode" data-ext="kt"><pre class="shiki github-dark-dimmed" style="background-color:#22272e;" tabindex="0"><code><span class="line"><span style="color:#768390;">// 假设这就是这个 Class 的实例</span></span>
<span class="line"><span style="color:#F47067;">val</span><span style="color:#ADBAC7;"> instance </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> </span><span style="color:#DCBDFB;">Test</span><span style="color:#ADBAC7;">()</span></span>
<span class="line"><span style="color:#768390;">// 使用 YukiHookAPI 调用并执行</span></span>
<span class="line"><span style="color:#ADBAC7;">Test::</span><span style="color:#DCBDFB;">class</span><span style="color:#ADBAC7;">.java.</span><span style="color:#DCBDFB;">method</span><span style="color:#ADBAC7;"> {</span></span>
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#DCBDFB;">paramCount</span><span style="color:#ADBAC7;">(</span><span style="color:#6CB6FF;">1</span><span style="color:#F47067;">..</span><span style="color:#6CB6FF;">3</span><span style="color:#ADBAC7;">)</span></span>
<span class="line"><span style="color:#ADBAC7;">}.</span><span style="color:#DCBDFB;">all</span><span style="color:#ADBAC7;">(instance).</span><span style="color:#DCBDFB;">forEach</span><span style="color:#ADBAC7;"> { instance </span><span style="color:#F47067;">-&gt;</span></span>
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#768390;">// 调用执行每个方法</span></span>
<span class="line"><span style="color:#ADBAC7;"> instance.</span><span style="color:#DCBDFB;">call</span><span style="color:#ADBAC7;">(</span><span style="color:#F47067;">..</span><span style="color:#ADBAC7;">.)</span></span>
<span class="line"><span style="color:#ADBAC7;">}</span></span>
<span class="line"></span></code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p>上述示例可完美匹配到如下 3 个方法。</p><p><code>private void doTask(String taskName)</code></p><p><code>private void release(String taskName, Function&lt;boolean, String&gt; task, boolean isFinish)</code></p><p><code>private void b(String a)</code></p><p>如果你想更加自由地定义参数个数范围的条件,可以使用如下实现。</p><blockquote><p>示例如下</p></blockquote><div class="language-kotlin line-numbers-mode" data-ext="kt"><pre class="shiki github-dark-dimmed" style="background-color:#22272e;" tabindex="0"><code><span class="line"><span style="color:#768390;">// 假设这就是这个 Class 的实例</span></span>
<span class="line"><span style="color:#F47067;">val</span><span style="color:#ADBAC7;"> instance </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> </span><span style="color:#DCBDFB;">Test</span><span style="color:#ADBAC7;">()</span></span>
<span class="line"><span style="color:#768390;">// 使用 YukiHookAPI 调用并执行</span></span>
<span class="line"><span style="color:#ADBAC7;">Test::</span><span style="color:#DCBDFB;">class</span><span style="color:#ADBAC7;">.java.</span><span style="color:#DCBDFB;">method</span><span style="color:#ADBAC7;"> {</span></span>
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#DCBDFB;">paramCount</span><span style="color:#ADBAC7;"> { it </span><span style="color:#F47067;">&lt;</span><span style="color:#ADBAC7;"> </span><span style="color:#6CB6FF;">3</span><span style="color:#ADBAC7;"> }</span></span>
<span class="line"><span style="color:#ADBAC7;">}.</span><span style="color:#DCBDFB;">all</span><span style="color:#ADBAC7;">(instance).</span><span style="color:#DCBDFB;">forEach</span><span style="color:#ADBAC7;"> { instance </span><span style="color:#F47067;">-&gt;</span></span>
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#768390;">// 调用执行每个方法</span></span>
<span class="line"><span style="color:#ADBAC7;"> instance.</span><span style="color:#DCBDFB;">call</span><span style="color:#ADBAC7;">(</span><span style="color:#F47067;">..</span><span style="color:#ADBAC7;">.)</span></span>
<span class="line"><span style="color:#ADBAC7;">}</span></span>
<span class="line"></span></code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p>上述示例可完美匹配到如下 6 个方法。</p><p><code>private static void init()</code></p><p><code>private void doTask(String taskName)</code></p><p><code>private void stop(String a)</code></p><p><code>private void getName(String a)</code></p><p><code>private void b()</code></p><p><code>private void b(String a)</code></p><p>通过观察 <code>Class</code> 中有两个名称为 <code>b</code> 的方法,可以使用如下实现。</p><blockquote><p>示例如下</p></blockquote><div class="language-kotlin line-numbers-mode" data-ext="kt"><pre class="shiki github-dark-dimmed" style="background-color:#22272e;" tabindex="0"><code><span class="line"><span style="color:#768390;">// 假设这就是这个 Class 的实例</span></span>
<span class="line"><span style="color:#F47067;">val</span><span style="color:#ADBAC7;"> instance </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> </span><span style="color:#DCBDFB;">Test</span><span style="color:#ADBAC7;">()</span></span>
<span class="line"><span style="color:#768390;">// 使用 YukiHookAPI 调用并执行</span></span>
<span class="line"><span style="color:#ADBAC7;">Test::</span><span style="color:#DCBDFB;">class</span><span style="color:#ADBAC7;">.java.</span><span style="color:#DCBDFB;">method</span><span style="color:#ADBAC7;"> {</span></span>
<span class="line"><span style="color:#ADBAC7;"> name </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> </span><span style="color:#96D0FF;">&quot;b&quot;</span></span>
<span class="line"><span style="color:#ADBAC7;">}.</span><span style="color:#DCBDFB;">all</span><span style="color:#ADBAC7;">(instance).</span><span style="color:#DCBDFB;">forEach</span><span style="color:#ADBAC7;"> { instance </span><span style="color:#F47067;">-&gt;</span></span>
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#768390;">// 调用执行每个方法</span></span>
<span class="line"><span style="color:#ADBAC7;"> instance.</span><span style="color:#DCBDFB;">call</span><span style="color:#ADBAC7;">(</span><span style="color:#F47067;">..</span><span style="color:#ADBAC7;">.)</span></span>
<span class="line"><span style="color:#ADBAC7;">}</span></span>
<span class="line"></span></code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p>上述示例可完美匹配到如下 2 个方法。</p><p><code>private void b()</code></p><p><code>private void b(String a)</code></p><div class="custom-container tip"><p class="custom-container-title">小提示</p><p>使用 <strong>paramCount { ... }</strong> 创建一个条件方法体,其中的变量 <strong>it</strong> 即当前参数个数的整数,此时你就可以在 <strong>CountRules</strong> 的扩展方法中自由使用其中的功能。</p><p>方法体末尾条件需要返回一个 <strong>Boolean</strong>,即最终的条件判断结果。</p><p>更多功能请参考 <a href="../public/com/highcapable/yukihookapi/hook/core/finder/members/MethodFinder#paramcount-method-2">MethodFinder.paramCount</a>、<a href="../public/com/highcapable/yukihookapi/hook/core/finder/members/ConstructorFinder#paramcount-method-2">ConstructorFinder.paramCount</a> 方法以及 <a href="../public/com/highcapable/yukihookapi/hook/core/finder/base/rules/CountRules">CountRules</a>。</p></div><h3 id="静态字节码" tabindex="-1"><a class="header-anchor" href="#静态字节码" aria-hidden="true">#</a> 静态字节码</h3><p>有些方法和变量在 <code>Class</code> 中是静态的实现,这个时候,我们不需要传入实例就可以调用它们。</p><p>假设我们这次要得到静态变量 <code>TAG</code> 的内容。</p><blockquote><p>示例如下</p></blockquote><div class="language-kotlin line-numbers-mode" data-ext="kt"><pre class="shiki github-dark-dimmed" style="background-color:#22272e;" tabindex="0"><code><span class="line"><span style="color:#ADBAC7;">Test::</span><span style="color:#DCBDFB;">class</span><span style="color:#ADBAC7;">.java.</span><span style="color:#DCBDFB;">field</span><span style="color:#ADBAC7;"> {</span></span>
<span class="line"><span style="color:#ADBAC7;"> name </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> </span><span style="color:#96D0FF;">&quot;TAG&quot;</span></span>
<span class="line"><span style="color:#ADBAC7;"> type </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> StringClass</span></span>
<span class="line"><span style="color:#ADBAC7;">}.</span><span style="color:#DCBDFB;">get</span><span style="color:#ADBAC7;">().</span><span style="color:#DCBDFB;">string</span><span style="color:#ADBAC7;">() </span><span style="color:#768390;">// Field 的类型是字符串,可直接进行 cast</span></span>
<span class="line"></span></code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p>假设 <code>Class</code> 中存在同名的非静态 <code>TAG</code> 变量,这个时候怎么办呢?</p><p>加入一个筛选条件即可。</p><blockquote><p>示例如下</p></blockquote><div class="language-kotlin line-numbers-mode" data-ext="kt"><pre class="shiki github-dark-dimmed" style="background-color:#22272e;" tabindex="0"><code><span class="line"><span style="color:#ADBAC7;">Test::</span><span style="color:#DCBDFB;">class</span><span style="color:#ADBAC7;">.java.</span><span style="color:#DCBDFB;">field</span><span style="color:#ADBAC7;"> {</span></span>
<span class="line"><span style="color:#ADBAC7;"> name </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> </span><span style="color:#96D0FF;">&quot;TAG&quot;</span></span>
<span class="line"><span style="color:#ADBAC7;"> type </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> StringClass</span></span>
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#768390;">// 标识查找的这个变量需要是静态</span></span>
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#DCBDFB;">modifiers</span><span style="color:#ADBAC7;"> { isStatic }</span></span>
<span class="line"><span style="color:#ADBAC7;">}.</span><span style="color:#DCBDFB;">get</span><span style="color:#ADBAC7;">().</span><span style="color:#DCBDFB;">string</span><span style="color:#ADBAC7;">() </span><span style="color:#768390;">// Field 的类型是字符串,可直接进行 cast</span></span>
<span class="line"></span></code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p>我们还可以调用名为 <code>init</code> 的静态方法。</p><blockquote><p>示例如下</p></blockquote><div class="language-kotlin line-numbers-mode" data-ext="kt"><pre class="shiki github-dark-dimmed" style="background-color:#22272e;" tabindex="0"><code><span class="line"><span style="color:#ADBAC7;">Test::</span><span style="color:#DCBDFB;">class</span><span style="color:#ADBAC7;">.java.</span><span style="color:#DCBDFB;">method</span><span style="color:#ADBAC7;"> {</span></span>
<span class="line"><span style="color:#ADBAC7;"> name </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> </span><span style="color:#96D0FF;">&quot;init&quot;</span></span>
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#DCBDFB;">emptyParam</span><span style="color:#ADBAC7;">()</span></span>
<span class="line"><span style="color:#ADBAC7;">}.</span><span style="color:#DCBDFB;">get</span><span style="color:#ADBAC7;">().</span><span style="color:#DCBDFB;">call</span><span style="color:#ADBAC7;">()</span></span>
<span class="line"></span></code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p>同样地,你可以标识它是一个静态。</p><blockquote><p>示例如下</p></blockquote><div class="language-kotlin line-numbers-mode" data-ext="kt"><pre class="shiki github-dark-dimmed" style="background-color:#22272e;" tabindex="0"><code><span class="line"><span style="color:#ADBAC7;">Test::</span><span style="color:#DCBDFB;">class</span><span style="color:#ADBAC7;">.java.</span><span style="color:#DCBDFB;">method</span><span style="color:#ADBAC7;"> {</span></span>
<span class="line"><span style="color:#ADBAC7;"> name </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> </span><span style="color:#96D0FF;">&quot;init&quot;</span></span>
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#DCBDFB;">emptyParam</span><span style="color:#ADBAC7;">()</span></span>
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#768390;">// 标识查找的这个方法需要是静态</span></span>
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#DCBDFB;">modifiers</span><span style="color:#ADBAC7;"> { isStatic }</span></span>
<span class="line"><span style="color:#ADBAC7;">}.</span><span style="color:#DCBDFB;">get</span><span style="color:#ADBAC7;">().</span><span style="color:#DCBDFB;">call</span><span style="color:#ADBAC7;">()</span></span>
<span class="line"></span></code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><div class="custom-container tip"><p class="custom-container-title">小提示</p><p>使用 <strong>modifiers { ... }</strong> 创建一个条件方法体,此时你就可以在 <strong>ModifierRules</strong> 中自由使用其中的功能。</p><p>方法体末尾条件需要返回一个 <strong>Boolean</strong>,即最终的条件判断结果。</p><p>更多功能请参考 <a href="../public/com/highcapable/yukihookapi/hook/core/finder/members/FieldFinder#modifiers-method">FieldFinder.modifiers</a>、<a href="../public/com/highcapable/yukihookapi/hook/core/finder/members/MethodFinder#modifiers-method">MethodFinder.modifiers</a>、<a href="../public/com/highcapable/yukihookapi/hook/core/finder/members/ConstructorFinder#modifiers-method">ConstructorFinder.modifiers</a> 方法以及 <a href="../public/com/highcapable/yukihookapi/hook/core/finder/base/rules/ModifierRules">ModifierRules</a>。</p></div><h3 id="混淆的字节码" tabindex="-1"><a class="header-anchor" href="#混淆的字节码" aria-hidden="true">#</a> 混淆的字节码</h3><p>你可能已经注意到了,这里给出的示例 <code>Class</code> 中有两个混淆的变量名称,它们都是 <code>a</code>,这个时候我们要怎么得到它们呢?</p><p>有两种方案。</p><p>第一种方案,确定变量的名称和类型。</p><blockquote><p>示例如下</p></blockquote><div class="language-kotlin line-numbers-mode" data-ext="kt"><pre class="shiki github-dark-dimmed" style="background-color:#22272e;" tabindex="0"><code><span class="line"><span style="color:#768390;">// 假设这就是这个 Class 的实例</span></span>
<span class="line"><span style="color:#F47067;">val</span><span style="color:#ADBAC7;"> instance </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> </span><span style="color:#DCBDFB;">Test</span><span style="color:#ADBAC7;">()</span></span>
<span class="line"><span style="color:#768390;">// 使用 YukiHookAPI 调用并执行</span></span>
<span class="line"><span style="color:#ADBAC7;">Test::</span><span style="color:#DCBDFB;">class</span><span style="color:#ADBAC7;">.java.</span><span style="color:#DCBDFB;">field</span><span style="color:#ADBAC7;"> {</span></span>
<span class="line"><span style="color:#ADBAC7;"> name </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> </span><span style="color:#96D0FF;">&quot;a&quot;</span></span>
<span class="line"><span style="color:#ADBAC7;"> type </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> BooleanType</span></span>
<span class="line"><span style="color:#ADBAC7;">}.</span><span style="color:#DCBDFB;">get</span><span style="color:#ADBAC7;">(instance).</span><span style="color:#DCBDFB;">any</span><span style="color:#ADBAC7;">() </span><span style="color:#768390;">// 得到名称为 a 类型为 Boolean 的变量</span></span>
<span class="line"></span></code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p>第二种方案,确定变量的类型所在的位置。</p><blockquote><p>示例如下</p></blockquote><div class="language-kotlin line-numbers-mode" data-ext="kt"><pre class="shiki github-dark-dimmed" style="background-color:#22272e;" tabindex="0"><code><span class="line"><span style="color:#768390;">// 假设这就是这个 Class 的实例</span></span>
<span class="line"><span style="color:#F47067;">val</span><span style="color:#ADBAC7;"> instance </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> </span><span style="color:#DCBDFB;">Test</span><span style="color:#ADBAC7;">()</span></span>
<span class="line"><span style="color:#768390;">// 使用 YukiHookAPI 调用并执行</span></span>
<span class="line"><span style="color:#ADBAC7;">Test::</span><span style="color:#DCBDFB;">class</span><span style="color:#ADBAC7;">.java.</span><span style="color:#DCBDFB;">field</span><span style="color:#ADBAC7;"> {</span></span>
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#DCBDFB;">type</span><span style="color:#ADBAC7;">(BooleanType).</span><span style="color:#DCBDFB;">index</span><span style="color:#ADBAC7;">().</span><span style="color:#DCBDFB;">first</span><span style="color:#ADBAC7;">()</span></span>
<span class="line"><span style="color:#ADBAC7;">}.</span><span style="color:#DCBDFB;">get</span><span style="color:#ADBAC7;">(instance).</span><span style="color:#DCBDFB;">any</span><span style="color:#ADBAC7;">() </span><span style="color:#768390;">// 得到第一个类型为 Boolean 的变量</span></span>
<span class="line"></span></code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p>以上两种情况均可得到对应的变量 <code>private boolean a</code>。</p><p>同样地,这个 <code>Class</code> 中也有两个混淆的方法名称,它们都是 <code>b</code>。</p><p>你也可以有两种方案来得到它们。</p><p>第一种方案,确定方法的名称和方法参数。</p><blockquote><p>示例如下</p></blockquote><div class="language-kotlin line-numbers-mode" data-ext="kt"><pre class="shiki github-dark-dimmed" style="background-color:#22272e;" tabindex="0"><code><span class="line"><span style="color:#768390;">// 假设这就是这个 Class 的实例</span></span>
<span class="line"><span style="color:#F47067;">val</span><span style="color:#ADBAC7;"> instance </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> </span><span style="color:#DCBDFB;">Test</span><span style="color:#ADBAC7;">()</span></span>
<span class="line"><span style="color:#768390;">// 使用 YukiHookAPI 调用并执行</span></span>
<span class="line"><span style="color:#ADBAC7;">Test::</span><span style="color:#DCBDFB;">class</span><span style="color:#ADBAC7;">.java.</span><span style="color:#DCBDFB;">method</span><span style="color:#ADBAC7;"> {</span></span>
<span class="line"><span style="color:#ADBAC7;"> name </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> </span><span style="color:#96D0FF;">&quot;b&quot;</span></span>
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#DCBDFB;">param</span><span style="color:#ADBAC7;">(StringClass)</span></span>
<span class="line"><span style="color:#ADBAC7;">}.</span><span style="color:#DCBDFB;">get</span><span style="color:#ADBAC7;">(instance).</span><span style="color:#DCBDFB;">call</span><span style="color:#ADBAC7;">(</span><span style="color:#96D0FF;">&quot;test_string&quot;</span><span style="color:#ADBAC7;">) </span><span style="color:#768390;">// 得到名称为 b 方法参数为 [String] 的方法</span></span>
<span class="line"></span></code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p>第二种方案,确定方法的参数所在的位置。</p><blockquote><p>示例如下</p></blockquote><div class="language-kotlin line-numbers-mode" data-ext="kt"><pre class="shiki github-dark-dimmed" style="background-color:#22272e;" tabindex="0"><code><span class="line"><span style="color:#768390;">// 假设这就是这个 Class 的实例</span></span>
<span class="line"><span style="color:#F47067;">val</span><span style="color:#ADBAC7;"> instance </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> </span><span style="color:#DCBDFB;">Test</span><span style="color:#ADBAC7;">()</span></span>
<span class="line"><span style="color:#768390;">// 使用 YukiHookAPI 调用并执行</span></span>
<span class="line"><span style="color:#ADBAC7;">Test::</span><span style="color:#DCBDFB;">class</span><span style="color:#ADBAC7;">.java.</span><span style="color:#DCBDFB;">method</span><span style="color:#ADBAC7;"> {</span></span>
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#DCBDFB;">param</span><span style="color:#ADBAC7;">(StringClass).</span><span style="color:#DCBDFB;">index</span><span style="color:#ADBAC7;">().</span><span style="color:#DCBDFB;">first</span><span style="color:#ADBAC7;">()</span></span>
<span class="line"><span style="color:#ADBAC7;">}.</span><span style="color:#DCBDFB;">get</span><span style="color:#ADBAC7;">(instance).</span><span style="color:#DCBDFB;">call</span><span style="color:#ADBAC7;">(</span><span style="color:#96D0FF;">&quot;test_string&quot;</span><span style="color:#ADBAC7;">) </span><span style="color:#768390;">// 得到第一个方法参数为 [String] 的方法</span></span>
<span class="line"></span></code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p>由于观察到这个方法在 <code>Class</code> 的最后一个,那我们还有一个备选方案。</p><blockquote><p>示例如下</p></blockquote><div class="language-kotlin line-numbers-mode" data-ext="kt"><pre class="shiki github-dark-dimmed" style="background-color:#22272e;" tabindex="0"><code><span class="line"><span style="color:#768390;">// 假设这就是这个 Class 的实例</span></span>
<span class="line"><span style="color:#F47067;">val</span><span style="color:#ADBAC7;"> instance </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> </span><span style="color:#DCBDFB;">Test</span><span style="color:#ADBAC7;">()</span></span>
<span class="line"><span style="color:#768390;">// 使用 YukiHookAPI 调用并执行</span></span>
<span class="line"><span style="color:#ADBAC7;">Test::</span><span style="color:#DCBDFB;">class</span><span style="color:#ADBAC7;">.java.</span><span style="color:#DCBDFB;">method</span><span style="color:#ADBAC7;"> {</span></span>
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#DCBDFB;">order</span><span style="color:#ADBAC7;">().</span><span style="color:#DCBDFB;">index</span><span style="color:#ADBAC7;">().</span><span style="color:#DCBDFB;">last</span><span style="color:#ADBAC7;">()</span></span>
<span class="line"><span style="color:#ADBAC7;">}.</span><span style="color:#DCBDFB;">get</span><span style="color:#ADBAC7;">(instance).</span><span style="color:#DCBDFB;">call</span><span style="color:#ADBAC7;">(</span><span style="color:#96D0FF;">&quot;test_string&quot;</span><span style="color:#ADBAC7;">) </span><span style="color:#768390;">// 得到当前 Class 的最后一个方法</span></span>
<span class="line"></span></code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><div class="custom-container warning"><p class="custom-container-title">注意</p><p>请尽量避免使用 <strong>order</strong> 来筛选字节码的下标,它们可能是不确定的,除非你确定它在这个 <strong>Class</strong> 中的位置一定不会变。</p></div><h3 id="直接调用" tabindex="-1"><a class="header-anchor" href="#直接调用" aria-hidden="true">#</a> 直接调用</h3><p>上面介绍的调用字节码的方法都需要使用 <code>get(instance)</code> 才能调用对应的方法,有没有简单一点的办法呢?</p><p>此时,你可以在任意实例上使用 <code>current</code> 方法来创建一个调用空间。</p><blockquote><p>示例如下</p></blockquote><div class="language-kotlin line-numbers-mode" data-ext="kt"><pre class="shiki github-dark-dimmed" style="background-color:#22272e;" tabindex="0"><code><span class="line"><span style="color:#768390;">// 假设这就是这个 Class 的实例</span></span>
<span class="line"><span style="color:#F47067;">val</span><span style="color:#ADBAC7;"> instance </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> </span><span style="color:#DCBDFB;">Test</span><span style="color:#ADBAC7;">()</span></span>
<span class="line"><span style="color:#768390;">// 假设这个 Class 是不能被直接得到的</span></span>
<span class="line"><span style="color:#ADBAC7;">instance.</span><span style="color:#DCBDFB;">current</span><span style="color:#ADBAC7;"> {</span></span>
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#768390;">// 执行 doTask 方法</span></span>
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#DCBDFB;">method</span><span style="color:#ADBAC7;"> {</span></span>
<span class="line"><span style="color:#ADBAC7;"> name </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> </span><span style="color:#96D0FF;">&quot;doTask&quot;</span></span>
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#DCBDFB;">param</span><span style="color:#ADBAC7;">(StringClass)</span></span>
<span class="line"><span style="color:#ADBAC7;"> }.</span><span style="color:#DCBDFB;">call</span><span style="color:#ADBAC7;">(</span><span style="color:#96D0FF;">&quot;task_name&quot;</span><span style="color:#ADBAC7;">)</span></span>
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#768390;">// 执行 stop 方法</span></span>
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#DCBDFB;">method</span><span style="color:#ADBAC7;"> {</span></span>
<span class="line"><span style="color:#ADBAC7;"> name </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> </span><span style="color:#96D0FF;">&quot;stop&quot;</span></span>
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#DCBDFB;">emptyParam</span><span style="color:#ADBAC7;">()</span></span>
<span class="line"><span style="color:#ADBAC7;"> }.</span><span style="color:#DCBDFB;">call</span><span style="color:#ADBAC7;">()</span></span>
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#768390;">// 得到 name</span></span>
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#F47067;">val</span><span style="color:#ADBAC7;"> name </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> </span><span style="color:#DCBDFB;">method</span><span style="color:#ADBAC7;"> { name </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> </span><span style="color:#96D0FF;">&quot;getName&quot;</span><span style="color:#ADBAC7;"> }.</span><span style="color:#DCBDFB;">string</span><span style="color:#ADBAC7;">()</span></span>
<span class="line"><span style="color:#ADBAC7;">}</span></span>
<span class="line"></span></code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p>我们还可以用 <code>superClass</code> 调用当前 <code>Class</code> 父类的方法。</p><blockquote><p>示例如下</p></blockquote><div class="language-kotlin line-numbers-mode" data-ext="kt"><pre class="shiki github-dark-dimmed" style="background-color:#22272e;" tabindex="0"><code><span class="line"><span style="color:#768390;">// 假设这就是这个 Class 的实例</span></span>
<span class="line"><span style="color:#F47067;">val</span><span style="color:#ADBAC7;"> instance </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> </span><span style="color:#DCBDFB;">Test</span><span style="color:#ADBAC7;">()</span></span>
<span class="line"><span style="color:#768390;">// 假设这个 Class 是不能被直接得到的</span></span>
<span class="line"><span style="color:#ADBAC7;">instance.</span><span style="color:#DCBDFB;">current</span><span style="color:#ADBAC7;"> {</span></span>
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#768390;">// 执行父类的 doBaseTask 方法</span></span>
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#DCBDFB;">superClass</span><span style="color:#ADBAC7;">().</span><span style="color:#DCBDFB;">method</span><span style="color:#ADBAC7;"> {</span></span>
<span class="line"><span style="color:#ADBAC7;"> name </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> </span><span style="color:#96D0FF;">&quot;doBaseTask&quot;</span></span>
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#DCBDFB;">param</span><span style="color:#ADBAC7;">(StringClass)</span></span>
<span class="line"><span style="color:#ADBAC7;"> }.</span><span style="color:#DCBDFB;">call</span><span style="color:#ADBAC7;">(</span><span style="color:#96D0FF;">&quot;task_name&quot;</span><span style="color:#ADBAC7;">)</span></span>
<span class="line"><span style="color:#ADBAC7;">}</span></span>
<span class="line"></span></code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p>如果你不喜欢使用一个大括号的调用域来创建当前实例的命名空间,你可以直接使用 <code>current()</code> 方法。</p><blockquote><p>示例如下</p></blockquote><div class="language-kotlin line-numbers-mode" data-ext="kt"><pre class="shiki github-dark-dimmed" style="background-color:#22272e;" tabindex="0"><code><span class="line"><span style="color:#768390;">// 假设这就是这个 Class 的实例,这个 Class 是不能被直接得到的</span></span>
<span class="line"><span style="color:#F47067;">val</span><span style="color:#ADBAC7;"> instance </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> </span><span style="color:#DCBDFB;">Test</span><span style="color:#ADBAC7;">()</span></span>
<span class="line"><span style="color:#768390;">// 执行 doTask 方法</span></span>
<span class="line"><span style="color:#ADBAC7;">instance</span></span>
<span class="line"><span style="color:#ADBAC7;"> .</span><span style="color:#DCBDFB;">current</span><span style="color:#ADBAC7;">()</span></span>
<span class="line"><span style="color:#ADBAC7;"> .</span><span style="color:#DCBDFB;">method</span><span style="color:#ADBAC7;"> {</span></span>
<span class="line"><span style="color:#ADBAC7;"> name </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> </span><span style="color:#96D0FF;">&quot;doTask&quot;</span></span>
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#DCBDFB;">param</span><span style="color:#ADBAC7;">(StringClass)</span></span>
<span class="line"><span style="color:#ADBAC7;"> }.</span><span style="color:#DCBDFB;">call</span><span style="color:#ADBAC7;">(</span><span style="color:#96D0FF;">&quot;task_name&quot;</span><span style="color:#ADBAC7;">)</span></span>
<span class="line"><span style="color:#768390;">// 执行 stop 方法</span></span>
<span class="line"><span style="color:#ADBAC7;">instance</span></span>
<span class="line"><span style="color:#ADBAC7;"> .</span><span style="color:#DCBDFB;">current</span><span style="color:#ADBAC7;">()</span></span>
<span class="line"><span style="color:#ADBAC7;"> .</span><span style="color:#DCBDFB;">method</span><span style="color:#ADBAC7;"> {</span></span>
<span class="line"><span style="color:#ADBAC7;"> name </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> </span><span style="color:#96D0FF;">&quot;stop&quot;</span></span>
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#DCBDFB;">emptyParam</span><span style="color:#ADBAC7;">()</span></span>
<span class="line"><span style="color:#ADBAC7;"> }.</span><span style="color:#DCBDFB;">call</span><span style="color:#ADBAC7;">()</span></span>
<span class="line"><span style="color:#768390;">// 得到 name</span></span>
<span class="line"><span style="color:#F47067;">val</span><span style="color:#ADBAC7;"> name </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> instance.</span><span style="color:#DCBDFB;">current</span><span style="color:#ADBAC7;">().</span><span style="color:#DCBDFB;">method</span><span style="color:#ADBAC7;"> { name </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> </span><span style="color:#96D0FF;">&quot;getName&quot;</span><span style="color:#ADBAC7;"> }.</span><span style="color:#DCBDFB;">string</span><span style="color:#ADBAC7;">()</span></span>
<span class="line"></span></code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p>同样地,它们之间可以连续调用,但<u><strong>不允许内联调用</strong></u>。</p><blockquote><p>示例如下</p></blockquote><div class="language-kotlin line-numbers-mode" data-ext="kt"><pre class="shiki github-dark-dimmed" style="background-color:#22272e;" tabindex="0"><code><span class="line"><span style="color:#768390;">// 假设这就是这个 Class 的实例</span></span>
<span class="line"><span style="color:#F47067;">val</span><span style="color:#ADBAC7;"> instance </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> </span><span style="color:#DCBDFB;">Test</span><span style="color:#ADBAC7;">()</span></span>
<span class="line"><span style="color:#768390;">// 假设这个 Class 是不能被直接得到的</span></span>
<span class="line"><span style="color:#ADBAC7;">instance.</span><span style="color:#DCBDFB;">current</span><span style="color:#ADBAC7;"> {</span></span>
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#DCBDFB;">method</span><span style="color:#ADBAC7;"> {</span></span>
<span class="line"><span style="color:#ADBAC7;"> name </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> </span><span style="color:#96D0FF;">&quot;doTask&quot;</span></span>
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#DCBDFB;">param</span><span style="color:#ADBAC7;">(StringClass)</span></span>
<span class="line"><span style="color:#ADBAC7;"> }.</span><span style="color:#DCBDFB;">call</span><span style="color:#ADBAC7;">(</span><span style="color:#96D0FF;">&quot;task_name&quot;</span><span style="color:#ADBAC7;">)</span></span>
<span class="line"><span style="color:#ADBAC7;">}.</span><span style="color:#DCBDFB;">current</span><span style="color:#ADBAC7;">()</span></span>
<span class="line"><span style="color:#ADBAC7;"> .</span><span style="color:#DCBDFB;">method</span><span style="color:#ADBAC7;"> {</span></span>
<span class="line"><span style="color:#ADBAC7;"> name </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> </span><span style="color:#96D0FF;">&quot;stop&quot;</span></span>
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#DCBDFB;">emptyParam</span><span style="color:#ADBAC7;">()</span></span>
<span class="line"><span style="color:#ADBAC7;"> }.</span><span style="color:#DCBDFB;">call</span><span style="color:#ADBAC7;">()</span></span>
<span class="line"><span style="color:#768390;">// 注意,因为 current() 返回的是 CurrentClass 自身对象,所以不能像下面这样调用</span></span>
<span class="line"><span style="color:#ADBAC7;">instance.</span><span style="color:#DCBDFB;">current</span><span style="color:#ADBAC7;">().</span><span style="color:#DCBDFB;">current</span><span style="color:#ADBAC7;">()</span></span>
<span class="line"></span></code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p>针对 <code>Field</code> 实例,还有一个便捷的方法,可以直接获取 <code>Field</code> 所在实例的对象。</p><blockquote><p>示例如下</p></blockquote><div class="language-kotlin line-numbers-mode" data-ext="kt"><pre class="shiki github-dark-dimmed" style="background-color:#22272e;" tabindex="0"><code><span class="line"><span style="color:#768390;">// 假设这就是这个 Class 的实例</span></span>
<span class="line"><span style="color:#F47067;">val</span><span style="color:#ADBAC7;"> instance </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> </span><span style="color:#DCBDFB;">Test</span><span style="color:#ADBAC7;">()</span></span>
<span class="line"><span style="color:#768390;">// 假设这个 Class 是不能被直接得到的</span></span>
<span class="line"><span style="color:#ADBAC7;">instance.</span><span style="color:#DCBDFB;">current</span><span style="color:#ADBAC7;"> {</span></span>
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#768390;">// &lt;方案1&gt;</span></span>
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#F47067;">field</span><span style="color:#ADBAC7;"> {</span></span>
<span class="line"><span style="color:#ADBAC7;"> name </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> </span><span style="color:#96D0FF;">&quot;baseInstance&quot;</span></span>
<span class="line"><span style="color:#ADBAC7;"> }.</span><span style="color:#DCBDFB;">current</span><span style="color:#ADBAC7;"> {</span></span>
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#DCBDFB;">method</span><span style="color:#ADBAC7;"> {</span></span>
<span class="line"><span style="color:#ADBAC7;"> name </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> </span><span style="color:#96D0FF;">&quot;doBaseTask&quot;</span></span>
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#DCBDFB;">param</span><span style="color:#ADBAC7;">(StringClass)</span></span>
<span class="line"><span style="color:#ADBAC7;"> }.</span><span style="color:#DCBDFB;">call</span><span style="color:#ADBAC7;">(</span><span style="color:#96D0FF;">&quot;task_name&quot;</span><span style="color:#ADBAC7;">)</span></span>
<span class="line"><span style="color:#ADBAC7;"> }</span></span>
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#768390;">// &lt;方案2&gt;</span></span>
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#F47067;">field</span><span style="color:#ADBAC7;"> {</span></span>
<span class="line"><span style="color:#ADBAC7;"> name </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> </span><span style="color:#96D0FF;">&quot;baseInstance&quot;</span></span>
<span class="line"><span style="color:#ADBAC7;"> }.</span><span style="color:#DCBDFB;">current</span><span style="color:#ADBAC7;">()</span></span>
<span class="line"><span style="color:#ADBAC7;"> ?.</span><span style="color:#DCBDFB;">method</span><span style="color:#ADBAC7;"> {</span></span>
<span class="line"><span style="color:#ADBAC7;"> name </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> </span><span style="color:#96D0FF;">&quot;doBaseTask&quot;</span></span>
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#DCBDFB;">param</span><span style="color:#ADBAC7;">(StringClass)</span></span>
<span class="line"><span style="color:#ADBAC7;"> }?.</span><span style="color:#DCBDFB;">call</span><span style="color:#ADBAC7;">(</span><span style="color:#96D0FF;">&quot;task_name&quot;</span><span style="color:#ADBAC7;">)</span></span>
<span class="line"><span style="color:#ADBAC7;">}</span></span>
<span class="line"></span></code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><div class="custom-container warning"><p class="custom-container-title">注意</p><p>上述 <strong>current</strong> 方法相当于帮你调用了 <strong>CurrentClass</strong> 中的 <strong>field { ... }.any()?.current()</strong> 方法。</p><p>若不存在 <strong>CurrentClass</strong> 调用域,你需要使用 <strong>field { ... }.get(instance).current()</strong> 来进行调用。</p></div><p>问题又来了,我想使用反射的方式创建如下的实例并调用其中的方法,该怎么做呢?</p><blockquote><p>示例如下</p></blockquote><div class="language-kotlin line-numbers-mode" data-ext="kt"><pre class="shiki github-dark-dimmed" style="background-color:#22272e;" tabindex="0"><code><span class="line"><span style="color:#DCBDFB;">Test</span><span style="color:#ADBAC7;">(</span><span style="color:#6CB6FF;">true</span><span style="color:#ADBAC7;">).</span><span style="color:#DCBDFB;">doTask</span><span style="color:#ADBAC7;">(</span><span style="color:#96D0FF;">&quot;task_name&quot;</span><span style="color:#ADBAC7;">)</span></span>
<span class="line"></span></code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div></div></div><p>通常情况下,我们可以使用标准的反射 API 来调用。</p><blockquote><p>示例如下</p></blockquote><div class="language-kotlin line-numbers-mode" data-ext="kt"><pre class="shiki github-dark-dimmed" style="background-color:#22272e;" tabindex="0"><code><span class="line"><span style="color:#96D0FF;">&quot;com.demo.Test&quot;</span><span style="color:#ADBAC7;">.</span><span style="color:#DCBDFB;">toClass</span><span style="color:#ADBAC7;">()</span></span>
<span class="line"><span style="color:#ADBAC7;"> .</span><span style="color:#DCBDFB;">getDeclaredConstructor</span><span style="color:#ADBAC7;">(Boolean::</span><span style="color:#DCBDFB;">class</span><span style="color:#ADBAC7;">.java)</span></span>
<span class="line"><span style="color:#ADBAC7;"> .</span><span style="color:#DCBDFB;">apply</span><span style="color:#ADBAC7;"> { isAccessible </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> </span><span style="color:#6CB6FF;">true</span><span style="color:#ADBAC7;"> }</span></span>
<span class="line"><span style="color:#ADBAC7;"> .</span><span style="color:#DCBDFB;">newInstance</span><span style="color:#ADBAC7;">(</span><span style="color:#6CB6FF;">true</span><span style="color:#ADBAC7;">)</span></span>
<span class="line"><span style="color:#ADBAC7;"> .</span><span style="color:#DCBDFB;">apply</span><span style="color:#ADBAC7;"> {</span></span>
<span class="line"><span style="color:#ADBAC7;"> javaClass</span></span>
<span class="line"><span style="color:#ADBAC7;"> .</span><span style="color:#DCBDFB;">getDeclaredMethod</span><span style="color:#ADBAC7;">(</span><span style="color:#96D0FF;">&quot;doTask&quot;</span><span style="color:#ADBAC7;">, String::</span><span style="color:#DCBDFB;">class</span><span style="color:#ADBAC7;">.java)</span></span>
<span class="line"><span style="color:#ADBAC7;"> .</span><span style="color:#DCBDFB;">apply</span><span style="color:#ADBAC7;"> { isAccessible </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> </span><span style="color:#6CB6FF;">true</span><span style="color:#ADBAC7;"> }</span></span>
<span class="line"><span style="color:#ADBAC7;"> .</span><span style="color:#DCBDFB;">invoke</span><span style="color:#ADBAC7;">(</span><span style="color:#6CB6FF;">this</span><span style="color:#ADBAC7;">, </span><span style="color:#96D0FF;">&quot;task_name&quot;</span><span style="color:#ADBAC7;">)</span></span>
<span class="line"><span style="color:#ADBAC7;"> }</span></span>
<span class="line"></span></code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p>但是感觉这种做法好麻烦,有没有更简洁的调用方法呢?</p><p>这个时候,我们还可以借助 <code>buildOf</code> 方法来创建一个实例。</p><blockquote><p>示例如下</p></blockquote><div class="language-kotlin line-numbers-mode" data-ext="kt"><pre class="shiki github-dark-dimmed" style="background-color:#22272e;" tabindex="0"><code><span class="line"><span style="color:#96D0FF;">&quot;com.demo.Test&quot;</span><span style="color:#ADBAC7;">.</span><span style="color:#DCBDFB;">toClass</span><span style="color:#ADBAC7;">().</span><span style="color:#DCBDFB;">buildOf</span><span style="color:#ADBAC7;">(</span><span style="color:#6CB6FF;">true</span><span style="color:#ADBAC7;">) { </span><span style="color:#DCBDFB;">param</span><span style="color:#ADBAC7;">(BooleanType) }?.</span><span style="color:#DCBDFB;">current</span><span style="color:#ADBAC7;"> {</span></span>
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#DCBDFB;">method</span><span style="color:#ADBAC7;"> {</span></span>
<span class="line"><span style="color:#ADBAC7;"> name </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> </span><span style="color:#96D0FF;">&quot;doTask&quot;</span></span>
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#DCBDFB;">param</span><span style="color:#ADBAC7;">(StringClass)</span></span>
<span class="line"><span style="color:#ADBAC7;"> }.</span><span style="color:#DCBDFB;">call</span><span style="color:#ADBAC7;">(</span><span style="color:#96D0FF;">&quot;task_name&quot;</span><span style="color:#ADBAC7;">)</span></span>
<span class="line"><span style="color:#ADBAC7;">}</span></span>
<span class="line"></span></code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p>若你希望 <code>buildOf</code> 方法返回当前实例的类型,你可以在其中加入类型泛型声明,而无需使用 <code>as</code> 来 <code>cast</code> 目标类型。</p><p>这种情况多用于实例本身的构造方法是私有的,但是里面的方法是公有的,这样我们只需要对其构造方法进行反射创建即可。</p><blockquote><p>示例如下</p></blockquote><div class="language-kotlin line-numbers-mode" data-ext="kt"><pre class="shiki github-dark-dimmed" style="background-color:#22272e;" tabindex="0"><code><span class="line"><span style="color:#768390;">// 假设这个 Class 是能够直接被得到的</span></span>
<span class="line"><span style="color:#F47067;">val</span><span style="color:#ADBAC7;"> test </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> Test::</span><span style="color:#DCBDFB;">class</span><span style="color:#ADBAC7;">.java.</span><span style="color:#DCBDFB;">buildOf</span><span style="color:#ADBAC7;">&lt;</span><span style="color:#F69D50;">Test</span><span style="color:#ADBAC7;">&gt;(</span><span style="color:#6CB6FF;">true</span><span style="color:#ADBAC7;">) { </span><span style="color:#DCBDFB;">param</span><span style="color:#ADBAC7;">(BooleanType) }</span></span>
<span class="line"><span style="color:#ADBAC7;">test.</span><span style="color:#DCBDFB;">doTask</span><span style="color:#ADBAC7;">(</span><span style="color:#96D0FF;">&quot;task_name&quot;</span><span style="color:#ADBAC7;">)</span></span>
<span class="line"></span></code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><div class="custom-container tip"><p class="custom-container-title">小提示</p><p>更多功能请参考 <a href="../public/com/highcapable/yukihookapi/hook/bean/CurrentClass">CurrentClass</a> 以及 <a href="../public/com/highcapable/yukihookapi/hook/factory/ReflectionFactory#class-buildof-ext-method">Class.buildOf</a> 方法。</p></div><h3 id="原始调用" tabindex="-1"><a class="header-anchor" href="#原始调用" aria-hidden="true">#</a> 原始调用</h3><p>若你正在使用反射调用的一个方法是被 Hook 过的,此时我们如何调用其原始方法呢?</p><p>原生的 <code>XposedBridge</code> 为我们提供了一个 <code>XposedBridge.invokeOriginalMethod</code> 功能。</p><p>现在,在 <code>YukiHookAPI</code> 中你可以使用如下方法便捷地实现这个功能。</p><p>假设下面是我们要演示的 <code>Class</code>。</p><blockquote><p>示例如下</p></blockquote><div class="language-java" data-ext="java"><pre class="shiki github-dark-dimmed" style="background-color:#22272e;" tabindex="0"><code><span class="line"><span style="color:#F47067;">public</span><span style="color:#ADBAC7;"> </span><span style="color:#F47067;">class</span><span style="color:#ADBAC7;"> </span><span style="color:#F69D50;">Test</span><span style="color:#ADBAC7;"> {</span></span>
<span class="line"></span>
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#F47067;">public</span><span style="color:#ADBAC7;"> </span><span style="color:#F47067;">static</span><span style="color:#ADBAC7;"> String </span><span style="color:#DCBDFB;">getString</span><span style="color:#ADBAC7;">() {</span></span>
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#F47067;">return</span><span style="color:#ADBAC7;"> </span><span style="color:#96D0FF;">&quot;Original&quot;</span><span style="color:#ADBAC7;">;</span></span>
<span class="line"><span style="color:#ADBAC7;"> }</span></span>
<span class="line"><span style="color:#ADBAC7;">}</span></span>
<span class="line"></span></code></pre></div><p>下面是 Hook 这个 <code>Class</code> 中 <code>getString</code> 方法的方式。</p><blockquote><p>示例如下</p></blockquote><div class="language-kotlin line-numbers-mode" data-ext="kt"><pre class="shiki github-dark-dimmed" style="background-color:#22272e;" tabindex="0"><code><span class="line"><span style="color:#ADBAC7;">Test::</span><span style="color:#DCBDFB;">class</span><span style="color:#ADBAC7;">.java.</span><span style="color:#DCBDFB;">method</span><span style="color:#ADBAC7;"> {</span></span>
<span class="line"><span style="color:#ADBAC7;"> name </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> </span><span style="color:#96D0FF;">&quot;getString&quot;</span></span>
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#DCBDFB;">emptyParam</span><span style="color:#ADBAC7;">()</span></span>
<span class="line"><span style="color:#ADBAC7;"> returnType </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> StringClass</span></span>
<span class="line"><span style="color:#ADBAC7;">}.</span><span style="color:#DCBDFB;">hook</span><span style="color:#ADBAC7;"> {</span></span>
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#DCBDFB;">replaceTo</span><span style="color:#ADBAC7;">(</span><span style="color:#96D0FF;">&quot;Hooked&quot;</span><span style="color:#ADBAC7;">)</span></span>
<span class="line"><span style="color:#ADBAC7;">}</span></span>
<span class="line"></span></code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p>此时,我们再使用反射调用这个方法,则会得到 Hook 后的结果 <code>&quot;Hooked&quot;</code>。</p><blockquote><p>示例如下</p></blockquote><div class="language-kotlin line-numbers-mode" data-ext="kt"><pre class="shiki github-dark-dimmed" style="background-color:#22272e;" tabindex="0"><code><span class="line"><span style="color:#768390;">// result 的结果会是 &quot;Hooked&quot;</span></span>
<span class="line"><span style="color:#F47067;">val</span><span style="color:#ADBAC7;"> result </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> Test::</span><span style="color:#DCBDFB;">class</span><span style="color:#ADBAC7;">.java.</span><span style="color:#DCBDFB;">method</span><span style="color:#ADBAC7;"> {</span></span>
<span class="line"><span style="color:#ADBAC7;"> name </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> </span><span style="color:#96D0FF;">&quot;getString&quot;</span></span>
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#DCBDFB;">emptyParam</span><span style="color:#ADBAC7;">()</span></span>
<span class="line"><span style="color:#ADBAC7;"> returnType </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> StringClass</span></span>
<span class="line"><span style="color:#ADBAC7;">}.</span><span style="color:#DCBDFB;">get</span><span style="color:#ADBAC7;">().</span><span style="color:#DCBDFB;">string</span><span style="color:#ADBAC7;">()</span></span>
<span class="line"></span></code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p>如果我们想得到这个方法未经 Hook 的原始方法及结果,只需要在结果中加入 <code>original</code> 即可。</p><blockquote><p>示例如下</p></blockquote><div class="language-kotlin line-numbers-mode" data-ext="kt"><pre class="shiki github-dark-dimmed" style="background-color:#22272e;" tabindex="0"><code><span class="line"><span style="color:#768390;">// result 的结果会是 &quot;Original&quot;</span></span>
<span class="line"><span style="color:#F47067;">val</span><span style="color:#ADBAC7;"> result </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> Test::</span><span style="color:#DCBDFB;">class</span><span style="color:#ADBAC7;">.java.</span><span style="color:#DCBDFB;">method</span><span style="color:#ADBAC7;"> {</span></span>
<span class="line"><span style="color:#ADBAC7;"> name </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> </span><span style="color:#96D0FF;">&quot;getString&quot;</span></span>
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#DCBDFB;">emptyParam</span><span style="color:#ADBAC7;">()</span></span>
<span class="line"><span style="color:#ADBAC7;"> returnType </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> StringClass</span></span>
<span class="line"><span style="color:#ADBAC7;">}.</span><span style="color:#DCBDFB;">get</span><span style="color:#ADBAC7;">().</span><span style="color:#DCBDFB;">original</span><span style="color:#ADBAC7;">().</span><span style="color:#DCBDFB;">string</span><span style="color:#ADBAC7;">()</span></span>
<span class="line"></span></code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><div class="custom-container tip"><p class="custom-container-title">小提示</p><p>更多功能请参考 <a href="../public/com/highcapable/yukihookapi/hook/core/finder/members/MethodFinder#original-method">MethodFinder.Result.original</a> 方法。</p></div><h3 id="再次查找" tabindex="-1"><a class="header-anchor" href="#再次查找" aria-hidden="true">#</a> 再次查找</h3><p>假设有三个不同版本的 <code>Class</code>,它们都是这个宿主不同版本相同的 <code>Class</code>。</p><p>这里面同样都有一个方法 <code>doTask</code>,假设它们的功能是一样的。</p><blockquote><p>版本 A 示例如下</p></blockquote><div class="language-java" data-ext="java"><pre class="shiki github-dark-dimmed" style="background-color:#22272e;" tabindex="0"><code><span class="line"><span style="color:#F47067;">public</span><span style="color:#ADBAC7;"> </span><span style="color:#F47067;">class</span><span style="color:#ADBAC7;"> </span><span style="color:#F69D50;">Test</span><span style="color:#ADBAC7;"> {</span></span>
<span class="line"></span>
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#F47067;">public</span><span style="color:#ADBAC7;"> </span><span style="color:#F47067;">void</span><span style="color:#ADBAC7;"> </span><span style="color:#DCBDFB;">doTask</span><span style="color:#ADBAC7;">() {</span></span>
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#768390;">// ...</span></span>
<span class="line"><span style="color:#ADBAC7;"> }</span></span>
<span class="line"><span style="color:#ADBAC7;">}</span></span>
<span class="line"></span></code></pre></div><blockquote><p>版本 B 示例如下</p></blockquote><div class="language-java" data-ext="java"><pre class="shiki github-dark-dimmed" style="background-color:#22272e;" tabindex="0"><code><span class="line"><span style="color:#F47067;">public</span><span style="color:#ADBAC7;"> </span><span style="color:#F47067;">class</span><span style="color:#ADBAC7;"> </span><span style="color:#F69D50;">Test</span><span style="color:#ADBAC7;"> {</span></span>
<span class="line"></span>
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#F47067;">public</span><span style="color:#ADBAC7;"> </span><span style="color:#F47067;">void</span><span style="color:#ADBAC7;"> </span><span style="color:#DCBDFB;">doTask</span><span style="color:#ADBAC7;">(String </span><span style="color:#F69D50;">taskName</span><span style="color:#ADBAC7;">) {</span></span>
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#768390;">// ...</span></span>
<span class="line"><span style="color:#ADBAC7;"> }</span></span>
<span class="line"><span style="color:#ADBAC7;">}</span></span>
<span class="line"></span></code></pre></div><blockquote><p>版本 C 示例如下</p></blockquote><div class="language-java" data-ext="java"><pre class="shiki github-dark-dimmed" style="background-color:#22272e;" tabindex="0"><code><span class="line"><span style="color:#F47067;">public</span><span style="color:#ADBAC7;"> </span><span style="color:#F47067;">class</span><span style="color:#ADBAC7;"> </span><span style="color:#F69D50;">Test</span><span style="color:#ADBAC7;"> {</span></span>
<span class="line"></span>
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#F47067;">public</span><span style="color:#ADBAC7;"> </span><span style="color:#F47067;">void</span><span style="color:#ADBAC7;"> </span><span style="color:#DCBDFB;">doTask</span><span style="color:#ADBAC7;">(String </span><span style="color:#F69D50;">taskName</span><span style="color:#ADBAC7;">, </span><span style="color:#F47067;">int</span><span style="color:#ADBAC7;"> </span><span style="color:#F69D50;">type</span><span style="color:#ADBAC7;">) {</span></span>
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#768390;">// ...</span></span>
<span class="line"><span style="color:#ADBAC7;"> }</span></span>
<span class="line"><span style="color:#ADBAC7;">}</span></span>
<span class="line"></span></code></pre></div><p>我们需要在不同的版本中得到这个相同功能的 <code>doTask</code> 方法,要怎么做呢?</p><p>此时,你可以使用 <code>RemedyPlan</code> 完成你的需求。</p><blockquote><p>示例如下</p></blockquote><div class="language-kotlin line-numbers-mode" data-ext="kt"><pre class="shiki github-dark-dimmed" style="background-color:#22272e;" tabindex="0"><code><span class="line"><span style="color:#768390;">// 假设这就是这个 Class 的实例</span></span>
<span class="line"><span style="color:#F47067;">val</span><span style="color:#ADBAC7;"> instance </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> </span><span style="color:#DCBDFB;">Test</span><span style="color:#ADBAC7;">()</span></span>
<span class="line"><span style="color:#768390;">// 使用 YukiHookAPI 调用并执行</span></span>
<span class="line"><span style="color:#ADBAC7;">Test::</span><span style="color:#DCBDFB;">class</span><span style="color:#ADBAC7;">.java.</span><span style="color:#DCBDFB;">method</span><span style="color:#ADBAC7;"> {</span></span>
<span class="line"><span style="color:#ADBAC7;"> name </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> </span><span style="color:#96D0FF;">&quot;doTask&quot;</span></span>
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#DCBDFB;">emptyParam</span><span style="color:#ADBAC7;">()</span></span>
<span class="line"><span style="color:#ADBAC7;">}.</span><span style="color:#DCBDFB;">remedys</span><span style="color:#ADBAC7;"> {</span></span>
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#DCBDFB;">method</span><span style="color:#ADBAC7;"> {</span></span>
<span class="line"><span style="color:#ADBAC7;"> name </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> </span><span style="color:#96D0FF;">&quot;doTask&quot;</span></span>
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#DCBDFB;">param</span><span style="color:#ADBAC7;">(StringClass)</span></span>
<span class="line"><span style="color:#ADBAC7;"> }.</span><span style="color:#DCBDFB;">onFind</span><span style="color:#ADBAC7;"> {</span></span>
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#768390;">// 可在这里实现找到的逻辑</span></span>
<span class="line"><span style="color:#ADBAC7;"> }</span></span>
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#DCBDFB;">method</span><span style="color:#ADBAC7;"> {</span></span>
<span class="line"><span style="color:#ADBAC7;"> name </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> </span><span style="color:#96D0FF;">&quot;doTask&quot;</span></span>
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#DCBDFB;">param</span><span style="color:#ADBAC7;">(StringClass, IntType)</span></span>
<span class="line"><span style="color:#ADBAC7;"> }.</span><span style="color:#DCBDFB;">onFind</span><span style="color:#ADBAC7;"> {</span></span>
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#768390;">// 可在这里实现找到的逻辑</span></span>
<span class="line"><span style="color:#ADBAC7;"> }</span></span>
<span class="line"><span style="color:#ADBAC7;">}.</span><span style="color:#DCBDFB;">wait</span><span style="color:#ADBAC7;">(instance) {</span></span>
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#768390;">// 得到方法的结果</span></span>
<span class="line"><span style="color:#ADBAC7;">}</span></span>
<span class="line"></span></code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><div class="custom-container danger"><p class="custom-container-title">特别注意</p><p>使用了 <strong>RemedyPlan</strong> 的方法查找结果不能再使用 <strong>get</strong> 的方式得到方法实例,应当使用 <strong>wait</strong> 方法。</p></div><p>另外,你还可以在使用 <a href="#%E5%A4%9A%E9%87%8D%E6%9F%A5%E6%89%BE">多重查找</a> 的情况下继续使用 <code>RemedyPlan</code>。</p><blockquote><p>示例如下</p></blockquote><div class="language-kotlin line-numbers-mode" data-ext="kt"><pre class="shiki github-dark-dimmed" style="background-color:#22272e;" tabindex="0"><code><span class="line"><span style="color:#768390;">// 假设这就是这个 Class 的实例</span></span>
<span class="line"><span style="color:#F47067;">val</span><span style="color:#ADBAC7;"> instance </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> </span><span style="color:#DCBDFB;">Test</span><span style="color:#ADBAC7;">()</span></span>
<span class="line"><span style="color:#768390;">// 使用 YukiHookAPI 调用并执行</span></span>
<span class="line"><span style="color:#ADBAC7;">Test::</span><span style="color:#DCBDFB;">class</span><span style="color:#ADBAC7;">.java.</span><span style="color:#DCBDFB;">method</span><span style="color:#ADBAC7;"> {</span></span>
<span class="line"><span style="color:#ADBAC7;"> name </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> </span><span style="color:#96D0FF;">&quot;doTask&quot;</span></span>
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#DCBDFB;">emptyParam</span><span style="color:#ADBAC7;">()</span></span>
<span class="line"><span style="color:#ADBAC7;">}.</span><span style="color:#DCBDFB;">remedys</span><span style="color:#ADBAC7;"> {</span></span>
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#DCBDFB;">method</span><span style="color:#ADBAC7;"> {</span></span>
<span class="line"><span style="color:#ADBAC7;"> name </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> </span><span style="color:#96D0FF;">&quot;doTask&quot;</span></span>
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#DCBDFB;">paramCount</span><span style="color:#ADBAC7;">(</span><span style="color:#6CB6FF;">0</span><span style="color:#F47067;">..</span><span style="color:#6CB6FF;">1</span><span style="color:#ADBAC7;">)</span></span>
<span class="line"><span style="color:#ADBAC7;"> }.</span><span style="color:#DCBDFB;">onFind</span><span style="color:#ADBAC7;"> {</span></span>
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#768390;">// 可在这里实现找到的逻辑</span></span>
<span class="line"><span style="color:#ADBAC7;"> }</span></span>
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#DCBDFB;">method</span><span style="color:#ADBAC7;"> {</span></span>
<span class="line"><span style="color:#ADBAC7;"> name </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> </span><span style="color:#96D0FF;">&quot;doTask&quot;</span></span>
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#DCBDFB;">paramCount</span><span style="color:#ADBAC7;">(</span><span style="color:#6CB6FF;">1</span><span style="color:#F47067;">..</span><span style="color:#6CB6FF;">2</span><span style="color:#ADBAC7;">)</span></span>
<span class="line"><span style="color:#ADBAC7;"> }.</span><span style="color:#DCBDFB;">onFind</span><span style="color:#ADBAC7;"> {</span></span>
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#768390;">// 可在这里实现找到的逻辑</span></span>
<span class="line"><span style="color:#ADBAC7;"> }</span></span>
<span class="line"><span style="color:#ADBAC7;">}.</span><span style="color:#DCBDFB;">waitAll</span><span style="color:#ADBAC7;">(instance) {</span></span>
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#768390;">// 得到方法的结果</span></span>
<span class="line"><span style="color:#ADBAC7;">}</span></span>
<span class="line"></span></code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><div class="custom-container tip"><p class="custom-container-title">小提示</p><p>更多功能请参考 <a href="../public/com/highcapable/yukihookapi/hook/core/finder/members/MethodFinder#remedyplan-class">MethodFinder.RemedyPlan</a>、<a href="../public/com/highcapable/yukihookapi/hook/core/finder/members/ConstructorFinder#remedyplan-class">ConstructorFinder.RemedyPlan</a>、<a href="../public/com/highcapable/yukihookapi/hook/core/finder/members/FieldFinder#remedyplan-class">FieldFinder.RemedyPlan</a>。</p></div><h3 id="相对匹配" tabindex="-1"><a class="header-anchor" href="#相对匹配" aria-hidden="true">#</a> 相对匹配</h3><p>假设宿主中不同版本中存在功能相同的 <code>Class</code> 但仅有 <code>Class</code> 的名称不一样。</p><blockquote><p>版本 A 示例如下</p></blockquote><div class="language-java" data-ext="java"><pre class="shiki github-dark-dimmed" style="background-color:#22272e;" tabindex="0"><code><span class="line"><span style="color:#F47067;">public</span><span style="color:#ADBAC7;"> </span><span style="color:#F47067;">class</span><span style="color:#ADBAC7;"> </span><span style="color:#F69D50;">ATest</span><span style="color:#ADBAC7;"> {</span></span>
<span class="line"></span>
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#F47067;">public</span><span style="color:#ADBAC7;"> </span><span style="color:#F47067;">static</span><span style="color:#ADBAC7;"> </span><span style="color:#F47067;">void</span><span style="color:#ADBAC7;"> </span><span style="color:#DCBDFB;">doTask</span><span style="color:#ADBAC7;">() {</span></span>
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#768390;">// ...</span></span>
<span class="line"><span style="color:#ADBAC7;"> }</span></span>
<span class="line"><span style="color:#ADBAC7;">}</span></span>
<span class="line"></span></code></pre></div><blockquote><p>版本 B 示例如下</p></blockquote><div class="language-java" data-ext="java"><pre class="shiki github-dark-dimmed" style="background-color:#22272e;" tabindex="0"><code><span class="line"><span style="color:#F47067;">public</span><span style="color:#ADBAC7;"> </span><span style="color:#F47067;">class</span><span style="color:#ADBAC7;"> </span><span style="color:#F69D50;">BTest</span><span style="color:#ADBAC7;"> {</span></span>
<span class="line"></span>
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#F47067;">public</span><span style="color:#ADBAC7;"> </span><span style="color:#F47067;">static</span><span style="color:#ADBAC7;"> </span><span style="color:#F47067;">void</span><span style="color:#ADBAC7;"> </span><span style="color:#DCBDFB;">doTask</span><span style="color:#ADBAC7;">() {</span></span>
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#768390;">// ...</span></span>
<span class="line"><span style="color:#ADBAC7;"> }</span></span>
<span class="line"><span style="color:#ADBAC7;">}</span></span>
<span class="line"></span></code></pre></div><p>这个时候我们想在每个版本都调用这个 <code>Class</code> 里的 <code>doTask</code> 方法该怎么做呢?</p><p>通常做法是判断 <code>Class</code> 是否存在。</p><blockquote><p>示例如下</p></blockquote><div class="language-kotlin line-numbers-mode" data-ext="kt"><pre class="shiki github-dark-dimmed" style="background-color:#22272e;" tabindex="0"><code><span class="line"><span style="color:#768390;">// 首先查找到这个 Class</span></span>
<span class="line"><span style="color:#F47067;">val</span><span style="color:#ADBAC7;"> currentClass </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> </span></span>
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#F47067;">if</span><span style="color:#ADBAC7;">(</span><span style="color:#96D0FF;">&quot;com.demo.ATest&quot;</span><span style="color:#ADBAC7;">.</span><span style="color:#DCBDFB;">hasClass</span><span style="color:#ADBAC7;">()) </span><span style="color:#96D0FF;">&quot;com.demo.ATest&quot;</span><span style="color:#ADBAC7;">.</span><span style="color:#DCBDFB;">toClass</span><span style="color:#ADBAC7;">() </span><span style="color:#F47067;">else</span><span style="color:#ADBAC7;"> </span><span style="color:#96D0FF;">&quot;com.demo.BTest&quot;</span><span style="color:#ADBAC7;">.</span><span style="color:#DCBDFB;">toClass</span><span style="color:#ADBAC7;">()</span></span>
<span class="line"><span style="color:#768390;">// 然后再查找这个方法并调用</span></span>
<span class="line"><span style="color:#ADBAC7;">currentClass.</span><span style="color:#DCBDFB;">method</span><span style="color:#ADBAC7;"> {</span></span>
<span class="line"><span style="color:#ADBAC7;"> name </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> </span><span style="color:#96D0FF;">&quot;doTask&quot;</span></span>
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#DCBDFB;">emptyParam</span><span style="color:#ADBAC7;">()</span></span>
<span class="line"><span style="color:#ADBAC7;">}.</span><span style="color:#DCBDFB;">get</span><span style="color:#ADBAC7;">().</span><span style="color:#DCBDFB;">call</span><span style="color:#ADBAC7;">()</span></span>
<span class="line"></span></code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p>感觉这种方案非常的不优雅且繁琐,那么此时 <code>YukiHookAPI</code> 就为你提供了一个非常方便的 <code>VariousClass</code> 专门来解决这个问题。</p><p>现在,你可以直接使用以下方式获取到这个 <code>Class</code>。</p><blockquote><p>示例如下</p></blockquote><div class="language-kotlin line-numbers-mode" data-ext="kt"><pre class="shiki github-dark-dimmed" style="background-color:#22272e;" tabindex="0"><code><span class="line"><span style="color:#DCBDFB;">VariousClass</span><span style="color:#ADBAC7;">(</span><span style="color:#96D0FF;">&quot;com.demo.ATest&quot;</span><span style="color:#ADBAC7;">, </span><span style="color:#96D0FF;">&quot;com.demo.BTest&quot;</span><span style="color:#ADBAC7;">).</span><span style="color:#DCBDFB;">get</span><span style="color:#ADBAC7;">().</span><span style="color:#DCBDFB;">method</span><span style="color:#ADBAC7;"> {</span></span>
<span class="line"><span style="color:#ADBAC7;"> name </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> </span><span style="color:#96D0FF;">&quot;doTask&quot;</span></span>
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#DCBDFB;">emptyParam</span><span style="color:#ADBAC7;">()</span></span>
<span class="line"><span style="color:#ADBAC7;">}.</span><span style="color:#DCBDFB;">get</span><span style="color:#ADBAC7;">().</span><span style="color:#DCBDFB;">call</span><span style="color:#ADBAC7;">()</span></span>
<span class="line"></span></code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p>若当前 <code>Class</code> 在指定的 <code>ClassLoader</code> 中存在,你可以在 <code>get</code> 中填入你的 <code>ClassLoader</code>。</p><blockquote><p>示例如下</p></blockquote><div class="language-kotlin line-numbers-mode" data-ext="kt"><pre class="shiki github-dark-dimmed" style="background-color:#22272e;" tabindex="0"><code><span class="line"><span style="color:#F47067;">val</span><span style="color:#ADBAC7;"> customClassLoader: </span><span style="color:#F69D50;">ClassLoader</span><span style="color:#ADBAC7;">? </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> </span><span style="color:#F47067;">..</span><span style="color:#ADBAC7;">. </span><span style="color:#768390;">// 假设这个就是你的 ClassLoader</span></span>
<span class="line"><span style="color:#DCBDFB;">VariousClass</span><span style="color:#ADBAC7;">(</span><span style="color:#96D0FF;">&quot;com.demo.ATest&quot;</span><span style="color:#ADBAC7;">, </span><span style="color:#96D0FF;">&quot;com.demo.BTest&quot;</span><span style="color:#ADBAC7;">).</span><span style="color:#DCBDFB;">get</span><span style="color:#ADBAC7;">(customClassLoader).</span><span style="color:#DCBDFB;">method</span><span style="color:#ADBAC7;"> {</span></span>
<span class="line"><span style="color:#ADBAC7;"> name </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> </span><span style="color:#96D0FF;">&quot;doTask&quot;</span></span>
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#DCBDFB;">emptyParam</span><span style="color:#ADBAC7;">()</span></span>
<span class="line"><span style="color:#ADBAC7;">}.</span><span style="color:#DCBDFB;">get</span><span style="color:#ADBAC7;">().</span><span style="color:#DCBDFB;">call</span><span style="color:#ADBAC7;">()</span></span>
<span class="line"></span></code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p>若你不确定所有的 <code>Class</code> 一定会被匹配到,你可以使用 <code>getOrNull</code> 方法。</p><blockquote><p>示例如下</p></blockquote><div class="language-kotlin line-numbers-mode" data-ext="kt"><pre class="shiki github-dark-dimmed" style="background-color:#22272e;" tabindex="0"><code><span class="line"><span style="color:#F47067;">val</span><span style="color:#ADBAC7;"> customClassLoader: </span><span style="color:#F69D50;">ClassLoader</span><span style="color:#ADBAC7;">? </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> </span><span style="color:#F47067;">..</span><span style="color:#ADBAC7;">. </span><span style="color:#768390;">// 假设这个就是你的 ClassLoader</span></span>
<span class="line"><span style="color:#DCBDFB;">VariousClass</span><span style="color:#ADBAC7;">(</span><span style="color:#96D0FF;">&quot;com.demo.ATest&quot;</span><span style="color:#ADBAC7;">, </span><span style="color:#96D0FF;">&quot;com.demo.BTest&quot;</span><span style="color:#ADBAC7;">).</span><span style="color:#DCBDFB;">getOrNull</span><span style="color:#ADBAC7;">(customClassLoader)?.</span><span style="color:#DCBDFB;">method</span><span style="color:#ADBAC7;"> {</span></span>
<span class="line"><span style="color:#ADBAC7;"> name </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> </span><span style="color:#96D0FF;">&quot;doTask&quot;</span></span>
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#DCBDFB;">emptyParam</span><span style="color:#ADBAC7;">()</span></span>
<span class="line"><span style="color:#ADBAC7;">}?.</span><span style="color:#DCBDFB;">get</span><span style="color:#ADBAC7;">()?.</span><span style="color:#DCBDFB;">call</span><span style="color:#ADBAC7;">()</span></span>
<span class="line"></span></code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p>若你正在 <code>PackageParam</code> 中操作 (Xposed) 宿主环境的 <code>Class</code>,可以直接使用 <code>toClass()</code> 进行设置。</p><blockquote><p>示例如下</p></blockquote><div class="language-kotlin line-numbers-mode" data-ext="kt"><pre class="shiki github-dark-dimmed" style="background-color:#22272e;" tabindex="0"><code><span class="line"><span style="color:#DCBDFB;">VariousClass</span><span style="color:#ADBAC7;">(</span><span style="color:#96D0FF;">&quot;com.demo.ATest&quot;</span><span style="color:#ADBAC7;">, </span><span style="color:#96D0FF;">&quot;com.demo.BTest&quot;</span><span style="color:#ADBAC7;">).</span><span style="color:#DCBDFB;">toClass</span><span style="color:#ADBAC7;">().</span><span style="color:#DCBDFB;">method</span><span style="color:#ADBAC7;"> {</span></span>
<span class="line"><span style="color:#ADBAC7;"> name </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> </span><span style="color:#96D0FF;">&quot;doTask&quot;</span></span>
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#DCBDFB;">emptyParam</span><span style="color:#ADBAC7;">()</span></span>
<span class="line"><span style="color:#ADBAC7;">}.</span><span style="color:#DCBDFB;">get</span><span style="color:#ADBAC7;">().</span><span style="color:#DCBDFB;">call</span><span style="color:#ADBAC7;">()</span></span>
<span class="line"></span></code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><div class="custom-container tip"><p class="custom-container-title">小提示</p><p>更多功能请参考 <a href="../public/com/highcapable/yukihookapi/hook/bean/VariousClass">VariousClass</a>。</p></div><p>若在创建 Hook 的时候使用,可以更加方便,还可以自动拦截找不到 <code>Class</code> 的异常。</p><p>你可以把这个 <code>Class</code> 定义为一个常量类型来使用。</p><blockquote><p>示例如下</p></blockquote><div class="language-kotlin line-numbers-mode" data-ext="kt"><pre class="shiki github-dark-dimmed" style="background-color:#22272e;" tabindex="0"><code><span class="line"><span style="color:#768390;">// 定义常量类型</span></span>
<span class="line"><span style="color:#F47067;">val</span><span style="color:#ADBAC7;"> ABTestClass </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> </span><span style="color:#DCBDFB;">VariousClass</span><span style="color:#ADBAC7;">(</span><span style="color:#96D0FF;">&quot;com.demo.ATest&quot;</span><span style="color:#ADBAC7;">, </span><span style="color:#96D0FF;">&quot;com.demo.BTest&quot;</span><span style="color:#ADBAC7;">)</span></span>
<span class="line"><span style="color:#768390;">// 直接使用</span></span>
<span class="line"><span style="color:#ADBAC7;">ABTestClass.</span><span style="color:#DCBDFB;">hook</span><span style="color:#ADBAC7;"> {</span></span>
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#768390;">// Your code here.</span></span>
<span class="line"><span style="color:#ADBAC7;">}</span></span>
<span class="line"></span></code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><h3 id="调用泛型" tabindex="-1"><a class="header-anchor" href="#调用泛型" aria-hidden="true">#</a> 调用泛型</h3><p>在反射过程中,我们可能会遇到泛型问题,在泛型的反射处理上,<code>YukiHookAPI</code> 同样提供了一个可在任意地方使用的语法糖。</p><p>例如我们有如下的泛型类。</p><blockquote><p>示例如下</p></blockquote><div class="language-kotlin line-numbers-mode" data-ext="kt"><pre class="shiki github-dark-dimmed" style="background-color:#22272e;" tabindex="0"><code><span class="line"><span style="color:#F47067;">class</span><span style="color:#ADBAC7;"> </span><span style="color:#F69D50;">TestGeneric</span><span style="color:#ADBAC7;">&lt;</span><span style="color:#F69D50;">T</span><span style="color:#ADBAC7;">, </span><span style="color:#F69D50;">R</span><span style="color:#ADBAC7;">&gt; (t: </span><span style="color:#F69D50;">T</span><span style="color:#ADBAC7;">, r: </span><span style="color:#F69D50;">R</span><span style="color:#ADBAC7;">) {</span></span>
<span class="line"></span>
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#F47067;">fun</span><span style="color:#ADBAC7;"> </span><span style="color:#DCBDFB;">foo</span><span style="color:#ADBAC7;">() {</span></span>
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#768390;">// ...</span></span>
<span class="line"><span style="color:#ADBAC7;"> }</span></span>
<span class="line"><span style="color:#ADBAC7;">}</span></span>
<span class="line"></span></code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p>当我们想在当前 <code>Class</code> 中获得泛型 <code>T</code> 或 <code>R</code> 的 <code>Class</code> 实例,只需要如下实现。</p><blockquote><p>示例如下</p></blockquote><div class="language-kotlin line-numbers-mode" data-ext="kt"><pre class="shiki github-dark-dimmed" style="background-color:#22272e;" tabindex="0"><code><span class="line"><span style="color:#F47067;">class</span><span style="color:#ADBAC7;"> </span><span style="color:#F69D50;">TestGeneric</span><span style="color:#ADBAC7;">&lt;</span><span style="color:#F69D50;">T</span><span style="color:#ADBAC7;">, </span><span style="color:#F69D50;">R</span><span style="color:#ADBAC7;">&gt; (t: </span><span style="color:#F69D50;">T</span><span style="color:#ADBAC7;">, r: </span><span style="color:#F69D50;">R</span><span style="color:#ADBAC7;">) {</span></span>
<span class="line"></span>
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#F47067;">fun</span><span style="color:#ADBAC7;"> </span><span style="color:#DCBDFB;">foo</span><span style="color:#ADBAC7;">() {</span></span>
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#768390;">// 获得当前实例的操作对象</span></span>
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#768390;">// 获得 T 的 Class 实例,在参数第 0 位,默认值可以不写</span></span>
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#F47067;">val</span><span style="color:#ADBAC7;"> tClass </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> </span><span style="color:#DCBDFB;">current</span><span style="color:#ADBAC7;">().</span><span style="color:#DCBDFB;">generic</span><span style="color:#ADBAC7;">()?.</span><span style="color:#DCBDFB;">argument</span><span style="color:#ADBAC7;">()</span></span>
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#768390;">// 获得 R 的 Class 实例,在参数第 1 位</span></span>
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#F47067;">val</span><span style="color:#ADBAC7;"> rClass </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> </span><span style="color:#DCBDFB;">current</span><span style="color:#ADBAC7;">().</span><span style="color:#DCBDFB;">generic</span><span style="color:#ADBAC7;">()?.</span><span style="color:#DCBDFB;">argument</span><span style="color:#ADBAC7;">(index </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> </span><span style="color:#6CB6FF;">1</span><span style="color:#ADBAC7;">)</span></span>
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#768390;">// 你还可以使用如下写法</span></span>
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#DCBDFB;">current</span><span style="color:#ADBAC7;">().</span><span style="color:#DCBDFB;">generic</span><span style="color:#ADBAC7;"> {</span></span>
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#768390;">// 获得 T 的 Class 实例,在参数第 0 位,默认值可以不写</span></span>
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#F47067;">val</span><span style="color:#ADBAC7;"> tClass </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> </span><span style="color:#DCBDFB;">argument</span><span style="color:#ADBAC7;">()</span></span>
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#768390;">// 获得 R 的 Class 实例,在参数第 1 位</span></span>
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#F47067;">val</span><span style="color:#ADBAC7;"> rClass </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> </span><span style="color:#DCBDFB;">argument</span><span style="color:#ADBAC7;">(index </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> </span><span style="color:#6CB6FF;">1</span><span style="color:#ADBAC7;">)</span></span>
<span class="line"><span style="color:#ADBAC7;"> }</span></span>
<span class="line"><span style="color:#ADBAC7;"> }</span></span>
<span class="line"><span style="color:#ADBAC7;">}</span></span>
<span class="line"></span></code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p>当我们想在外部调用这个 <code>Class</code> 时,就可以有如下实现。</p><blockquote><p>示例如下</p></blockquote><div class="language-kotlin line-numbers-mode" data-ext="kt"><pre class="shiki github-dark-dimmed" style="background-color:#22272e;" tabindex="0"><code><span class="line"><span style="color:#768390;">// 假设这个就是 T 的 Class</span></span>
<span class="line"><span style="color:#F47067;">class</span><span style="color:#ADBAC7;"> </span><span style="color:#F69D50;">TI</span><span style="color:#ADBAC7;"> {</span></span>
<span class="line"></span>
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#F47067;">fun</span><span style="color:#ADBAC7;"> </span><span style="color:#DCBDFB;">foo</span><span style="color:#ADBAC7;">() {</span></span>
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#768390;">// ...</span></span>
<span class="line"><span style="color:#ADBAC7;"> }</span></span>
<span class="line"><span style="color:#ADBAC7;">}</span></span>
<span class="line"><span style="color:#768390;">// 假设这个就是 T 的实例</span></span>
<span class="line"><span style="color:#F47067;">val</span><span style="color:#ADBAC7;"> tInstance: </span><span style="color:#F69D50;">TI</span><span style="color:#ADBAC7;">? </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> </span><span style="color:#F47067;">..</span><span style="color:#ADBAC7;">.</span></span>
<span class="line"><span style="color:#768390;">// 获得 T 的 Class 实例,在参数第 0 位,默认值可以不写,并获得其中的方法 foo 并调用</span></span>
<span class="line"><span style="color:#ADBAC7;">TestGeneric::</span><span style="color:#DCBDFB;">class</span><span style="color:#ADBAC7;">.java.</span><span style="color:#DCBDFB;">generic</span><span style="color:#ADBAC7;">()?.</span><span style="color:#DCBDFB;">argument</span><span style="color:#ADBAC7;">()?.</span><span style="color:#DCBDFB;">method</span><span style="color:#ADBAC7;"> {</span></span>
<span class="line"><span style="color:#ADBAC7;"> name </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> </span><span style="color:#96D0FF;">&quot;foo&quot;</span></span>
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#DCBDFB;">emptyParam</span><span style="color:#ADBAC7;">()</span></span>
<span class="line"><span style="color:#ADBAC7;">}?.</span><span style="color:#DCBDFB;">get</span><span style="color:#ADBAC7;">(tInstance)?.</span><span style="color:#DCBDFB;">invoke</span><span style="color:#ADBAC7;">&lt;</span><span style="color:#F69D50;">TI</span><span style="color:#ADBAC7;">&gt;()</span></span>
<span class="line"></span></code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><div class="custom-container tip"><p class="custom-container-title">小提示</p><p>更多功能请参考 <a href="../public/com/highcapable/yukihookapi/hook/bean/CurrentClass#generic-method">CurrentClass.generic</a>、<a href="../public/com/highcapable/yukihookapi/hook/factory/ReflectionFactory#class-generic-ext-method">Class.generic</a> 方法以及 <a href="../public/com/highcapable/yukihookapi/hook/bean/GenericClass">GenericClass</a>。</p></div><h3 id="注意误区" tabindex="-1"><a class="header-anchor" href="#注意误区" aria-hidden="true">#</a> 注意误区</h3><blockquote><p>这里列举了使用时可能会遇到的误区部分,可供参考。</p></blockquote><h4 id="限制性查找条件" tabindex="-1"><a class="header-anchor" href="#限制性查找条件" aria-hidden="true">#</a> 限制性查找条件</h4><p>在查找条件中,除了 <code>order</code> 你<u><strong>只能</strong></u>使用一次 <code>index</code> 功能。</p><blockquote><p>示例如下</p></blockquote><div class="language-kotlin line-numbers-mode" data-ext="kt"><pre class="shiki github-dark-dimmed" style="background-color:#22272e;" tabindex="0"><code><span class="line"><span style="color:#DCBDFB;">method</span><span style="color:#ADBAC7;"> {</span></span>
<span class="line"><span style="color:#ADBAC7;"> name </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> </span><span style="color:#96D0FF;">&quot;test&quot;</span></span>
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#DCBDFB;">param</span><span style="color:#ADBAC7;">(BooleanType).</span><span style="color:#DCBDFB;">index</span><span style="color:#ADBAC7;">(num </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> </span><span style="color:#6CB6FF;">2</span><span style="color:#ADBAC7;">)</span></span>
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#768390;">// 错误的使用方法,请仅保留一个 index 方法</span></span>
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#DCBDFB;">returnType</span><span style="color:#ADBAC7;">(StringClass).</span><span style="color:#DCBDFB;">index</span><span style="color:#ADBAC7;">(num </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> </span><span style="color:#6CB6FF;">1</span><span style="color:#ADBAC7;">)</span></span>
<span class="line"><span style="color:#ADBAC7;">}</span></span>
<span class="line"></span></code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p>以下查找条件的使用是没有任何问题的。</p><blockquote><p>示例如下</p></blockquote><div class="language-kotlin line-numbers-mode" data-ext="kt"><pre class="shiki github-dark-dimmed" style="background-color:#22272e;" tabindex="0"><code><span class="line"><span style="color:#DCBDFB;">method</span><span style="color:#ADBAC7;"> {</span></span>
<span class="line"><span style="color:#ADBAC7;"> name </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> </span><span style="color:#96D0FF;">&quot;test&quot;</span></span>
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#DCBDFB;">param</span><span style="color:#ADBAC7;">(BooleanType).</span><span style="color:#DCBDFB;">index</span><span style="color:#ADBAC7;">(num </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> </span><span style="color:#6CB6FF;">2</span><span style="color:#ADBAC7;">)</span></span>
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#DCBDFB;">order</span><span style="color:#ADBAC7;">().</span><span style="color:#DCBDFB;">index</span><span style="color:#ADBAC7;">(num </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> </span><span style="color:#6CB6FF;">1</span><span style="color:#ADBAC7;">)</span></span>
<span class="line"><span style="color:#ADBAC7;">}</span></span>
<span class="line"></span></code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><h4 id="必要的查找条件" tabindex="-1"><a class="header-anchor" href="#必要的查找条件" aria-hidden="true">#</a> 必要的查找条件</h4><p>在普通方法查找条件中,<u><strong>即使是无参的方法也需要设置查找条件</strong></u>。</p><p>假设我们有如下的 <code>Class</code>。</p><blockquote><p>示例如下</p></blockquote><div class="language-java" data-ext="java"><pre class="shiki github-dark-dimmed" style="background-color:#22272e;" tabindex="0"><code><span class="line"><span style="color:#F47067;">public</span><span style="color:#ADBAC7;"> </span><span style="color:#F47067;">class</span><span style="color:#ADBAC7;"> </span><span style="color:#F69D50;">TestFoo</span><span style="color:#ADBAC7;"> {</span></span>
<span class="line"></span>
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#F47067;">public</span><span style="color:#ADBAC7;"> </span><span style="color:#F47067;">void</span><span style="color:#ADBAC7;"> </span><span style="color:#DCBDFB;">foo</span><span style="color:#ADBAC7;">(String </span><span style="color:#F69D50;">string</span><span style="color:#ADBAC7;">) {</span></span>
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#768390;">// ...</span></span>
<span class="line"><span style="color:#ADBAC7;"> }</span></span>
<span class="line"></span>
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#F47067;">public</span><span style="color:#ADBAC7;"> </span><span style="color:#F47067;">void</span><span style="color:#ADBAC7;"> </span><span style="color:#DCBDFB;">foo</span><span style="color:#ADBAC7;">() {</span></span>
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#768390;">// ...</span></span>
<span class="line"><span style="color:#ADBAC7;"> }</span></span>
<span class="line"><span style="color:#ADBAC7;">}</span></span>
<span class="line"></span></code></pre></div><p>我们要得到其中的 <code>public void foo()</code> 方法,可以写作如下形式。</p><blockquote><p>示例如下</p></blockquote><div class="language-kotlin line-numbers-mode" data-ext="kt"><pre class="shiki github-dark-dimmed" style="background-color:#22272e;" tabindex="0"><code><span class="line"><span style="color:#ADBAC7;">TestFoo::</span><span style="color:#DCBDFB;">class</span><span style="color:#ADBAC7;">.java.</span><span style="color:#DCBDFB;">method</span><span style="color:#ADBAC7;"> {</span></span>
<span class="line"><span style="color:#ADBAC7;"> name </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> </span><span style="color:#96D0FF;">&quot;foo&quot;</span></span>
<span class="line"><span style="color:#ADBAC7;">}</span></span>
<span class="line"></span></code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p>但是,上面的例子<u><strong>是错误的</strong></u>。</p><p>你会发现这个 <code>Class</code> 中有两个 <code>foo</code> 方法,其中一个带有方法参数。</p><p>由于上述例子没有设置 <code>param</code> 的查找条件,得到的结果将会是匹配名称且匹配字节码顺序的第一个方法 <code>public void foo(String string)</code>,而不是我们需要的最后一个方法。</p><p>这是一个<strong>经常会出现的错误</strong><strong>没有方法参数就会丢失方法参数查找条件</strong>的使用问题。</p><p>正确的使用方法如下。</p><blockquote><p>示例如下</p></blockquote><div class="language-kotlin line-numbers-mode" data-ext="kt"><pre class="shiki github-dark-dimmed" style="background-color:#22272e;" tabindex="0"><code><span class="line"><span style="color:#ADBAC7;">TestFoo::</span><span style="color:#DCBDFB;">class</span><span style="color:#ADBAC7;">.java.</span><span style="color:#DCBDFB;">method</span><span style="color:#ADBAC7;"> {</span></span>
<span class="line"><span style="color:#ADBAC7;"> name </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> </span><span style="color:#96D0FF;">&quot;foo&quot;</span></span>
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#768390;">// ✅ 正确的使用方法,添加详细的筛选条件</span></span>
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#DCBDFB;">emptyParam</span><span style="color:#ADBAC7;">()</span></span>
<span class="line"><span style="color:#ADBAC7;">}</span></span>
<span class="line"></span></code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p>至此,上述的示例将可以完美地匹配到 <code>public void foo()</code> 方法。</p><div class="custom-container tip"><p class="custom-container-title">兼容性说明</p><p>在过往历史版本的 API 中是允许匹配不写默认匹配无参方法的做法的,但是最新版本更正了这一问题,请确保你使用的是最新的 API 版本。</p></div><p>在构造方法查找条件中,<u><strong>即使是无参的构造方法也需要设置查找条件</strong></u>。</p><p>假设我们有如下的 <code>Class</code>。</p><blockquote><p>示例如下</p></blockquote><div class="language-java" data-ext="java"><pre class="shiki github-dark-dimmed" style="background-color:#22272e;" tabindex="0"><code><span class="line"><span style="color:#F47067;">public</span><span style="color:#ADBAC7;"> </span><span style="color:#F47067;">class</span><span style="color:#ADBAC7;"> </span><span style="color:#F69D50;">TestFoo</span><span style="color:#ADBAC7;"> {</span></span>
<span class="line"></span>
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#F47067;">public</span><span style="color:#ADBAC7;"> </span><span style="color:#DCBDFB;">TestFoo</span><span style="color:#ADBAC7;">() {</span></span>
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#768390;">// ...</span></span>
<span class="line"><span style="color:#ADBAC7;"> }</span></span>
<span class="line"><span style="color:#ADBAC7;">}</span></span>
<span class="line"></span></code></pre></div><p>我们要得到其中的 <code>public TestFoo()</code> 构造方法,必须写作如下形式。</p><blockquote><p>示例如下</p></blockquote><div class="language-kotlin line-numbers-mode" data-ext="kt"><pre class="shiki github-dark-dimmed" style="background-color:#22272e;" tabindex="0"><code><span class="line"><span style="color:#ADBAC7;">TestFoo::</span><span style="color:#DCBDFB;">class</span><span style="color:#ADBAC7;">.java.</span><span style="color:#DCBDFB;">constructor</span><span style="color:#ADBAC7;"> { </span><span style="color:#DCBDFB;">emptyParam</span><span style="color:#ADBAC7;">() }</span></span>
<span class="line"></span></code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div></div></div><p>上面的例子可以成功获取到 <code>public TestFoo()</code> 构造方法。</p><p>如果你写作 <code>constructor()</code> 而丢失了 <code>emptyParam()</code>,此时查找到的结果会是按照字节码顺序排列的的第一位,<u><strong>可能并不是无参的</strong></u>。</p><div class="custom-container tip"><p class="custom-container-title">兼容性说明</p><p>在过往历史版本的 API 中构造方法不填写任何查找参数会直接找不到构造方法,<u><strong>这是一个 BUG最新版本已经进行修复</strong></u>,请确保你使用的是最新的 API 版本。</p></div><div class="custom-container danger"><p class="custom-container-title">API 行为变更</p><p>在 <strong>1.2.0</strong> 及之后的版本中,<strong>constructor()</strong> 的行为不再是 <strong>constructor { emptyParam() }</strong> 而是 <strong>constructor {}</strong>,请注意行为变更合理调整查找参数。</p></div><h4 id="不设置查找条件" tabindex="-1"><a class="header-anchor" href="#不设置查找条件" aria-hidden="true">#</a> 不设置查找条件</h4><p>在不设置查找条件的情况下,使用 <code>field()</code>、<code>constructor()</code>、<code>method()</code> 将返回当前 <code>Class</code> 下的所有成员对象。</p><p>使用 <code>get(...)</code> 或 <code>give()</code> 的方式获取将只能得到按照字节码顺序排列的的第一位。</p><blockquote><p>示例如下</p></blockquote><div class="language-kotlin line-numbers-mode" data-ext="kt"><pre class="shiki github-dark-dimmed" style="background-color:#22272e;" tabindex="0"><code><span class="line"><span style="color:#ADBAC7;">Test::</span><span style="color:#DCBDFB;">class</span><span style="color:#ADBAC7;">.java.</span><span style="color:#DCBDFB;">field</span><span style="color:#ADBAC7;">().</span><span style="color:#DCBDFB;">get</span><span style="color:#ADBAC7;">(</span><span style="color:#F47067;">..</span><span style="color:#ADBAC7;">.)</span></span>
<span class="line"><span style="color:#ADBAC7;">Test::</span><span style="color:#DCBDFB;">class</span><span style="color:#ADBAC7;">.java.</span><span style="color:#DCBDFB;">method</span><span style="color:#ADBAC7;">().</span><span style="color:#DCBDFB;">give</span><span style="color:#ADBAC7;">()</span></span>
<span class="line"></span></code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div><div class="line-number"></div></div></div><p>如果你想得到全部成员对象,你可以使用 <code>all(...)</code> 或 <code>giveAll()</code></p><blockquote><p>示例如下</p></blockquote><div class="language-kotlin line-numbers-mode" data-ext="kt"><pre class="shiki github-dark-dimmed" style="background-color:#22272e;" tabindex="0"><code><span class="line"><span style="color:#ADBAC7;">Test::</span><span style="color:#DCBDFB;">class</span><span style="color:#ADBAC7;">.java.</span><span style="color:#DCBDFB;">field</span><span style="color:#ADBAC7;">().</span><span style="color:#DCBDFB;">all</span><span style="color:#ADBAC7;">(</span><span style="color:#F47067;">..</span><span style="color:#ADBAC7;">.)</span></span>
<span class="line"><span style="color:#ADBAC7;">Test::</span><span style="color:#DCBDFB;">class</span><span style="color:#ADBAC7;">.java.</span><span style="color:#DCBDFB;">method</span><span style="color:#ADBAC7;">().</span><span style="color:#DCBDFB;">giveAll</span><span style="color:#ADBAC7;">()</span></span>
<span class="line"></span></code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div><div class="line-number"></div></div></div><div class="custom-container tip"><p class="custom-container-title">兼容性说明</p><p>在过往历史版本的 API 中,不设置查找条件将抛出异常,此特性在 <strong>1.2.0</strong> 及之后的版本中加入。</p></div><h4 id="字节码类型" tabindex="-1"><a class="header-anchor" href="#字节码类型" aria-hidden="true">#</a> 字节码类型</h4><p>在字节码调用结果中,<strong>cast</strong> 方法<u><strong>只能</strong></u>指定字节码对应的类型。</p><p>例如我们想得到一个 <code>Boolean</code> 类型的变量,把他转换为 <code>String</code>。</p><p>以下是错误的使用方法。</p><blockquote><p>示例如下</p></blockquote><div class="language-kotlin line-numbers-mode" data-ext="kt"><pre class="shiki github-dark-dimmed" style="background-color:#22272e;" tabindex="0"><code><span class="line"><span style="color:#F47067;">field</span><span style="color:#ADBAC7;"> {</span></span>
<span class="line"><span style="color:#ADBAC7;"> name </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> </span><span style="color:#96D0FF;">&quot;test&quot;</span></span>
<span class="line"><span style="color:#ADBAC7;"> type </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> BooleanType</span></span>
<span class="line"><span style="color:#ADBAC7;">}.</span><span style="color:#DCBDFB;">get</span><span style="color:#ADBAC7;">().</span><span style="color:#DCBDFB;">string</span><span style="color:#ADBAC7;">() </span><span style="color:#768390;">// 错误的使用方法,必须 cast 为字节码目标类型</span></span>
<span class="line"></span></code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p>以下是正确的使用方法。</p><blockquote><p>示例如下</p></blockquote><div class="language-kotlin line-numbers-mode" data-ext="kt"><pre class="shiki github-dark-dimmed" style="background-color:#22272e;" tabindex="0"><code><span class="line"><span style="color:#F47067;">field</span><span style="color:#ADBAC7;"> {</span></span>
<span class="line"><span style="color:#ADBAC7;"> name </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> </span><span style="color:#96D0FF;">&quot;test&quot;</span></span>
<span class="line"><span style="color:#ADBAC7;"> type </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> BooleanType</span></span>
<span class="line"><span style="color:#ADBAC7;">}.</span><span style="color:#DCBDFB;">get</span><span style="color:#ADBAC7;">().</span><span style="color:#DCBDFB;">boolean</span><span style="color:#ADBAC7;">().</span><span style="color:#DCBDFB;">toString</span><span style="color:#ADBAC7;">() </span><span style="color:#768390;">// ✅ 正确的使用方法,得到类型后再进行转换</span></span>
<span class="line"></span></code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><h2 id="常用类型扩展" tabindex="-1"><a class="header-anchor" href="#常用类型扩展" aria-hidden="true">#</a> 常用类型扩展</h2><p>在查找方法、变量的时候我们通常需要指定所查找的类型。</p><blockquote><p>示例如下</p></blockquote><div class="language-kotlin line-numbers-mode" data-ext="kt"><pre class="shiki github-dark-dimmed" style="background-color:#22272e;" tabindex="0"><code><span class="line"><span style="color:#F47067;">field</span><span style="color:#ADBAC7;"> {</span></span>
<span class="line"><span style="color:#ADBAC7;"> name </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> </span><span style="color:#96D0FF;">&quot;test&quot;</span></span>
<span class="line"><span style="color:#ADBAC7;"> type </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> Boolean::</span><span style="color:#DCBDFB;">class</span><span style="color:#ADBAC7;">.javaPrimitiveType</span></span>
<span class="line"><span style="color:#ADBAC7;">}</span></span>
<span class="line"></span></code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p>在 Kotlin 中表达出 <code>Boolean::class.javaPrimitiveType</code> 这个类型的写法很长,感觉并不方便。</p><p>因此,<code>YukiHookAPI</code> 为开发者封装了常见的类型调用,其中包含了 Android 的相关类型和 Java 的常见类型与<strong>原始类型关键字</strong>。</p><p>这个时候上面的类型就可以写作如下形式了。</p><blockquote><p>示例如下</p></blockquote><div class="language-kotlin line-numbers-mode" data-ext="kt"><pre class="shiki github-dark-dimmed" style="background-color:#22272e;" tabindex="0"><code><span class="line"><span style="color:#F47067;">field</span><span style="color:#ADBAC7;"> {</span></span>
<span class="line"><span style="color:#ADBAC7;"> name </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> </span><span style="color:#96D0FF;">&quot;test&quot;</span></span>
<span class="line"><span style="color:#ADBAC7;"> type </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> BooleanType</span></span>
<span class="line"><span style="color:#ADBAC7;">}</span></span>
<span class="line"></span></code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p>在 Java 常见类型中的<strong>原始类型 (或基本类型) 关键字</strong>都已被封装为 <strong>类型 + Type</strong> 的方式,例如 <code>IntType</code>、<code>FloatType</code> (它们的字节码类型为 <code>int</code>、<code>float</code>)。</p><p>相应地,数组类型也有方便的使用方法,假设我们要获得 <code>String[]</code> 类型的数组。</p><p>需要写做 <code>java.lang.reflect.Array.newInstance(String::class.java, 0).javaClass</code> 才能得到这个类型。</p><p>感觉是不是很麻烦,这个时候我们可以使用方法 <code>ArrayClass(StringClass)</code> 来得到这个类型。</p><p>同时由于 <code>String</code> 是常见类型,所以还可以直接使用 <code>StringArrayClass</code> 来得到这个类型。</p><p>一些常见的 Hook 中查找的方法,都有其对应的封装类型以供使用,格式为 <strong>类型 + Class</strong>。</p><p>例如 Hook <code>onCreate</code> 方法需要查找 <code>Bundle::class.java</code> 类型。</p><blockquote><p>示例如下</p></blockquote><div class="language-kotlin line-numbers-mode" data-ext="kt"><pre class="shiki github-dark-dimmed" style="background-color:#22272e;" tabindex="0"><code><span class="line"><span style="color:#DCBDFB;">method</span><span style="color:#ADBAC7;"> {</span></span>
<span class="line"><span style="color:#ADBAC7;"> name </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> </span><span style="color:#96D0FF;">&quot;onCreate&quot;</span></span>
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#DCBDFB;">param</span><span style="color:#ADBAC7;">(BundleClass)</span></span>
<span class="line"><span style="color:#ADBAC7;">}</span></span>
<span class="line"></span></code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p>以下是 Java 中一些特例类型在 <code>YukiHookAPI</code> 中的封装名称。</p><ul><li><p><code>void</code> → <code>UnitType</code></p></li><li><p><code>java.lang.Void</code> → <code>UnitClass</code></p></li><li><p><code>java.lang.Object</code> → <code>AnyClass</code></p></li><li><p><code>java.lang.Integer</code> → <code>IntClass</code></p></li><li><p><code>java.lang.Character</code> → <code>CharClass</code></p></li></ul><div class="custom-container warning"><p class="custom-container-title">注意</p><p>以 <strong>类型 + Type</strong> 封装类型会且仅会表示为 Java <strong>原始类型关键字</strong>,由于 Kotlin 中不存在<strong>原始类型</strong>这个概念,所以它们都会被定义为 <strong>KClass</strong>。</p><p>Java 中共有 9 个<strong>原始类型关键字</strong>,其中 8 个为<strong>原始类型</strong>,分别为 <strong>boolean</strong>、<strong>char</strong>、<strong>byte</strong>、<strong>short</strong>、<strong>int</strong>、<strong>float</strong>、<strong>long</strong>、<strong>double</strong>,其中 <strong>void</strong> 类型是一个特例。</p><p>同时它们都有 Java 自身对应的封装类型,例如 <strong>java.lang.Boolean</strong>、<strong>java.lang.Integer</strong>,这些类型是<u><strong>不相等的</strong></u>,请注意区分。</p><p>同样地,数组也有对应的封装类型,它们也需要与 Java <strong>原始类型关键字</strong> 进行区分。</p><p>例如 <strong>byte[]</strong> 的封装类型为 <strong>ByteArrayType</strong> 或 <strong>ArrayClass(ByteType)</strong>,而 <strong>Byte[]</strong> 的封装类型为 <strong>ByteArrayClass</strong> 或 <strong>ArrayClass(ByteClass)</strong>,这些类型也是<u><strong>不相等的</strong></u>。</p></div><div class="custom-container tip"><p class="custom-container-title">小提示</p><p>更多类型可查看 <a href="../public/com/highcapable/yukihookapi/hook/type/android/ComponentTypeFactory">ComponentTypeFactory</a>、<a href="../public/com/highcapable/yukihookapi/hook/type/android/GraphicsTypeFactory">GraphicsTypeFactory</a>、<a href="../public/com/highcapable/yukihookapi/hook/type/android/ViewTypeFactory">ViewTypeFactory</a>、<a href="../public/com/highcapable/yukihookapi/hook/type/java/VariableTypeFactory">VariableTypeFactory</a>。</p></div><p>同时,欢迎你能贡献更多的常用类型。</p>`,363);function N(M,O){const l=e("ExternalLinkIcon"),p=e("Badge");return t(),r("div",null,[d,A,s("p",null,[s("s",null,[n("此功能的核心部分已被解耦合为 "),s("a",y,[n("YukiReflection"),a(l)]),n(" 项目,它可以独立使用于任何 Java、Android 项目中。")])]),D,s("div",B,[C,s("p",null,[n("从 "),u,n(" 版本开始,"),v,n(" 已将自身的反射 API 部分迁移至 "),s("a",m,[n("KavaRef"),a(l)]),n(",我们不再推荐使用 "),b,n(" 自身的反射 API这些 API 已被标记为弃用。")]),F,s("p",null,[n("如果你依然在使用 "),k,n(" 的反射 API 部分,请参考 "),s("a",h,[n("这里"),a(l)]),n(" 的迁移文档,这将跳转到 "),g,n(" 的文档。")])]),s("div",q,[T,s("h3",x,[f,n(" 模糊查找 "),a(p,{type:"tip",text:"Beta",vertical:"middle"})]),P,s("div",S,[_,s("p",null,[s("s",null,[n("在 "),j,n(" 发布 "),I,n(" 版本后,此功能将被标记为作废,且不再会迁移到 "),s("a",L,[n("YukiReflection"),a(l)]),n("。")])]),s("p",null,[n("我们欢迎各位开发者开始使用 "),s("a",H,[n("DexKit"),a(l)]),n(",它是一个使用 C++ 实现的 "),R,n(" 高性能运行时解析库,在性能方面比 Java 层更加高效与优秀,目前尚在开发阶段,欢迎提出宝贵建议。")])]),Y])])}const V=c(i,[["render",N],["__file","reflection.html.vue"]]);export{V as default};