import{_ as l,r as o,o as p,c as t,b as s,d as i,a as n,e}from"./app.f643a53b.js";const c={},r=n(`<h1 id="host-resource-injection-extension" tabindex="-1"><a class="header-anchor" href="#host-resource-injection-extension" aria-hidden="true">#</a> Host Resource Injection Extension</h1><blockquote><p>This is an extension that injects Module App&#39;s Resources, <code>Activity</code> components, and <code>Context</code> topics into the Host App.</p></blockquote><p>Before using the following functions, in order to prevent Resource Id from conflicting with each other, you need to modify the Resource Id in the <code>build.gradle</code> of the current Xposed Module project.</p><ul><li>Kotlin Gradle DSL</li></ul><div class="language-kotlin ext-kt line-numbers-mode"><pre class="shiki" style="background-color:#22272e;"><code><span class="line"><span style="color:#ADBAC7;">android {</span></span>
<span class="line"><span style="color:#ADBAC7;">    androidResources.additionalParameters(</span><span style="color:#96D0FF;">&quot;--allow-reserved-package-id&quot;</span><span style="color:#ADBAC7;">, </span><span style="color:#96D0FF;">&quot;--package-id&quot;</span><span style="color:#ADBAC7;">, </span><span style="color:#96D0FF;">&quot;0x64&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></div><ul><li>Groovy</li></ul><div class="language-groovy ext-groovy line-numbers-mode"><pre class="shiki" style="background-color:#22272e;"><code><span class="line"><span style="color:#ADBAC7;">android {</span></span>
<span class="line"><span style="color:#ADBAC7;">    aaptOptions</span><span style="color:#F47067;">.</span><span style="color:#ADBAC7;">additionalParameters </span><span style="color:#96D0FF;">&#39;--allow-reserved-package-id&#39;</span><span style="color:#ADBAC7;">, </span><span style="color:#96D0FF;">&#39;--package-id&#39;</span><span style="color:#ADBAC7;">, </span><span style="color:#96D0FF;">&#39;0x64&#39;</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><div class="custom-container warning"><p class="custom-container-title">Notice</p><p>The sample Resource Id value provided is for reference only, <strong>0x7f</strong> cannot be used, the default is <strong>0x64</strong>.</p><p>In order to prevent the existence of multiple Xposed Modules in the current Host App, it is recommended to customize your own Resource Id.</p></div><h2 id="inject-module-app-s-resources" tabindex="-1"><a class="header-anchor" href="#inject-module-app-s-resources" aria-hidden="true">#</a> Inject Module App&#39;s Resources</h2><p>After the Host App is hooked, we can directly inject the <code>Context</code> obtained in the Hooker into the current Module App&#39;s Resources.</p><blockquote><p>The following example</p></blockquote><div class="language-kotlin ext-kt line-numbers-mode"><pre class="shiki" style="background-color:#22272e;"><code><span class="line"><span style="color:#ADBAC7;">injectMember {</span></span>
<span class="line"><span style="color:#ADBAC7;">    method {</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;">        param(</span><span style="color:#F69D50;">BundleClass</span><span style="color:#ADBAC7;">)</span></span>
<span class="line"><span style="color:#ADBAC7;">    }</span></span>
<span class="line"><span style="color:#ADBAC7;">    afterHook {</span></span>
<span class="line"><span style="color:#ADBAC7;">        instance</span><span style="color:#F47067;">&lt;</span><span style="color:#F69D50;">Activity</span><span style="color:#F47067;">&gt;</span><span style="color:#ADBAC7;">().</span><span style="color:#6CB6FF;">also</span><span style="color:#ADBAC7;"> {</span></span>
<span class="line"><span style="color:#ADBAC7;">            </span><span style="color:#768390;">// &lt;Scenario 1&gt; Inject Module App&#39;s Resources through Context</span></span>
<span class="line"><span style="color:#ADBAC7;">            it.injectModuleAppResources()</span></span>
<span class="line"><span style="color:#ADBAC7;">            </span><span style="color:#768390;">// &lt;Scenario 2&gt; Get the Host App&#39;s Resources directly and inject the Module App&#39;s Resources</span></span>
<span class="line"><span style="color:#ADBAC7;">            it.resources.injectModuleAppResources()</span></span>
<span class="line"><span style="color:#ADBAC7;">            </span><span style="color:#768390;">// Use the Module App&#39;s Resource Id directly</span></span>
<span class="line"><span style="color:#ADBAC7;">            it.getString(</span><span style="color:#F69D50;">R</span><span style="color:#ADBAC7;">.id.app_name)</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></div><p>You can also inject current Module App&#39;s Resources directly in <code>AppLifecycle</code>.</p><blockquote><p>The following example</p></blockquote><div class="language-kotlin ext-kt line-numbers-mode"><pre class="shiki" style="background-color:#22272e;"><code><span class="line"><span style="color:#ADBAC7;">onAppLifecycle {</span></span>
<span class="line"><span style="color:#ADBAC7;">    onCreate {</span></span>
<span class="line"><span style="color:#ADBAC7;">        </span><span style="color:#768390;">// Globally inject Module App&#39;s Resources, but only in the global lifecycle</span></span>
<span class="line"><span style="color:#ADBAC7;">        </span><span style="color:#768390;">// Methods like ImageView.setImageResource need to be injected separately in Activity</span></span>
<span class="line"><span style="color:#ADBAC7;">        </span><span style="color:#768390;">// &lt;Scenario 1&gt; Inject Module App&#39;s Resources through Context</span></span>
<span class="line"><span style="color:#ADBAC7;">        injectModuleAppResources()</span></span>
<span class="line"><span style="color:#ADBAC7;">        </span><span style="color:#768390;">// &lt;Scenario 2&gt; Get the Host App&#39;s Resources directly and inject the Module App&#39;s Resources</span></span>
<span class="line"><span style="color:#ADBAC7;">        resources.injectModuleAppResources()</span></span>
<span class="line"><span style="color:#ADBAC7;">        </span><span style="color:#768390;">// Use the Module App&#39;s Resource Id directly</span></span>
<span class="line"><span style="color:#ADBAC7;">        getString(</span><span style="color:#F69D50;">R</span><span style="color:#ADBAC7;">.id.app_name)</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></div><div class="custom-container tip"><p class="custom-container-title">Tips</p><p>For more functions, please refer to the <a href="../public/com/highcapable/yukihookapi/hook/factory/YukiHookFactory#context-resources-injectmoduleappresources-ext-method">Context+Resources.injectModuleAppResources</a> method.</p></div><h2 id="register-module-app-s-activity" tabindex="-1"><a class="header-anchor" href="#register-module-app-s-activity" aria-hidden="true">#</a> Register Module App&#39;s Activity</h2><p>When the <code>Activity</code> of all applications in the Android system starts, it needs to be registered in <code>AndroidManifest.xml</code>.</p><p>During the Hook process, if we want to directly start the unregistered <code>Activity</code> in the Module App through the Host App, what should we do?</p><p>After the Host App is hooked, we can directly register the <code>Activity</code> proxy of the current Module App in the <code>Context</code> obtained in the Hooker.</p><blockquote><p>The following example</p></blockquote><div class="language-kotlin ext-kt line-numbers-mode"><pre class="shiki" style="background-color:#22272e;"><code><span class="line"><span style="color:#ADBAC7;">injectMember {</span></span>
<span class="line"><span style="color:#ADBAC7;">    method {</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;">        param(</span><span style="color:#F69D50;">BundleClass</span><span style="color:#ADBAC7;">)</span></span>
<span class="line"><span style="color:#ADBAC7;">    }</span></span>
<span class="line"><span style="color:#ADBAC7;">    afterHook {</span></span>
<span class="line"><span style="color:#ADBAC7;">        instance</span><span style="color:#F47067;">&lt;</span><span style="color:#F69D50;">Activity</span><span style="color:#F47067;">&gt;</span><span style="color:#ADBAC7;">().registerModuleAppActivities()</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></div><p>You can also register the current Module App&#39;s <code>Activity</code> proxy directly in <code>AppLifecycle</code>.</p><blockquote><p>The following example</p></blockquote><div class="language-kotlin ext-kt line-numbers-mode"><pre class="shiki" style="background-color:#22272e;"><code><span class="line"><span style="color:#ADBAC7;">onAppLifecycle {</span></span>
<span class="line"><span style="color:#ADBAC7;">    onCreate {</span></span>
<span class="line"><span style="color:#ADBAC7;">        registerModuleAppActivities()</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></div><p>If the <code>proxy</code> parameter is not filled in, the API will automatically obtain the current Host App&#39;s launching entry <code>Activity</code> for proxying according to the current <code>Context</code>.</p><p>Usually, it works, but the above situation will fail in some apps, for example, some <code>Activity</code> will add launching parameters to the registration list, so we need to use another solution.</p><p>If the unregistered <code>Activity</code> cannot be launched correctly, we can manually get the Host App&#39;s <code>AndroidManifest.xml</code> for analysis to get a registered <code>Activity</code> tag and get the <code>name</code>.</p><p>You need to choose an unneeded <code>Activity</code> that may not be used by the current Host App as a &quot;puppet&quot; to proxy it, which usually works.</p><p>For example, we have found a suitable <code>Activity</code> that can be proxied.</p><blockquote><p>The following example</p></blockquote><div class="language-xml ext-xml line-numbers-mode"><pre class="shiki" style="background-color:#22272e;"><code><span class="line"><span style="color:#ADBAC7;">&lt;</span><span style="color:#8DDB8C;">activity</span></span>
<span class="line"><span style="color:#ADBAC7;">    </span><span style="color:#6CB6FF;">android:name</span><span style="color:#ADBAC7;">=</span><span style="color:#96D0FF;">&quot;com.demo.test.activity.TestActivity&quot;</span></span>
<span class="line"><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></div><p>According to the <code>name</code>, we only need to add this parameter to the method for registration.</p><blockquote><p>The following example</p></blockquote><div class="language-kotlin ext-kt line-numbers-mode"><pre class="shiki" style="background-color:#22272e;"><code><span class="line"><span style="color:#ADBAC7;">registerModuleAppActivities(proxy </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> </span><span style="color:#96D0FF;">&quot;com.demo.test.activity.TestActivity&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>Alternatively, if you write a <code>stub</code> for the Host App&#39;s class, you can register it directly through the <code>Class</code> object.</p><blockquote><p>The following example</p></blockquote><div class="language-kotlin ext-kt line-numbers-mode"><pre class="shiki" style="background-color:#22272e;"><code><span class="line"><span style="color:#ADBAC7;">registerModuleAppActivities(TestActivity::</span><span style="color:#6CB6FF;">class</span><span style="color:#ADBAC7;">.java)</span></span>
<span class="line"></span></code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div></div></div><p>After the registration is complete, extends the <code>Activity</code> in the Module App you need to use the Host App to start by <code>ModuleAppActivity</code> or <code>ModuleAppCompatActivity</code>.</p><p>These <code>Activity</code> now live seamlessly in the Host App without registration.</p><blockquote><p>The following example</p></blockquote><div class="language-kotlin ext-kt line-numbers-mode"><pre class="shiki" style="background-color:#22272e;"><code><span class="line"><span style="color:#F47067;">class</span><span style="color:#ADBAC7;"> </span><span style="color:#F69D50;">HostTestActivity</span><span style="color:#ADBAC7;"> </span><span style="color:#F47067;">:</span><span style="color:#ADBAC7;"> </span><span style="color:#6CB6FF;">ModuleAppActivity</span><span style="color:#ADBAC7;">() {</span></span>
<span class="line"></span>
<span class="line"><span style="color:#ADBAC7;">    </span><span style="color:#F47067;">override</span><span style="color:#ADBAC7;"> </span><span style="color:#F47067;">fun</span><span style="color:#ADBAC7;"> </span><span style="color:#DCBDFB;">onCreate</span><span style="color:#ADBAC7;">(savedInstanceState</span><span style="color:#F47067;">:</span><span style="color:#ADBAC7;"> </span><span style="color:#F69D50;">Bundle?</span><span style="color:#ADBAC7;">) {</span></span>
<span class="line"><span style="color:#ADBAC7;">        </span><span style="color:#6CB6FF;">super</span><span style="color:#ADBAC7;">.onCreate(savedInstanceState)</span></span>
<span class="line"><span style="color:#ADBAC7;">        </span><span style="color:#768390;">// Module App&#39;s Resources have been injected automatically</span></span>
<span class="line"><span style="color:#ADBAC7;">        </span><span style="color:#768390;">// You can directly use xml to load the layout</span></span>
<span class="line"><span style="color:#ADBAC7;">        setContentView(</span><span style="color:#F69D50;">R</span><span style="color:#ADBAC7;">.layout.activity_main)</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></div><p>If you need to extends <code>ModuleAppCompatActivity</code>, you need to set the AppCompat theme manually.</p><blockquote><p>The following example</p></blockquote><div class="language-kotlin ext-kt line-numbers-mode"><pre class="shiki" style="background-color:#22272e;"><code><span class="line"><span style="color:#F47067;">class</span><span style="color:#ADBAC7;"> </span><span style="color:#F69D50;">HostTestActivity</span><span style="color:#ADBAC7;"> </span><span style="color:#F47067;">:</span><span style="color:#ADBAC7;"> </span><span style="color:#6CB6FF;">ModuleAppCompatActivity</span><span style="color:#ADBAC7;">() {</span></span>
<span class="line"></span>
<span class="line"><span style="color:#ADBAC7;">    </span><span style="color:#768390;">// The theme name here is for reference only</span></span>
<span class="line"><span style="color:#ADBAC7;">    </span><span style="color:#768390;">// Please fill in the theme name already in your Module App</span></span>
<span class="line"><span style="color:#ADBAC7;">    </span><span style="color:#F47067;">override</span><span style="color:#ADBAC7;"> </span><span style="color:#F47067;">val</span><span style="color:#ADBAC7;"> moduleTheme get() </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> </span><span style="color:#F69D50;">R</span><span style="color:#ADBAC7;">.</span><span style="color:#F69D50;">style</span><span style="color:#F47067;">.</span><span style="color:#F69D50;">Theme_AppCompat</span></span>
<span class="line"></span>
<span class="line"><span style="color:#ADBAC7;">    </span><span style="color:#F47067;">override</span><span style="color:#ADBAC7;"> </span><span style="color:#F47067;">fun</span><span style="color:#ADBAC7;"> </span><span style="color:#DCBDFB;">onCreate</span><span style="color:#ADBAC7;">(savedInstanceState</span><span style="color:#F47067;">:</span><span style="color:#ADBAC7;"> </span><span style="color:#F69D50;">Bundle?</span><span style="color:#ADBAC7;">) {</span></span>
<span class="line"><span style="color:#ADBAC7;">        </span><span style="color:#6CB6FF;">super</span><span style="color:#ADBAC7;">.onCreate(savedInstanceState)</span></span>
<span class="line"><span style="color:#ADBAC7;">        </span><span style="color:#768390;">// Module App&#39;s Resources have been injected automatically</span></span>
<span class="line"><span style="color:#ADBAC7;">        </span><span style="color:#768390;">// You can directly use xml to load the layout</span></span>
<span class="line"><span style="color:#ADBAC7;">        setContentView(</span><span style="color:#F69D50;">R</span><span style="color:#ADBAC7;">.layout.activity_main)</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></div><p>After all the above steps are completed, you can happily call <code>startActivity</code> anywhere in the (Xposed) Host environment where a <code>Context</code> exists.</p><blockquote><p>The following example</p></blockquote><div class="language-kotlin ext-kt line-numbers-mode"><pre class="shiki" style="background-color:#22272e;"><code><span class="line"><span style="color:#F47067;">val</span><span style="color:#ADBAC7;"> context</span><span style="color:#F47067;">:</span><span style="color:#ADBAC7;"> </span><span style="color:#F69D50;">Context</span><span style="color:#ADBAC7;"> </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> ... </span><span style="color:#768390;">// Assume this is your Context</span></span>
<span class="line"><span style="color:#ADBAC7;">context.startActivity(context, HostTestActivity::</span><span style="color:#6CB6FF;">class</span><span style="color:#ADBAC7;">.java)</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>The <code>proxy</code> parameter we set in the <code>registerModuleAppActivities</code> method above is the default global proxy <code>Activity</code>.</p><p>If you need to specify a delegated <code>Activity</code> to use another Host App&#39;s <code>Activity</code> as a proxy, you can refer to the following method.</p><blockquote><p>The following example</p></blockquote><div class="language-kotlin ext-kt line-numbers-mode"><pre class="shiki" style="background-color:#22272e;"><code><span class="line"><span style="color:#F47067;">class</span><span style="color:#ADBAC7;"> </span><span style="color:#F69D50;">HostTestActivity</span><span style="color:#ADBAC7;"> </span><span style="color:#F47067;">:</span><span style="color:#ADBAC7;"> </span><span style="color:#6CB6FF;">ModuleAppActivity</span><span style="color:#ADBAC7;">() {</span></span>
<span class="line"></span>
<span class="line"><span style="color:#ADBAC7;">    </span><span style="color:#768390;">// Specify an additional proxy Activity class name</span></span>
<span class="line"><span style="color:#ADBAC7;">    </span><span style="color:#768390;">// Which must also exist in the Host App&#39;s AndroidManifest</span></span>
<span class="line"><span style="color:#ADBAC7;">    </span><span style="color:#F47067;">override</span><span style="color:#ADBAC7;"> </span><span style="color:#F47067;">val</span><span style="color:#ADBAC7;"> proxyClassName get() </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> </span><span style="color:#96D0FF;">&quot;com.demo.test.activity.OtherActivity&quot;</span></span>
<span class="line"></span>
<span class="line"><span style="color:#ADBAC7;">    </span><span style="color:#F47067;">override</span><span style="color:#ADBAC7;"> </span><span style="color:#F47067;">fun</span><span style="color:#ADBAC7;"> </span><span style="color:#DCBDFB;">onCreate</span><span style="color:#ADBAC7;">(savedInstanceState</span><span style="color:#F47067;">:</span><span style="color:#ADBAC7;"> </span><span style="color:#F69D50;">Bundle?</span><span style="color:#ADBAC7;">) {</span></span>
<span class="line"><span style="color:#ADBAC7;">        </span><span style="color:#6CB6FF;">super</span><span style="color:#ADBAC7;">.onCreate(savedInstanceState)</span></span>
<span class="line"><span style="color:#ADBAC7;">        </span><span style="color:#768390;">// Module App&#39;s Resources have been injected automatically</span></span>
<span class="line"><span style="color:#ADBAC7;">        </span><span style="color:#768390;">// You can directly use xml to load the layout</span></span>
<span class="line"><span style="color:#ADBAC7;">        setContentView(</span><span style="color:#F69D50;">R</span><span style="color:#ADBAC7;">. layout. activity_main)</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></div><div class="custom-container tip"><p class="custom-container-title">Tips</p><p>For more functions, please refer to the <a href="../public/com/highcapable/yukihookapi/hook/factory/YukiHookFactory#context-registermoduleappactivities-ext-method">Context.registerModuleAppActivities</a> method.</p></div><h2 id="create-contextthemewrapper-proxy" tabindex="-1"><a class="header-anchor" href="#create-contextthemewrapper-proxy" aria-hidden="true">#</a> Create ContextThemeWrapper Proxy</h2><p>Sometimes, we need to use <code>MaterialAlertDialogBuilder</code> to beautify our own dialogs in the Host App, but we can&#39;t create them without the AppCompat theme.</p><ul><li>Will got the following exception</li></ul><div class="language-text ext-text"><pre class="shiki" style="background-color:#22272e;"><code><span class="line"><span style="color:#adbac7;">The style on this component requires your app theme to be Theme.AppCompat (or a descendant).</span></span>
<span class="line"><span style="color:#adbac7;"></span></span></code></pre></div><p>At this time, we want to use <code>MaterialAlertDialogBuilder</code> to create a dialog in the current <code>Activity</code> of the Host App being hooked, you can have the following methods.</p><blockquote><p>The following example</p></blockquote><div class="language-kotlin ext-kt line-numbers-mode"><pre class="shiki" style="background-color:#22272e;"><code><span class="line"><span style="color:#ADBAC7;">injectMember {</span></span>
<span class="line"><span style="color:#ADBAC7;">    method {</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;">        param(</span><span style="color:#F69D50;">BundleClass</span><span style="color:#ADBAC7;">)</span></span>
<span class="line"><span style="color:#ADBAC7;">    }</span></span>
<span class="line"><span style="color:#ADBAC7;">    afterHook {</span></span>
<span class="line"><span style="color:#ADBAC7;">        </span><span style="color:#768390;">// Use applyModuleTheme to create a theme resource in the current Module App</span></span>
<span class="line"><span style="color:#ADBAC7;">        </span><span style="color:#F47067;">val</span><span style="color:#ADBAC7;"> appCompatContext </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> instance</span><span style="color:#F47067;">&lt;</span><span style="color:#F69D50;">Activity</span><span style="color:#F47067;">&gt;</span><span style="color:#ADBAC7;">().applyModuleTheme(</span><span style="color:#F69D50;">R</span><span style="color:#ADBAC7;">.</span><span style="color:#F69D50;">style</span><span style="color:#F47067;">.</span><span style="color:#F69D50;">Theme_AppCompat</span><span style="color:#ADBAC7;">)</span></span>
<span class="line"><span style="color:#ADBAC7;">        </span><span style="color:#768390;">// Directly use this Context that wraps the Module App&#39;s theme to create a dialog</span></span>
<span class="line"><span style="color:#ADBAC7;">        </span><span style="color:#F69D50;">MaterialAlertDialogBuilder</span><span style="color:#ADBAC7;">(appCompatContext)</span></span>
<span class="line"><span style="color:#ADBAC7;">            .setTitle(</span><span style="color:#96D0FF;">&quot;AppCompat Theme Dialog&quot;</span><span style="color:#ADBAC7;">)</span></span>
<span class="line"><span style="color:#ADBAC7;">            .setMessage(</span><span style="color:#96D0FF;">&quot;I am an AppCompat theme dialog displayed in the Host App.&quot;</span><span style="color:#ADBAC7;">)</span></span>
<span class="line"><span style="color:#ADBAC7;">            .setPositiveButton(</span><span style="color:#96D0FF;">&quot;OK&quot;</span><span style="color:#ADBAC7;">, </span><span style="color:#6CB6FF;">null</span><span style="color:#ADBAC7;">)</span></span>
<span class="line"><span style="color:#ADBAC7;">            .show()</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></div><p>You can also set the system (native) night mode and day mode on the current <code>Context</code> through <code>uiMode</code>.</p><p>Which requires at least Android 10 and above system version support and the current theme contains night mode related elements.</p><blockquote><p>The following example</p></blockquote><div class="language-kotlin ext-kt line-numbers-mode"><pre class="shiki" style="background-color:#22272e;"><code><span class="line"><span style="color:#ADBAC7;">injectMember {</span></span>
<span class="line"><span style="color:#ADBAC7;">    method {</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;">        param(</span><span style="color:#F69D50;">BundleClass</span><span style="color:#ADBAC7;">)</span></span>
<span class="line"><span style="color:#ADBAC7;">    }</span></span>
<span class="line"><span style="color:#ADBAC7;">    afterHook {</span></span>
<span class="line"><span style="color:#ADBAC7;">        </span><span style="color:#768390;">// Define the theme resource in the current Module App</span></span>
<span class="line"><span style="color:#ADBAC7;">        </span><span style="color:#F47067;">var</span><span style="color:#ADBAC7;"> appCompatContext</span><span style="color:#F47067;">:</span><span style="color:#ADBAC7;"> </span><span style="color:#F69D50;">ModuleContextThemeWrapper</span></span>
<span class="line"><span style="color:#ADBAC7;">        </span><span style="color:#768390;">// &lt;Scenario 1&gt; Get the Configuration object directly to set</span></span>
<span class="line"><span style="color:#ADBAC7;">        appCompatContext </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> instance</span><span style="color:#F47067;">&lt;</span><span style="color:#F69D50;">Activity</span><span style="color:#F47067;">&gt;</span><span style="color:#ADBAC7;">()</span></span>
<span class="line"><span style="color:#ADBAC7;">            .applyModuleTheme(</span><span style="color:#F69D50;">R</span><span style="color:#ADBAC7;">.</span><span style="color:#F69D50;">style</span><span style="color:#F47067;">.</span><span style="color:#F69D50;">Theme_AppCompat</span><span style="color:#ADBAC7;">)</span></span>
<span class="line"><span style="color:#ADBAC7;">            .applyConfiguration { uiMode </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> </span><span style="color:#F69D50;">Configuration</span><span style="color:#ADBAC7;">.</span><span style="color:#F69D50;">UI_MODE_NIGHT_YES</span><span style="color:#ADBAC7;"> }</span></span>
<span class="line"><span style="color:#ADBAC7;">        </span><span style="color:#768390;">// &lt;Scenario 2&gt; Create a new Configuration object</span></span>
<span class="line"><span style="color:#ADBAC7;">        </span><span style="color:#768390;">// This solution will destroy the original font scaling and other settings in the current Host App</span></span>
<span class="line"><span style="color:#ADBAC7;">        </span><span style="color:#768390;">// You need to manually re-pass parameters such as densityDpi</span></span>
<span class="line"><span style="color:#ADBAC7;">        appCompatContext </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> instance</span><span style="color:#F47067;">&lt;</span><span style="color:#F69D50;">Activity</span><span style="color:#F47067;">&gt;</span><span style="color:#ADBAC7;">().applyModuleTheme(</span></span>
<span class="line"><span style="color:#ADBAC7;">            theme </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> </span><span style="color:#F69D50;">R</span><span style="color:#ADBAC7;">.</span><span style="color:#F69D50;">style</span><span style="color:#F47067;">.</span><span style="color:#F69D50;">Theme_AppCompat</span><span style="color:#ADBAC7;">,</span></span>
<span class="line"><span style="color:#ADBAC7;">            configuration </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> </span><span style="color:#F69D50;">Configuration</span><span style="color:#ADBAC7;">().</span><span style="color:#6CB6FF;">apply</span><span style="color:#ADBAC7;"> { uiMode </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> </span><span style="color:#F69D50;">Configuration</span><span style="color:#ADBAC7;">.</span><span style="color:#F69D50;">UI_MODE_NIGHT_YES</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;">// Directly use this Context that wraps the Module App&#39;s theme to create a dialog</span></span>
<span class="line"><span style="color:#ADBAC7;">        </span><span style="color:#F69D50;">MaterialAlertDialogBuilder</span><span style="color:#ADBAC7;">(appCompatContext)</span></span>
<span class="line"><span style="color:#ADBAC7;">            .setTitle(</span><span style="color:#96D0FF;">&quot;AppCompat Theme Dialog&quot;</span><span style="color:#ADBAC7;">)</span></span>
<span class="line"><span style="color:#ADBAC7;">            .setMessage(</span><span style="color:#96D0FF;">&quot;I am an AppCompat theme dialog displayed in the Host App.&quot;</span><span style="color:#ADBAC7;">)</span></span>
<span class="line"><span style="color:#ADBAC7;">            .setPositiveButton(</span><span style="color:#96D0FF;">&quot;OK&quot;</span><span style="color:#ADBAC7;">, </span><span style="color:#6CB6FF;">null</span><span style="color:#ADBAC7;">)</span></span>
<span class="line"><span style="color:#ADBAC7;">            .show()</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 class="line-number"></div><div class="line-number"></div><div class="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>This way, we can create dialogs in the Host App very simply using <code>MaterialAlertDialogBuilder</code>.</p>`,65),d={class:"custom-container warning"},u=s("p",{class:"custom-container-title"},"Possible Problems",-1),A=s("p",null,[e("Because some "),s("strong",null,"androidx"),e(" dependent libraries or custom themes used by some apps may interfere with the actual style of the current "),s("strong",null,"MaterialAlertDialog"),e(", such as the button style of the dialog.")],-1),y=e("You can refer to the "),v=s("strong",null,"Module App Demo",-1),m=e(" in this case and see "),h={href:"https://github.com/fankes/YukiHookAPI/tree/master/demo-module/src/main/java/com/highcapable/yukihookapi/demo_module/hook/factory/ComponentCompatFactory.kt",target:"_blank",rel:"noopener noreferrer"},C=e("here is the sample code"),D=e(" to fix this problem."),b=s("p",null,[s("strong",null,"ClassCastException"),e(" may occur when some apps are created, please manually specify a new "),s("strong",null,"Configuration"),e(" instance to fix.")],-1),B=n(`<div class="custom-container tip"><p class="custom-container-title">Tips</p><p>For more functions, please refer to the <a href="../public/com/highcapable/yukihookapi/hook/factory/YukiHookFactory#context-applymoduletheme-ext-method">Context.applyModuleTheme</a> method.</p></div><h2 id="classloader-conflict-problem" tabindex="-1"><a class="header-anchor" href="#classloader-conflict-problem" aria-hidden="true">#</a> ClassLoader Conflict Problem</h2><p>The content introduced on this page is to directly inject the resources of the Module App into the Host App.</p><p>Since the Module App and the Host App are not in the same process (the same <strong>APK</strong>), there may be a <code>ClassLoader</code> conflict.</p><p>If a <code>ClassLoader</code> conflict occurs, you may encounter a <code>ClassCastException</code>.</p><p><code>YukiHookAPI</code> has solved the problem of possible conflicts by default, and you need to configure the exclusion list by yourself in other cases.</p><p>The exclusion list determines whether these <code>Class</code> need to be loaded by the Module App or the Host App&#39;s <code>ClassLoader</code>.</p><blockquote><p>The following example</p></blockquote><div class="language-kotlin ext-kt line-numbers-mode"><pre class="shiki" style="background-color:#22272e;"><code><span class="line"><span style="color:#768390;">// Exclude Class names belonging to the Host App</span></span>
<span class="line"><span style="color:#768390;">// They will be loaded by the Host App&#39;s ClassLoader</span></span>
<span class="line"><span style="color:#768390;">// \u2757The following content is for demonstration only</span></span>
<span class="line"><span style="color:#768390;">// DO NOT USE IT DIRECTLY, please refer to your actual situation</span></span>
<span class="line"><span style="color:#F69D50;">ModuleClassLoader</span><span style="color:#ADBAC7;">.excludeHostClasses(</span></span>
<span class="line"><span style="color:#ADBAC7;">    </span><span style="color:#96D0FF;">&quot;androidx.core.app.ActivityCompat&quot;</span><span style="color:#ADBAC7;">,</span></span>
<span class="line"><span style="color:#ADBAC7;">    </span><span style="color:#96D0FF;">&quot;com.demo.Test&quot;</span></span>
<span class="line"><span style="color:#ADBAC7;">)</span></span>
<span class="line"><span style="color:#768390;">// Exclude Class names belonging to the Module App</span></span>
<span class="line"><span style="color:#768390;">// They will be loaded by the ClassLoader of the Module App (the current Hook process)</span></span>
<span class="line"><span style="color:#768390;">// \u2757The following content is for demonstration only</span></span>
<span class="line"><span style="color:#768390;">// DO NOT USE IT DIRECTLY, please refer to your actual situation</span></span>
<span class="line"><span style="color:#F69D50;">ModuleClassLoader</span><span style="color:#ADBAC7;">.excludeModuleClasses(</span></span>
<span class="line"><span style="color:#ADBAC7;">    </span><span style="color:#96D0FF;">&quot;com.demo.entry.HookEntry&quot;</span><span style="color:#ADBAC7;">,</span></span>
<span class="line"><span style="color:#ADBAC7;">    </span><span style="color:#96D0FF;">&quot;com.demo.controller.ModuleController&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 class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="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>You need to set it before the method of injecting Module App&#39;s resources into the Host App is executed to take effect.</p><p>This function is only to solve the situation that <strong><code>Class</code> with the same name</strong> may exist in the Host App and Module App, such as shared SDK and dependencies.</p><p>In most cases, you will not use this function.</p><div class="custom-container tip"><p class="custom-container-title">Tips</p><p>For more functions, please refer to <a href="../public/com/highcapable/yukihookapi/hook/xposed/parasitic/reference/ModuleClassLoader">ModuleClassLoader</a>.</p></div>`,13);function g(F,f){const a=o("ExternalLinkIcon");return p(),t("div",null,[r,s("div",d,[u,A,s("p",null,[y,v,m,s("a",h,[C,i(a)]),D]),b]),B])}const x=l(c,[["render",g],["__file","host-inject.html.vue"]]);export{x as default};
