feat: update demo

This commit is contained in:
2025-06-16 17:05:36 +08:00
parent c8f1e3441e
commit 242322954a
4 changed files with 51 additions and 59 deletions

View File

@@ -47,6 +47,8 @@ dependencies {
implementation(projects.yukihookapiCore) implementation(projects.yukihookapiCore)
ksp(projects.yukihookapiKspXposed) ksp(projects.yukihookapiKspXposed)
ksp(com.highcapable.hikage.hikage.compiler) ksp(com.highcapable.hikage.hikage.compiler)
implementation(com.highcapable.kavaref.kavaref.core)
implementation(com.highcapable.kavaref.kavaref.extension)
implementation(com.highcapable.hikage.hikage.core) implementation(com.highcapable.hikage.hikage.core)
implementation(com.highcapable.hikage.hikage.extension) implementation(com.highcapable.hikage.hikage.extension)
implementation(com.highcapable.hikage.hikage.widget.androidx) implementation(com.highcapable.hikage.hikage.widget.androidx)

View File

@@ -26,8 +26,11 @@ package com.highcapable.yukihookapi.demo_module.hook
import android.app.Activity import android.app.Activity
import android.content.Intent import android.content.Intent
import android.os.Build import android.os.Build
import android.os.Bundle
import android.widget.Button import android.widget.Button
import com.google.android.material.dialog.MaterialAlertDialogBuilder import com.google.android.material.dialog.MaterialAlertDialogBuilder
import com.highcapable.kavaref.KavaRef.Companion.resolve
import com.highcapable.kavaref.extension.ArrayClass
import com.highcapable.yukihookapi.YukiHookAPI import com.highcapable.yukihookapi.YukiHookAPI
import com.highcapable.yukihookapi.annotation.xposed.InjectYukiHookWithXposed import com.highcapable.yukihookapi.annotation.xposed.InjectYukiHookWithXposed
import com.highcapable.yukihookapi.demo_module.R import com.highcapable.yukihookapi.demo_module.R
@@ -36,15 +39,7 @@ import com.highcapable.yukihookapi.demo_module.hook.factory.compatStyle
import com.highcapable.yukihookapi.demo_module.ui.MainActivity import com.highcapable.yukihookapi.demo_module.ui.MainActivity
import com.highcapable.yukihookapi.hook.core.annotation.LegacyResourcesHook import com.highcapable.yukihookapi.hook.core.annotation.LegacyResourcesHook
import com.highcapable.yukihookapi.hook.factory.applyModuleTheme import com.highcapable.yukihookapi.hook.factory.applyModuleTheme
import com.highcapable.yukihookapi.hook.factory.constructor
import com.highcapable.yukihookapi.hook.factory.field
import com.highcapable.yukihookapi.hook.factory.method
import com.highcapable.yukihookapi.hook.factory.registerModuleAppActivities import com.highcapable.yukihookapi.hook.factory.registerModuleAppActivities
import com.highcapable.yukihookapi.hook.type.android.ActivityClass
import com.highcapable.yukihookapi.hook.type.android.BundleClass
import com.highcapable.yukihookapi.hook.type.java.StringArrayClass
import com.highcapable.yukihookapi.hook.type.java.StringClass
import com.highcapable.yukihookapi.hook.type.java.UnitType
import com.highcapable.yukihookapi.hook.xposed.bridge.event.YukiXposedEvent import com.highcapable.yukihookapi.hook.xposed.bridge.event.YukiXposedEvent
import com.highcapable.yukihookapi.hook.xposed.proxy.IYukiHookXposedInit import com.highcapable.yukihookapi.hook.xposed.proxy.IYukiHookXposedInit
@@ -151,16 +146,17 @@ object HookEntry : IYukiHookXposedInit {
loadZygote { loadZygote {
// Find Class to hook // Find Class to hook
// 得到需要 Hook 的 Class // 得到需要 Hook 的 Class
ActivityClass.method { Activity::class.resolve()
name = "onCreate" .firstMethod {
param(BundleClass) name = "onCreate"
}.hook { parameters(Bundle::class)
after { }.hook {
// Add text after the [Activity] title after {
// [Activity] 标题后方加入文字 // Add text after the [Activity] title
instance<Activity>().apply { title = "$title [Active]" } // 在 [Activity] 标题后方加入文字
instance<Activity>().apply { title = "$title [Active]" }
}
} }
}
// Find Resources to hook // Find Resources to hook
// Requires Hook Framework to support Resources Hook to succeed // Requires Hook Framework to support Resources Hook to succeed
// Resources Hook in Zygote only needs Hook Framework support, no need to enable this feature // Resources Hook in Zygote only needs Hook Framework support, no need to enable this feature
@@ -195,13 +191,13 @@ object HookEntry : IYukiHookXposedInit {
} }
// Find Class to hook // Find Class to hook
// 得到需要 Hook 的 Class // 得到需要 Hook 的 Class
"$packageName.ui.MainActivity".toClass().apply { "$packageName.ui.MainActivity".toClass().resolve().apply {
// Inject the method to be hooked // Inject the method to be hooked
// 注入要 Hook 的方法 // 注入要 Hook 的方法
method { firstMethod {
name = "getFirstText" name = "getFirstText"
emptyParam() emptyParameters()
returnType = StringClass returnType = String::class
}.hook { }.hook {
// Replaced hook // Replaced hook
// 执行替换 Hook // 执行替换 Hook
@@ -209,9 +205,9 @@ object HookEntry : IYukiHookXposedInit {
} }
// Inject the method to be hooked // Inject the method to be hooked
// 注入要 Hook 的方法 // 注入要 Hook 的方法
method { firstMethod {
name = "onCreate" name = "onCreate"
param(BundleClass) parameters(Bundle::class)
}.hook { }.hook {
// Before hook the method // Before hook the method
// 在方法执行之前拦截 // 在方法执行之前拦截
@@ -220,10 +216,10 @@ object HookEntry : IYukiHookXposedInit {
// We used "apply" function on the top // We used "apply" function on the top
// 当前实例为 "$packageName.ui.MainActivity" // 当前实例为 "$packageName.ui.MainActivity"
// 我们在顶部使用了 "apply" 方法 // 我们在顶部使用了 "apply" 方法
field { firstField {
name = "secondText" name = "secondText"
type = StringClass type = String::class
}.get(instance).set("I am hook result") }.of(instance).set("I am hook result")
} }
// After hook the method // After hook the method
// 在执行方法之后拦截 // 在执行方法之后拦截
@@ -243,10 +239,10 @@ object HookEntry : IYukiHookXposedInit {
} }
// Inject the method to be hooked // Inject the method to be hooked
// 注入要 Hook 的方法 // 注入要 Hook 的方法
method { firstMethod {
name = "getRegularText" name = "getRegularText"
param(StringClass) parameters(String::class)
returnType = StringClass returnType = String::class
}.hook { }.hook {
// Before hook the method // Before hook the method
// 在方法执行之前拦截 // 在方法执行之前拦截
@@ -261,10 +257,10 @@ object HookEntry : IYukiHookXposedInit {
} }
// Inject the method to be hooked // Inject the method to be hooked
// 注入要 Hook 的方法 // 注入要 Hook 的方法
method { firstMethod {
name = "getArray" name = "getArray"
param(StringArrayClass) parameters(ArrayClass(String::class))
returnType = StringArrayClass returnType = ArrayClass(String::class)
}.hook { }.hook {
// Before hook the method // Before hook the method
// 在方法执行之前拦截 // 在方法执行之前拦截
@@ -276,10 +272,10 @@ object HookEntry : IYukiHookXposedInit {
} }
// Inject the method to be hooked // Inject the method to be hooked
// 注入要 Hook 的方法 // 注入要 Hook 的方法
method { firstMethod {
name = "toast" name = "toast"
emptyParam() emptyParameters()
returnType = UnitType returnType = Void.TYPE
}.hook { }.hook {
// Intercept the entire method // Intercept the entire method
// 拦截整个方法 // 拦截整个方法
@@ -308,10 +304,10 @@ object HookEntry : IYukiHookXposedInit {
} }
// Inject the method to be hooked // Inject the method to be hooked
// 注入要 Hook 的方法 // 注入要 Hook 的方法
method { firstMethod {
name = "getDataText" name = "getDataText"
emptyParam() emptyParameters()
returnType = StringClass returnType = String::class
}.hook { }.hook {
// Replaced hook // Replaced hook
// 执行替换 Hook // 执行替换 Hook
@@ -320,10 +316,10 @@ object HookEntry : IYukiHookXposedInit {
} }
// Find Class to hook // Find Class to hook
// 得到需要 Hook 的 Class // 得到需要 Hook 的 Class
"$packageName.test.Main".toClass().apply { "$packageName.test.Main".toClass().resolve().apply {
// Inject the method to be hooked // Inject the method to be hooked
// 注入要 Hook 的方法 // 注入要 Hook 的方法
constructor { param(StringClass) }.hook { firstConstructor { parameters(String::class) }.hook {
// Before hook the method // Before hook the method
// 在方法执行之前拦截 // 在方法执行之前拦截
before { before {
@@ -334,19 +330,14 @@ object HookEntry : IYukiHookXposedInit {
} }
// Inject the method to be hooked // Inject the method to be hooked
// 注入要 Hook 的方法 // 注入要 Hook 的方法
method { firstMethod {
name = "getSuperString" name = "getSuperString"
emptyParam() emptyParameters()
// This method is not in the current Class // This method is not in the current Class
// Just set this find condition to automatically go to the super class of the current Class to find // Just set this find condition to automatically go to the super class of the current Class to find
// Since the method shown will only exist in the super class
// So you can set only the super class to find isOnlySuperClass = true to save time
// If you want to keep trying to find the current Class, please remove isOnlySuperClass = true
// 这个方法不在当前的 Class // 这个方法不在当前的 Class
// 只需要设置此查找条件即可自动前往当前 Class 的父类查找 // 只需要设置此查找条件即可自动前往当前 Class 的父类查找
// 由于演示的方法只会在父类存在 - 所以可以设置仅查找父类 isOnlySuperClass = true 节省时间 superclass()
// 如果想继续尝试查找当前 Class - 请删除 isOnlySuperClass = true
superClass(isOnlySuperClass = true)
}.hook { }.hook {
// Replaced hook // Replaced hook
// 执行替换 Hook // 执行替换 Hook

View File

@@ -25,7 +25,7 @@ import android.graphics.drawable.Drawable
import android.util.TypedValue import android.util.TypedValue
import android.widget.Button import android.widget.Button
import androidx.appcompat.app.AlertDialog import androidx.appcompat.app.AlertDialog
import com.highcapable.yukihookapi.hook.factory.current import com.highcapable.kavaref.KavaRef.Companion.resolve
/** /**
* Fixed [AlertDialog] dialog button issue after injecting Module App's Resources in some Host Apps * Fixed [AlertDialog] dialog button issue after injecting Module App's Resources in some Host Apps
@@ -38,11 +38,13 @@ import com.highcapable.yukihookapi.hook.factory.current
* @return [AlertDialog] * @return [AlertDialog]
*/ */
fun AlertDialog.compatStyle(): AlertDialog { fun AlertDialog.compatStyle(): AlertDialog {
current().field { name = "mAlert" }.current { resolve().firstField {
arrayOf( name = "mAlert"
field { name = "mButtonPositive" }.cast<Button>(), }.get()?.resolve()?.apply {
field { name = "mButtonNegative" }.cast<Button>(), listOf(
field { name = "mButtonNeutral" }.cast<Button>() firstField { name = "mButtonPositive" }.get<Button>(),
firstField { name = "mButtonNegative" }.get<Button>(),
firstField { name = "mButtonNeutral" }.get<Button>()
).forEach { ).forEach {
it?.setBackgroundResource(TypedValue().apply { it?.setBackgroundResource(TypedValue().apply {
context.theme.resolveAttribute(android.R.attr.selectableItemBackground, this, true) context.theme.resolveAttribute(android.R.attr.selectableItemBackground, this, true)
@@ -51,6 +53,5 @@ fun AlertDialog.compatStyle(): AlertDialog {
context.theme.resolveAttribute(android.R.attr.colorPrimary, this, true) context.theme.resolveAttribute(android.R.attr.colorPrimary, this, true)
}.data) }.data)
} }
} }; return this
return this
} }

View File

@@ -28,7 +28,6 @@ import android.text.TextUtils
import android.view.Gravity import android.view.Gravity
import android.widget.LinearLayout import android.widget.LinearLayout
import android.widget.TextView import android.widget.TextView
import android.widget.Toast
import androidx.core.view.updateMargins import androidx.core.view.updateMargins
import com.highcapable.betterandroid.ui.extension.component.startActivity import com.highcapable.betterandroid.ui.extension.component.startActivity
import com.highcapable.betterandroid.ui.extension.view.textToString import com.highcapable.betterandroid.ui.extension.view.textToString
@@ -58,7 +57,7 @@ class MainActivity : ModuleAppCompatActivity() {
moduleEnvironment { moduleEnvironment {
dataChannel(packageName = "com.highcapable.yukihookapi.demo_app").with { dataChannel(packageName = "com.highcapable.yukihookapi.demo_app").with {
wait(DataConst.TEST_CN_DATA) { wait(DataConst.TEST_CN_DATA) {
Toast.makeText(applicationContext, it, Toast.LENGTH_SHORT).show() toast(it)
} }
} }
} }
@@ -138,7 +137,6 @@ class MainActivity : ModuleAppCompatActivity() {
} }
} }
Button( Button(
id = "button",
lparams = LayoutParams { lparams = LayoutParams {
bottomMargin = 15.dp bottomMargin = 15.dp
} }