222 Commits
1.1.5 ... 1.2.0

Author SHA1 Message Date
dc4b0281bd Bump version to 1.2.0 2023-10-07 19:09:05 +08:00
d55e4e3f16 refactor: change license to Apache-2.0 2023-10-07 18:52:55 +08:00
333877c4de refactor: change repository owner to HighCapable 2023-10-07 17:50:15 +08:00
87adab8029 docs: add LSPlant 2023-10-07 16:50:05 +08:00
8f523d470d style: use "2.0.0" instead "2.x.x" 2023-10-07 16:42:56 +08:00
6d82c28081 docs: merge some future to migrate docs 2023-10-07 16:29:05 +08:00
5939e1dcd3 fix: normal logs not output throwable 2023-10-07 11:22:55 +08:00
ba9928b43c fix: typo 2023-10-07 11:19:05 +08:00
8462d9cb34 docs: update api-exception, example 2023-10-07 11:17:35 +08:00
94ffac84bc docs: update api docs 2023-10-07 11:17:05 +08:00
8d8002df87 refactor: merge some legacy apis 2023-10-07 11:13:35 +08:00
ce3c2fa360 fix: when not using injectMember function create instance still show error when members is empty 2023-10-06 04:27:59 +08:00
973e406b95 docs: update future 2023-10-06 03:11:15 +08:00
fc1a8ae5e1 docs: update api docs 2023-10-06 02:32:35 +08:00
7b9af68fe6 refactor: make appClassLoader nullable 2023-10-06 02:32:20 +08:00
c4100247f8 docs: update example, reflection 2023-10-06 02:20:59 +08:00
c801f2aeca docs: update api docs 2023-10-06 02:20:25 +08:00
6687c69b17 feat: add lazyClass, lazyClassOrNull functions 2023-10-06 02:19:50 +08:00
29a594d272 refactor: mark some functions to legacy hook api 2023-10-05 22:23:25 +08:00
c7cafa11a9 docs: update api docs 2023-10-05 22:22:15 +08:00
a19dfb3b5f feat: add direct hook functions 2023-10-05 22:15:15 +08:00
a2056db45e refactor: disable hook when got empty members and optimize some functions 2023-10-05 05:16:55 +08:00
6e57dc9ab0 fix: legacy hook api may cause problem when class not found 2023-10-05 04:10:35 +08:00
39656b81b3 feat: log warn when no callback of already hooked members 2023-10-05 03:19:05 +08:00
e0b18eb81c docs: update Java requirement description 2023-10-05 02:27:05 +08:00
5d9b473bd6 feat: update demo 2023-10-05 02:15:35 +08:00
545f7f92ab docs: update xposed-using 2023-10-05 02:15:25 +08:00
b38d2b63ea fix: module package name obtain function 2023-10-05 02:15:15 +08:00
c921348572 feat: update demo 2023-10-05 00:37:55 +08:00
4e0f88dbad docs: update example, xposed-using 2023-10-05 00:37:35 +08:00
c7decb4119 docs: update api docs 2023-10-05 00:37:15 +08:00
da26016630 refactor: move xposed module status function to auto generator 2023-10-05 00:36:55 +08:00
922907fa0f refactor: make YukiXposedModuleStatus anonymous 2023-10-04 23:30:55 +08:00
a003a4ea07 refactor: remove FreeReflection auto generation, add it using dependency 2023-10-04 19:48:35 +08:00
ae71bea0a0 feat: support single process multiple AppLifecycle instance 2023-10-04 04:16:15 +08:00
92106d6e92 feat: dynamic name for PackageParam and HookParam 2023-10-04 03:51:25 +08:00
044e67ae7f fix: demo bugs 2023-10-04 03:39:55 +08:00
58ed2b962e chore(fix): suppress warning 2023-10-04 03:39:35 +08:00
73e09bef25 feat: update demo 2023-10-04 03:15:56 +08:00
89cec45326 refactor: optimize opt-in annotations 2023-10-04 03:15:50 +08:00
3d149a92ca docs: update api docs 2023-10-04 03:10:25 +08:00
d04b9a5211 refactor: merge hook priority to YukiHookPriority 2023-10-04 03:07:50 +08:00
fa24de805a fix: spelling case problems 2023-10-04 02:27:05 +08:00
f5c2ce2468 feat: update demo 2023-10-04 02:23:55 +08:00
3f5114851c docs: update api docs 2023-10-04 02:23:35 +08:00
edcc17907b refactor: remove hook tag and remove old api usage 2023-10-04 02:23:25 +08:00
786b2ad9ea docs: update reflection 2023-10-04 01:01:15 +08:00
da170e7ae1 feat: update api-exception 2023-10-03 23:23:15 +08:00
5c415c8d61 feat: allow no condition finding and ignore member access exception 2023-10-03 23:22:50 +08:00
8c8cfc5498 feat: update demo 2023-10-03 04:17:35 +08:00
6e658baf17 docs: update to new usage 2023-10-03 04:17:25 +08:00
375b2f3398 refactor: disable resources hook by default 2023-10-03 04:16:55 +08:00
7d2dc3c268 docs: update api docs 2023-10-03 04:16:25 +08:00
7280397d79 feat: add new api preview functions, mark old api to legacy 2023-10-03 04:15:59 +08:00
1ffa0fab4f refactor: merge opt-in api to new annotations 2023-10-03 01:59:55 +08:00
71203cd9bf refactor: make BaseFinder.BaseResult public 2023-10-02 23:07:15 +08:00
b8bb903ff7 feat: update demo 2023-10-02 22:41:55 +08:00
ea86a2b60a docs: update api-example, example, move-to-new-api, reflection 2023-10-02 22:41:35 +08:00
3ca7f4b017 docs: update api docs 2023-10-02 22:41:05 +08:00
b531fce974 refactor: deprecated findClass and String.hook functions 2023-10-02 22:40:38 +08:00
d7b670c94d docs: update api-exception 2023-10-02 02:36:35 +08:00
3118b3a5e6 docs: update api docs 2023-10-02 02:36:25 +08:00
18ec0e2727 feat: add replace resources hook callback functions 2023-10-02 02:36:15 +08:00
e813aaf97a fix: HookParam call timing problem and refactor HookParam 2023-10-02 01:15:35 +08:00
460ac083b0 refactor: merge HashSet/ArraySet to MutableSet, HashMap/ArrayMap to MutableMap, ArrayList to MutableList 2023-10-02 00:35:20 +08:00
00bea93085 refactor: merge HashSet, ArrayList to MutableList 2023-10-01 23:00:55 +08:00
2ee38ee54e docs: update api docs 2023-10-01 01:00:20 +08:00
c9e2720afc fix: make actualTypeArguments not force cast to Class type 2023-10-01 00:59:55 +08:00
e3da58952f feat: update demo 2023-09-30 23:32:56 +08:00
0709317d36 refactor: disable debug mode by default 2023-09-30 23:32:45 +08:00
bca5a07826 refactor: optimize some code 2023-09-30 23:25:55 +08:00
fd84b22532 feat: update demo 2023-09-28 00:53:00 +08:00
fe2f5c802e docs: update logger 2023-09-28 00:52:55 +08:00
dbe451d29c docs: update api docs 2023-09-28 00:52:35 +08:00
c651776da0 refactor: split LoggerFactory to YLog and YLogData 2023-09-28 00:50:45 +08:00
ee1fc85a4e refactor: make CauseProblemsApi open again 2023-09-28 00:11:43 +08:00
3ab4a8ee12 refactor: remove some comments 2023-09-27 22:15:05 +08:00
18172145ef refactor: remove "" and other comments 2023-09-27 18:17:45 +08:00
418fd9de00 refactor: use magic to hide lint on non-public, inline api
- remove all YukiGenerateApi, YukiPrivateApi and @PublishedApi
2023-09-27 18:01:35 +08:00
24290a7ee2 fix: typo in demo-module 2023-09-27 17:48:13 +08:00
92daf533c9 chore: bump plugin versions
- bump "com.highcapable.sweetdependency" version to 1.0.2
- bump "com.highcapable.sweetproperty" version to 1.0.3
- update build script usage
- update config file usage
2023-09-26 08:59:49 +08:00
4d0dce8fd3 style: rename toStackTrack to dumpToString 2023-09-26 02:33:39 +08:00
68f8b0f571 refactor: optimize core finder code
- fix remedy plan not show any errors problem
- rearrange some code
2023-09-24 01:09:03 +08:00
cfeac9075a feat: update demo 2023-09-23 22:25:37 +08:00
38b296274c docs(fix): tag level error 2023-09-23 22:23:55 +08:00
00788cce5a fix: debug mode use debug log 2023-09-23 21:59:17 +08:00
e14c3e3808 style: use TAG instead hardcode 2023-09-23 21:00:29 +08:00
c849690699 refactor: merge all util functions to factory 2023-09-23 20:55:43 +08:00
d0d1ce1cb9 feat: update demo 2023-09-23 20:55:38 +08:00
09e96feda4 docs: update api docs 2023-09-23 20:25:55 +08:00
1af4ff8525 feat: add TAG & merge API_VERSION_NAME, API_VERSION_CODE to VERSION 2023-09-23 20:23:25 +08:00
e7cca9b5ca docs: correct comments 2023-09-23 19:39:10 +08:00
1f1a0b6c11 docs(style): optimize symbols 2023-09-23 12:49:35 +08:00
24412eea84 ci: add docs deploy 2023-09-23 12:09:42 +08:00
b518376c00 docs(chore): update dependencies & remove old file 2023-09-23 12:09:11 +08:00
fe0bae8dfd docs: remove manually deployed 2023-09-23 12:08:58 +08:00
8aa5f34c36 docs: update docs compile files 2023-09-22 21:38:53 +08:00
a8a40b562f docs: optimize features 2023-09-22 21:38:16 +08:00
20618c10ec docs: update docs compile files 2023-09-22 20:37:45 +08:00
2c21554902 docs: fix typo 2023-09-22 20:36:09 +08:00
23f4da648a docs: optimize comments 2023-09-22 17:15:24 +08:00
9ebe38e358 docs: update docs compile files 2023-09-22 12:17:58 +08:00
d6f83ffc3c docs: add milestone related plans & modify some documents 2023-09-22 12:16:20 +08:00
ac316d1427 docs: update structure diagram 2023-09-22 09:15:20 +08:00
208c49cc0a docs: update docs compile files 2023-09-21 04:40:59 +08:00
a65dbe2c2f docs: add new contacts 2023-09-21 04:40:15 +08:00
0c239dcda4 docs: update docs compile files 2023-09-21 04:28:09 +08:00
2db28d8aab docs: update some functions 2023-09-21 04:26:20 +08:00
5bd18269c2 docs: optimize comments 2023-09-21 03:20:46 +08:00
8ba166dab9 style: lots of changes
- move demo-app, demo-module to samples
- rename yukihookapi to yukihookapi-core
- optimize code
- other small changes
2023-09-21 03:19:13 +08:00
dd7912a577 docs: update README, README-zh-CN 2023-09-21 03:16:23 +08:00
fc2187ddc8 chore: migrate build script from groovy to kts
- using SweetDependency, SweetProperty
- using new maven publish function
- update gradle and dependencies
2023-09-21 03:13:14 +08:00
bdae1944f2 chore: clean up build step files 2023-09-21 03:10:36 +08:00
e4063866f9 [Change Commit Specification] Use the new commit spec from here on
child commits:
chore: add .editorconfig
2023-09-21 03:06:43 +08:00
53de203733 Refactor optimize code in YukiHookDataChannel 2023-08-29 20:07:43 +08:00
db8cafe1f4 Modify rearrange code in YukiHookAPI 2023-08-29 20:06:13 +08:00
a88e88786e Refactor optimize code in YukiHookDataChannel, AppParasitics 2023-08-29 20:03:55 +08:00
Fankesyooni
f02e512ad8 Merge pull request #44 from BlueCat300/master
Fixed context-registered receivers
2023-08-29 19:53:47 +08:00
Blue cat
9da4743feb Fixed context-registered receivers 2023-08-24 19:09:46 +03:00
befa2d26ee Modify reformat code in README 2023-08-17 06:10:06 +08:00
Fankesyooni
4e8c46a85b Merge pull request #41 from kazutoiris/master
Add `zuiyou-adfree` to cooperation
2023-08-14 19:19:16 +08:00
kazutoiris
52739b9572 Add cooperation 2023-08-14 19:09:50 +08:00
30b4fda708 Fix naming of "ShortArrayType" in VariableTypeFactory 2023-06-26 06:00:06 +08:00
1e030ee72c Automatically compile documentation (1.1.11) 2023-05-12 17:05:56 +08:00
482efff67c Fix project url changed problem in type define documentation 2023-05-12 17:03:25 +08:00
1012777858 Fix translation problem in reflection documentation 2023-05-12 17:01:56 +08:00
Fankesyooni
a40318378f Merge pull request #38 from yangyiyu08/master
Fix get interfaces of class in ReflectionFactory
2023-05-05 23:47:45 +08:00
Fankesyooni
d2d95703dc Refactor optimize code in ReflectionFactory 2023-05-05 23:45:49 +08:00
qingyu
1bb2c4e5a2 fix get interfaces of class
fix get interfaces of class
2023-05-05 23:29:15 +08:00
9f24bffedc Automatically compile documentation (1.1.11) 2023-04-26 15:00:36 +08:00
f85cafc73d Fix "GitHub" spelling in all files 2023-04-26 14:59:35 +08:00
c5f2163fa3 Modify make makeWorldReadable function to inline in YukiHookPrefsBridge 2023-04-26 14:55:38 +08:00
e986a85d5a Automatically compile documentation (1.1.11) 2023-04-25 05:48:36 +08:00
0454c6faee Update version to 1.1.11 2023-04-25 05:45:05 +08:00
a398720755 Update demo 2023-04-25 05:05:55 +08:00
f6096721b7 Modify remove Members cache function and remove LruCache function, optimizing performance of finder 2023-04-25 05:03:20 +08:00
0b5bb7f09c Added Sequence.findLastIndex, Sequence.lastIndex functions in UtilsFactory 2023-04-25 04:29:55 +08:00
160856ebad Update demo 2023-04-25 01:22:05 +08:00
21970d1bc2 Modify remove prefs cache function in YukiHookPrefsBridge, YukiHookAPI 2023-04-25 01:21:05 +08:00
c2e4651137 Modify refactor code style in ReflectionTool 2023-04-24 22:15:43 +08:00
495aa08eb6 Automatically compile documentation (1.1.10) 2023-04-21 01:10:56 +08:00
48ed26366a Update version to 1.1.10 2023-04-21 01:09:35 +08:00
60f8937d55 Update host-inject documentation 2023-04-21 00:29:35 +08:00
388147f089 Added custom proxy class name for Activity Proxy function 2023-04-21 00:13:35 +08:00
cc321df3b8 Modify merge YukiHookPrefsBridge cache function to LruCache and add new PreferencesCacheManager 2023-04-20 22:48:55 +08:00
ea609fb1c3 Added LruCache function to save memory 2023-04-20 22:37:55 +08:00
ddacf818c8 Modify change some HashMap to ArrayMap to save memory 2023-04-20 17:23:36 +08:00
03320b40fa Fix contains, all functions not support isUsingNativeStorage function in YukiHookPrefsBridge 2023-04-18 22:15:56 +08:00
635e8b5e40 Automatically compile documentation (1.1.9) 2023-04-17 05:31:06 +08:00
6b4804cfb8 Update version to 1.1.9 2023-04-17 05:27:55 +08:00
51a9f42bd5 Fix some contents problem in NameRules documentation 2023-04-17 05:07:05 +08:00
f9cdcc508f Modify make YukiHookPrefsBridge not singleton to fix some duplicate assignment problems and change code note in documentation 2023-04-17 04:40:35 +08:00
b41897fd58 Modify suppress some warn lint checking in DexClassFinder, HandlerDelegateCaller, YukiHookDataChannel 2023-04-17 03:42:35 +08:00
9e1a6f2b07 Update demo 2023-04-17 03:36:05 +08:00
7f7b8e94f5 Update api-exception documentation 2023-04-17 03:35:35 +08:00
390ee9e509 Modify change YukiHookModulePrefs name to YukiHookPrefsBridge and make it support native storage usage in YukiHookPrefsBridge 2023-04-17 03:35:05 +08:00
e298f19e33 Fix prefs object created every time maybe called app OOM problem in YukiHookModulePrefs 2023-04-17 00:18:06 +08:00
b61bd33a67 Added XSharedPreferencesDelegate to fix no Xposed environment class not found problem 2023-04-17 00:16:05 +08:00
9ba7497b7a Update demo 2023-04-16 23:13:55 +08:00
1215ccf220 Modify move puts functions to Editor in YukiHookModulePrefs 2023-04-16 23:13:05 +08:00
f8eefd58fd Update example documentation 2023-04-16 20:57:05 +08:00
404bbfa4eb Added type function in YukiHookAPI.Status.Executor and add ExecutorType 2023-04-16 20:22:18 +08:00
3b8eba21b0 Modify merge yukihookapi, yukihookapi-stub java-library project to android-library project 2023-04-16 03:19:55 +08:00
c743dad733 Modify merge contents of build.gradle into constant definitions 2023-04-16 02:56:05 +08:00
68b7e3738f Modify remove build function in YukiHookAPI.Configs 2023-04-16 00:09:35 +08:00
7244d0b9b3 Modify move "com.google.devtools.ksp" version definition to root project's build.gradle 2023-04-15 21:43:55 +08:00
3ddd4b3c0d Modify move maven configs from .gradle to .maven directory and make it to json file 2023-04-15 00:55:55 +08:00
eeacd4f7d0 Modify add loggerForUnprocessableDataByFirstElement function in YukiHookDataChannel 2023-04-14 23:55:56 +08:00
98d46a3d9e Fix received data failed when same Host App scope decided and change the default action name in YukiHookDataChannel 2023-04-10 00:52:35 +08:00
a8121d8735 Modify change YukiHookDataChannel usages
- Fix data channel transaction data parse maybe failure on some devices
- Added dataMaxByteSize, dataMaxByteCompressionFactor functions
2023-04-09 23:57:05 +08:00
914b059d9c Added contains function in YukiHookModulePrefs 2023-04-09 00:46:27 +08:00
a0714eb996 Update api-exception documentation 2023-04-08 03:19:35 +08:00
8120206f4d Update xposed-channel documentation 2023-04-08 03:19:05 +08:00
05a7059eeb Modify remove restrictions on only can use data channel in Activity for Module App in YukiHookDataChannel 2023-04-08 03:17:35 +08:00
7c8086fde3 Modify merge external caller package and class name to ExternalCallerName in CodeSourceFileFactory 2023-04-08 02:42:55 +08:00
dc079e7dc8 Modify change Activity Proxy function to autogenerate 2023-04-08 02:23:35 +08:00
099ece1e97 Update api-exception documentation 2023-04-08 00:56:15 +08:00
f489313054 Modify remove checkingInternal function in ReflectionFactory, YukiMemberHookCreator 2023-04-08 00:55:32 +08:00
e17ce34d77 Update Gradle & Kotlin
- Update Kotlin version to 1.8.20
- Update Gradle version to 8.0.2
- Update Gradle dependencies
2023-04-07 23:55:35 +08:00
df5a24cf3f Added start history chart in README 2023-02-19 14:33:35 +08:00
1020203278 Added new cooperation repositories in README 2023-02-18 13:40:36 +08:00
9be3e2a49a Automatically compile documentation (1.1.8) 2023-02-01 04:05:06 +08:00
ecfd6e42bf Re-update version to 1.1.8 2023-02-01 04:00:55 +08:00
370f954c1a Modify replace version 1.1.7 to 1.1.8 in documentations 2023-02-01 03:59:25 +08:00
2999d1965b Revert "Fix some hooking process not always in the correct process problem in YukiXposedModule" 2023-02-01 03:56:42 +08:00
8955daceee Automatically compile documentation (1.1.7) 2023-02-01 03:15:06 +08:00
9215275c56 Update version to 1.1.7 2023-02-01 03:11:15 +08:00
aa352d3734 Update Gradle dependencies 2023-02-01 03:09:15 +08:00
4d665d76c7 Update demo's duplicate files 2023-02-01 02:39:52 +08:00
caa412953d Update xposed-using documentation 2023-02-01 02:39:52 +08:00
008962a1fc Update demo's duplicate files 2023-02-01 02:39:52 +08:00
0e554ce0e0 Update .gitignore 2023-02-01 02:21:05 +08:00
b7f537e511 Modify change YukiHookAPI entry class file generated path from assets to resources/META-INF in YukiHookXposedProcessor 2023-02-01 02:15:20 +08:00
476ce48d1f Modify change hooker functions to MemberBaseFinder.MemberHookerManager in FieldFinder, MethodFinder, ConstructorFinder, MemberBaseFinder 2023-02-01 01:52:55 +08:00
2b1acf896e Modify change by function to multiple reasons of hooker in YukiMemberHookCreator 2023-02-01 01:39:21 +08:00
249a39dc05 Fix some hooking process not always in the correct process problem in YukiXposedModule 2023-01-31 23:40:20 +08:00
244903553c Fix code note in Java demo 2023-01-31 23:13:55 +08:00
6e67298225 Added new registerReceiver function and fix Host App lifecycle events call multiple times in AppLifecycle in PackageParam 2023-01-31 22:19:20 +08:00
ac12e0e87c Modify remove invalid statement UserDataHandlerClass in ComponentTypeFactory 2023-01-31 21:45:36 +08:00
5bd1b3b79e Added instanceOrNull functions in HookParam 2023-01-31 21:30:27 +08:00
cf2473b92c Modify make null exception and throwable message to empty string in Throwable.throwToApp function in HookParam 2023-01-31 21:15:20 +08:00
8079b89615 Modify allowed empty "msg" parameter in loggerE, yLoggerE function and stop recording empty logs in LoggerFactory 2023-01-31 21:12:20 +08:00
a04018e28f Fix when hooking callback throw an exception or throwable the member description not shown up problem in YukiMemberHookCreator 2023-01-31 21:07:35 +08:00
686bcdb674 Modify change hooking callback delegate parameter to fix effective immediately function in HookCompatHelper, YukiHookDelegateFactory 2023-01-31 20:39:05 +08:00
c0855e089c Automatically compile documentation (1.1.6) 2023-01-26 02:33:02 +08:00
72ba52ad22 Modify add cooperations contents in reflection, future documentation 2023-01-26 02:32:21 +08:00
0b1e078829 Fix some problem contents in documentation 2023-01-26 01:50:50 +08:00
48ca18fe39 Modify remove invalid statement ComponentClass in ComponentTypeFactory 2023-01-26 01:49:02 +08:00
1dfcb75c9c Automatically compile documentation (1.1.6) 2023-01-21 00:38:08 +08:00
a7f9144c3d Update version to 1.1.6 2023-01-21 00:32:05 +08:00
f4b835f65c Update Android Gradle Plugin to 7.4.0 2023-01-21 00:31:12 +08:00
c7ed38927c Modify not allowed hook entry class has any constructor parameters in YukiHookXposedProcessor 2023-01-21 00:13:35 +08:00
4230e4f8be Update api-exception documentation 2023-01-21 00:07:21 +08:00
ba163c9367 Modify change naming of "HookEntryClass" to "hook entry class" in InjectYukiHookWithXposed, YukiHookXposedProcessor, CodeSourceFileFactory 2023-01-21 00:07:04 +08:00
1831257784 Update api-example documentation 2023-01-20 23:52:59 +08:00
3b56218fd2 Fix Xposed Module load scope single process multiple package names problem and make PackageParam to multiple instances in YukiXposedModule 2023-01-20 23:45:04 +08:00
3e55d6178d Fix some problem contents in YukiHookAPI documentation 2023-01-20 20:49:30 +08:00
c4acd31c8d Modify change member call param name to "args" in ConstructorFinder, MethodFinder, ReflectionFactory 2023-01-20 20:43:20 +08:00
ce35291435 Fix invoke original member "Wrong number of arguments" problem when hooking or called original function 2023-01-20 20:27:01 +08:00
3e9f90e14b Automatically compile documentation (1.1.5) 2023-01-13 10:11:09 +08:00
9d512a0d7d Fix documentation contents bugs 2023-01-13 10:09:37 +08:00
2b7ee6cf78 Modify change code note for obtainLoggerInMemoryData function in YukiHookDataChannel 2023-01-13 09:43:10 +08:00
852 changed files with 16009 additions and 34019 deletions

17
.editorconfig Normal file
View File

@@ -0,0 +1,17 @@
# noinspection EditorConfigKeyCorrectness
[{*.kt,*.kts}]
ktlint_standard_annotation = disabled
ktlint_standard_filename = disabled
ktlint_standard_wrapping = disabled
ktlint_standard_import-ordering = enabled
ktlint_standard_max-line-length = disabled
ktlint_standard_multiline-if-else = disabled
ktlint_standard_argument-list-wrapping = disabled
ktlint_standard_parameter-list-wrapping = disabled
ktlint_standard_trailing-comma-on-declaration-site = disabled
ktlint_function_signature_body_expression_wrapping = multiline
ij_continuation_indent_size = 2
indent_size = 4
indent_style = space
insert_final_newline = false
max_line_length = 150

37
.github/workflows/docs-deploy.yml vendored Normal file
View File

@@ -0,0 +1,37 @@
name: Deploy to GitHub pages
on:
workflow_dispatch:
push:
branches: [ master ]
paths:
- 'docs-source/**'
- '.github/workflows/**'
permissions:
contents: write
jobs:
docs:
if: ${{ success() }}
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
with:
fetch-depth: 0
- name: Setup Node.js
uses: actions/setup-node@v3
with:
node-version: 18
- name: Build VuePress site
run: |
cd docs-source
yarn -i
yarn docs:build-gh-pages
- name: Deploy to GitHub Pages
uses: crazy-max/ghaction-github-pages@v4
with:
target_branch: gh-pages
build_dir: docs-source/dist
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

2
.gitignore vendored
View File

@@ -12,4 +12,4 @@
/captures
.externalNativeBuild
.cxx
local.properties
local.properties

4
.idea/.gitignore generated vendored
View File

@@ -1,3 +1,5 @@
# Default ignored files
/shelf/
/workspace.xml
/gradle.xml
/misc.xml
/workspace.xml

26
.idea/appInsightsSettings.xml generated Normal file
View File

@@ -0,0 +1,26 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="AppInsightsSettings">
<option name="tabSettings">
<map>
<entry key="Firebase Crashlytics">
<value>
<InsightsFilterSettings>
<option name="connection">
<ConnectionSetting>
<option name="appId" value="PLACEHOLDER" />
<option name="mobileSdkAppId" value="" />
<option name="projectId" value="" />
<option name="projectNumber" value="" />
</ConnectionSetting>
</option>
<option name="signal" value="SIGNAL_UNSPECIFIED" />
<option name="timeIntervalDays" value="THIRTY_DAYS" />
<option name="visibilityType" value="ALL" />
</InsightsFilterSettings>
</value>
</entry>
</map>
</option>
</component>
</project>

4
.idea/compiler.xml generated
View File

@@ -1,8 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="CompilerConfiguration">
<bytecodeTargetLevel target="11">
<bytecodeTargetLevel target="17">
<module name="YukiHookAPI.app" target="11" />
<module name="YukiHookAPI.demo-app" target="17" />
<module name="YukiHookAPI.demo-module" target="17" />
<module name="YukiHookAPI.yukihookapi-yaya" target="11" />
</bytecodeTargetLevel>
</component>

13
.idea/deploymentTargetDropDown.xml generated Normal file
View File

@@ -0,0 +1,13 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="deploymentTargetDropDown">
<value>
<entry key="samples.demo-app">
<State />
</entry>
<entry key="samples.demo-module">
<State />
</entry>
</value>
</component>
</project>

24
.idea/gradle.xml generated
View File

@@ -1,24 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="GradleMigrationSettings" migrationVersion="1" />
<component name="GradleSettings">
<option name="linkedExternalProjectsSettings">
<GradleProjectSettings>
<option name="testRunner" value="GRADLE" />
<option name="distributionType" value="DEFAULT_WRAPPED" />
<option name="externalProjectPath" value="$PROJECT_DIR$" />
<option name="gradleJvm" value="Embedded JDK" />
<option name="modules">
<set>
<option value="$PROJECT_DIR$" />
<option value="$PROJECT_DIR$/demo-app" />
<option value="$PROJECT_DIR$/demo-module" />
<option value="$PROJECT_DIR$/yukihookapi" />
<option value="$PROJECT_DIR$/yukihookapi-ksp-xposed" />
<option value="$PROJECT_DIR$/yukihookapi-stub" />
</set>
</option>
</GradleProjectSettings>
</option>
</component>
</project>

View File

@@ -6,5 +6,6 @@
<option name="processLiterals" value="true" />
<option name="processComments" value="true" />
</inspection_tool>
<inspection_tool class="UnstableApiUsage" enabled="false" level="WARNING" enabled_by_default="false" />
</profile>
</component>

2
.idea/kotlinc.xml generated
View File

@@ -7,6 +7,6 @@
<option name="additionalArguments" value="-version -Xopt-in=kotlin.RequiresOptIn" />
</component>
<component name="KotlinJpsPluginSettings">
<option name="version" value="1.7.20" />
<option name="version" value="1.9.10" />
</component>
</project>

11
.idea/ktlint.xml generated Normal file
View File

@@ -0,0 +1,11 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="KtlintProjectConfiguration">
<treatAsErrors>false</treatAsErrors>
<disabledRules>
<list>
<option value="package-name" />
</list>
</disabledRules>
</component>
</project>

10
.idea/migrations.xml generated Normal file
View File

@@ -0,0 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectMigrations">
<option name="MigrateToGradleLocalJavaHome">
<set>
<option value="$PROJECT_DIR$" />
</set>
</option>
</component>
</project>

36
.idea/misc.xml generated
View File

@@ -1,36 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="DesignSurface">
<option name="filePathToZoomLevelMap">
<map>
<entry key="app/src/main/res/layout/activity_main.xml" value="0.4169230769230769" />
<entry key="app_demo/src/main/res/layout/activity_main.xml" value="0.4375" />
<entry key="demo-app/src/main/res/drawable/ic_launcher_background.xml" value="0.238" />
<entry key="demo-app/src/main/res/layout/activity_main.xml" value="0.4375" />
<entry key="demo-module/src/main/res/drawable-v24/ic_launcher_foreground.xml" value="0.238" />
<entry key="demo-module/src/main/res/drawable/ic_launcher_background.xml" value="0.238" />
<entry key="demo-module/src/main/res/layout/activity_main.xml" value="0.4375" />
<entry key="demo-module/src/main/res/mipmap-anydpi-v26/ic_launcher.xml" value="0.238" />
<entry key="demo-module/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml" value="0.238" />
<entry key="demo-module/src/main/res/xml/settings_preference.xml" value="0.4359375" />
<entry key="demo-module/src/main/res/xml/settings_preferences.xml" value="0.43697916666666664" />
<entry key="demo/src/main/res/layout/activity_main.xml" value="0.4375" />
<entry key="module_demo/src/main/res/layout/activity_main.xml" value="0.4375" />
<entry key="yukihookapi-ui-component/src/main/kotlin/com/highcapable/yukihookapi/ui/view/ModuleActiveBannerView.kt" value="0.44074074074074077" />
<entry key="yukihookapi-ui-component/src/main/res/drawable-night/bg_dark_round.xml" value="0.238" />
<entry key="yukihookapi-ui-component/src/main/res/drawable/bg_button_round.xml" value="0.238" />
<entry key="yukihookapi-ui-component/src/main/res/drawable/bg_dark_round.xml" value="0.238" />
<entry key="yukihookapi-ui-component/src/main/res/drawable/bg_green_round.xml" value="0.238" />
<entry key="yukihookapi-ui-component/src/main/res/drawable/bg_orange_round.xml" value="0.238" />
<entry key="yukihookapi-ui-component/src/main/res/drawable/bg_yellow_round.xml" value="0.238" />
<entry key="yukihookapi-ui-component/src/main/res/layout/wgt_module_active_banner.xml" value="0.4359375" />
</map>
</option>
</component>
<component name="ProjectRootManager" version="2" languageLevel="JDK_11" default="true" project-jdk-name="11" project-jdk-type="JavaSDK">
<output url="file://$PROJECT_DIR$/build/classes" />
</component>
<component name="ProjectType">
<option name="id" value="Android" />
</component>
</project>

215
LICENSE
View File

@@ -1,21 +1,202 @@
MIT License
Copyright (c) 2022 HighCapable
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
1. Definitions.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright HighCapable [name of copyright owner]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
https://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

View File

@@ -1,46 +1,29 @@
# Yuki Hook API
![Blank](https://img.shields.io/badge/license-MIT-blue)
![Blank](https://img.shields.io/badge/version-v1.1.5-green)
[![Telegram](https://img.shields.io/badge/Follow-Telegram-blue.svg?logo=telegram)](https://t.me/YukiHookAPI)
<br/><br/>
<img src="https://github.com/fankes/YuKiHookAPI/blob/master/img-src/icon.png?raw=true" width = "100" height = "100"/>
<br/>
<br/>
⛱️ 一个使用 Kotlin 构建的高效 Hook API 与 Xposed 模块解决方案。
<br/>
[![GitHub license](https://img.shields.io/github/license/HighCapable/YukiHookAPI?color=blue)](https://github.com/HighCapable/YukiHookAPI/blob/master/LICENSE)
[![GitHub release](https://img.shields.io/github/v/release/HighCapable/YukiHookAPI?display_name=release&logo=github&color=green)](https://github.com/HighCapable/YukiHookAPI/releases)
[![Telegram](https://img.shields.io/badge/discussion-Telegram-blue.svg?logo=telegram)](https://t.me/YukiHookAPI)
[![Telegram](https://img.shields.io/badge/discussion%20dev-Telegram-blue.svg?logo=telegram)](https://t.me/HighCapable_Dev)
[English](https://github.com/fankes/YukiHookAPI/blob/master/README.md) | 简体中文
<img src="https://github.com/HighCapable/YukiHookAPI/blob/master/img-src/icon.png?raw=true" width = "100" height = "100" alt="LOGO"/>
⛱️ 一个使用 Kotlin 构建的高效 Hook API 与 Xposed 模块解决方案。
[English](https://github.com/HighCapable/YukiHookAPI/blob/master/README.md) | 简体中文
## 这是什么
- 这是一个使用 Kotlin 基于 Xposed API 重新构建的高效 Hook API同时为 Xposed 模块的开发打造了丰富的功能扩展
- 名称取自 [《ももくり》女主 栗原 雪(Yuki)](https://www.bilibili.com/bangumi/play/ss5016)
- 前身为 [开发学习项目](https://github.com/fankes/TMore) 中使用的 Innocent Xposed API现在重新命名并开源
这是一个使用 Kotlin 基于 Xposed API 重新构建的高效 Hook API同时为 Xposed 模块的开发打造了丰富的功能扩展
## 支持的功能
名称取自 [《ももくり》女主 栗原 雪(Yuki)](https://www.bilibili.com/bangumi/play/ss5016)。
- Hook Framework 支持的基本 ART 动态方法 Hook 功能
- Xposed 资源钩子 (Resources Hook)
## 扩展功能
- 自动化 Xposed 模块构建 (完全无需自行创建 `assets/xposed_init`)
- [New XSharedPreferences](https://github.com/LSPosed/LSPosed/wiki/New-XSharedPreferences#for-the-module) 支持
- DataChannel (宿主 ←→ 模块) 无序广播通讯通道功能
- 简单快捷地实现混淆的字节码反射、查找功能
前身为 [开发学习项目](https://github.com/fankes/TMore) 中使用的 Innocent Xposed API现在重新命名并开源。
## 开始使用
- [点击这里](https://fankes.github.io/YukiHookAPI/zh-cn/) 前往文档页面查看更多详细教程和内容。
[点击这里](https://highcapable.github.io/YukiHookAPI/zh-cn/) 前往文档页面查看更多详细教程和内容。
## 联系我们
- [点击加入 Telegram 群组](https://t.me/YukiHookAPI)
## 展望未来
如果你喜欢 `YukiHookAPI` 项目,欢迎为此项目贡献你的代码 **PR**,可以是任何改进的建议以及新增的功能。
有关支持性的相关信息,你可以直接 [点击这里](https://highcapable.github.io/YukiHookAPI/zh-cn/guide/supportive) 进行查看。
## 合作项目
@@ -61,16 +44,32 @@
| [Auto NFC](https://github.com/GSWXXN/AutoNFC) | [GSWXXN](https://github.com/GSWXXN) |
| [不要竖屏](https://github.com/WankkoRee/Portrait2Landscape) | [WankkoRee](https://github.com/WankkoRee) |
| [QDReadHook](https://github.com/xihan123/QDReadHook) | [xihan123](https://github.com/xihan123) |
| [HXReadHook](https://github.com/xihan123/HXReadHook) | [xihan123](https://github.com/xihan123) |
| [WxRecordRead](https://github.com/pwh-pwh/wxrecordread) | [Coderpwh](https://github.com/pwh-pwh) |
| [MIUI更新进化](https://miup.utssg.xyz) | [ZQDesigned](https://github.com/ZQDesigned) |
| [MIUI录屏进化](https://www.coolapk.com/apk/UTSSG.ZQDesigned.miuirecordercracker) | [ZQDesigned](https://github.com/ZQDesigned) |
| [Fuck AD](https://github.com/hujiayucc/Fuck-AD) | [hujiayucc](https://github.com/hujiayucc) |
| [最右强力去广告](https://github.com/kazutoiris/zuiyou-adfree) | [kazutoiris](https://github.com/kazutoiris) |
你也在使用 `YukiHookAPI` 吗?快来 **PR** 将你的存储仓库添加到上方的列表(私有仓库可以不需要注明网页链接)。
你也在使用 `YukiHookAPI` 吗?快来 **PR** 将你的存储仓库添加到上方的列表 (私有仓库可以不需要注明网页链接)。
## 项目推广
如果你正在寻找一个可以自动管理 Gradle 项目依赖的 Gradle 插件,你可以了解一下 [SweetDependency](https://github.com/HighCapable/SweetDependency) 项目。
如果你正在寻找一个可以自动生成属性键值的 Gradle 插件,你可以了解一下 [SweetProperty](https://github.com/HighCapable/SweetProperty) 项目。
本项目同样使用了 **SweetDependency****SweetProperty**
## 捐赠支持
- 工作不易,无意外情况此项目将继续维护下去,提供更多可能,欢迎打赏。<br/><br/>
<img src="https://github.com/fankes/YuKiHookAPI/blob/master/img-src/wechat_code.jpg?raw=true" width = "200" height = "200"/>
工作不易,无意外情况此项目将继续维护下去,提供更多可能,欢迎打赏。
<img src="https://github.com/fankes/fankes/blob/main/img-src/payment_code.jpg?raw=true" width = "500" alt="Payment Code"/>
## Star History
![Star History Chart](https://api.star-history.com/svg?repos=HighCapable/YukiHookAPI&type=Date)
## 第三方开源使用声明
@@ -79,30 +78,24 @@
## 许可证
- [MIT](https://choosealicense.com/licenses/mit)
- [Apache-2.0](https://www.apache.org/licenses/LICENSE-2.0)
```
MIT License
Apache License Version 2.0
Copyright (C) 2019-2023 HighCapable
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
https://www.apache.org/licenses/LICENSE-2.0
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
```
版权所有 © 2019-2023 HighCapable

View File

@@ -1,47 +1,30 @@
# Yuki Hook API
![Blank](https://img.shields.io/badge/license-MIT-blue)
![Blank](https://img.shields.io/badge/version-v1.1.5-green)
[![Telegram](https://img.shields.io/badge/Follow-Telegram-blue.svg?logo=telegram)](https://t.me/YukiHookAPI)
<br/><br/>
<img src="https://github.com/fankes/YuKiHookAPI/blob/master/img-src/icon.png?raw=true" width = "100" height = "100"/>
<br/>
<br/>
⛱️ An efficient Hook API and Xposed Module solution built in Kotlin.
<br/>
[![GitHub license](https://img.shields.io/github/license/HighCapable/YukiHookAPI?color=blue)](https://github.com/HighCapable/YukiHookAPI/blob/master/LICENSE)
[![GitHub release](https://img.shields.io/github/v/release/HighCapable/YukiHookAPI?display_name=release&logo=github&color=green)](https://github.com/HighCapable/YukiHookAPI/releases)
[![Telegram](https://img.shields.io/badge/discussion-Telegram-blue.svg?logo=telegram)](https://t.me/YukiHookAPI)
[![Telegram](https://img.shields.io/badge/discussion%20dev-Telegram-blue.svg?logo=telegram)](https://t.me/HighCapable_Dev)
English | [简体中文](https://github.com/fankes/YukiHookAPI/blob/master/README-zh-CN.md)
<img src="https://github.com/HighCapable/YukiHookAPI/blob/master/img-src/icon.png?raw=true" width = "100" height = "100" alt="LOGO"/>
⛱️ An efficient Hook API and Xposed Module solution built in Kotlin.
English | [简体中文](https://github.com/HighCapable/YukiHookAPI/blob/master/README-zh-CN.md)
## What's this
- This is an efficient Hook API rebuilt based on the Xposed API using Kotlin, and creates rich function extensions for the development of
Xposed Modules
- The name is taken from ["ももくり" heroine Yuki Kurihara](https://www.bilibili.com/bangumi/play/ss5016)
- Formerly the Innocent Xposed API used in [Development Learning Project](https://github.com/fankes/TMore), now renamed and open sourced
This is an efficient Hook API rebuilt based on the Xposed API using Kotlin,
and creates rich function extensions for the development of Xposed Modules.
## Supports
The name is taken from ["ももくり" heroine Yuki Kurihara](https://www.bilibili.com/bangumi/play/ss5016).
- Basic ART dynamic method hook functions supported by Hook Framework
- Xposed Resources Hook
## Extensions
- Automatic Xposed Module Build (No need to create `assets/xposed_init` by yourself)
- [New XSharedPreferences](https://github.com/LSPosed/LSPosed/wiki/New-XSharedPreferences#for-the-module) Supports
- DataChannel (Host ←→ Module)
- Simple and quick implementation of obfuscated bytecode reflection and finding functions
Formerly the Innocent Xposed API used in [Development Learning Project](https://github.com/fankes/TMore), now renamed and open sourced.
## Get Started
- [Click here](https://fankes.github.io/YukiHookAPI/en/) go to the documentation page for more detailed tutorials and content.
[Click here](https://highcapable.github.io/YukiHookAPI/en/) go to the documentation page for more detailed tutorials and content.
## Contacts
- [Follow us on Telegram](https://t.me/YukiHookAPI)
## Features
If you like the `YukiHookAPI` project, we welcome you to make a **PR** in this project, any suggestions for improvement and new features.
For supportive related information, you can check it directly [click here](https://highcapable.github.io/YukiHookAPI/en/guide/supportive).
## Cooperations
@@ -62,13 +45,30 @@ The following are projects that have collaborated and are using `YukiHookAPI`.
| [Auto NFC](https://github.com/GSWXXN/AutoNFC) | [GSWXXN](https://github.com/GSWXXN) |
| [不要竖屏](https://github.com/WankkoRee/Portrait2Landscape) | [WankkoRee](https://github.com/WankkoRee) |
| [QDReadHook](https://github.com/xihan123/QDReadHook) | [xihan123](https://github.com/xihan123) |
| [HXReadHook](https://github.com/xihan123/HXReadHook) | [xihan123](https://github.com/xihan123) |
| [WxRecordRead](https://github.com/pwh-pwh/wxrecordread) | [Coderpwh](https://github.com/pwh-pwh) |
| [MIUI更新进化](https://miup.utssg.xyz) | [ZQDesigned](https://github.com/ZQDesigned) |
| [MIUI录屏进化](https://www.coolapk.com/apk/UTSSG.ZQDesigned.miuirecordercracker) | [ZQDesigned](https://github.com/ZQDesigned) |
| [Fuck AD](https://github.com/hujiayucc/Fuck-AD) | [hujiayucc](https://github.com/hujiayucc) |
| [Zuiyou ADFree](https://github.com/kazutoiris/zuiyou-adfree) | [kazutoiris](https://github.com/kazutoiris) |
Are you also using `YukiHookAPI`? Come and **PR** to add your repository to the list above (private repositories do not need to indicate web
links).
## Promotion
If you are looking for a Gradle plugin that can automatically manage Gradle project dependencies,
you can check out the [SweetDependency](https://github.com/HighCapable/SweetDependency) project.
If you are looking for a Gradle plugin that can automatically generate properties key-values,
you can check out the [SweetProperty](https://github.com/HighCapable/SweetProperty) project.
This project also uses **SweetDependency** and **SweetProperty**.
## Star History
![Star History Chart](https://api.star-history.com/svg?repos=HighCapable/YukiHookAPI&type=Date)
## Third-Party Open Source Usage Statement
- [Kotlin Symbol Processing API](https://github.com/google/ksp)
@@ -76,30 +76,24 @@ links).
## License
- [MIT](https://choosealicense.com/licenses/mit)
- [Apache-2.0](https://www.apache.org/licenses/LICENSE-2.0)
```
MIT License
Apache License Version 2.0
Copyright (C) 2019-2023 HighCapable
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
https://www.apache.org/licenses/LICENSE-2.0
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
```
Copyright © 2019-2023 HighCapable

View File

@@ -1,48 +0,0 @@
//file:noinspection unused
plugins {
id 'com.android.application' version '7.3.1' apply false
id 'com.android.library' version '7.3.1' apply false
id 'org.jetbrains.kotlin.android' version '1.7.22' apply false
}
ext {
devId = "0"
devUser = "fankesyooni"
userEmail = "qzmmcn@163.com"
groupId = "com.highcapable.yukihookapi"
apiVersion = "1.1.5"
repoName = "YukiHookAPI"
repoDescription = "An efficient Hook API and Xposed Module solution built in Kotlin."
licenceName = "MIT License"
licenceUrl = "https://github.com/fankes/YukiHookAPI/blob/master/LICENSE"
website = "https://github.com/fankes/YukiHookAPI"
githubConnection = "scm:git:git://github.com/path/to/repo.git"
githubDeveloperConnection = "scm:git:ssh://github.com/path/to/repo.git"
githubUrl = "https://github.com/path/to/repo"
ossName = "OSSRH"
ossUrl = "https://s01.oss.sonatype.org/service/local/staging/deploy/maven2/"
}
/**
* 获取授权文件内容 - 用于 Maven 的提交
*
* 若编译失败请将路径替换为自己的或置空
* @param name
* @return [String]
*/
static String getFileContent(String name) {
String result = ""
try {
FileReader reader = new FileReader("/Users/fankes/Project/Android/Xposed/YukiHookAPI/.gradle/" + name)
BufferedReader buff = new BufferedReader(reader)
result = buff.readLine()
buff.close()
reader.close()
} catch (Throwable ignored) {
}
return result
}
task clean(type: Delete) {
delete rootProject.buildDir
}

7
build.gradle.kts Normal file
View File

@@ -0,0 +1,7 @@
plugins {
autowire(libs.plugins.android.application) apply false
autowire(libs.plugins.android.library) apply false
autowire(libs.plugins.kotlin.jvm) apply false
autowire(libs.plugins.kotlin.android) apply false
autowire(libs.plugins.kotlin.ksp) apply false
}

View File

@@ -1,58 +0,0 @@
plugins {
id 'com.android.application'
id 'org.jetbrains.kotlin.android'
}
android {
signingConfigs {
debug {
storeFile file('../keystore/public')
storePassword '123456'
keyAlias 'public'
keyPassword '123456'
v1SigningEnabled true
v2SigningEnabled true
}
}
compileSdk 33
defaultConfig {
applicationId "com.highcapable.yukihookapi.demo_app"
minSdk 21
targetSdk 33
versionCode 1
versionName "1.0"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled false
signingConfig signingConfigs.debug
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_11
targetCompatibility JavaVersion.VERSION_11
}
kotlinOptions {
jvmTarget = '11'
}
buildFeatures {
viewBinding true
}
}
dependencies {
implementation 'androidx.core:core-ktx:1.9.0'
implementation 'androidx.appcompat:appcompat:1.5.1'
implementation 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.5.1'
implementation 'com.google.android.material:material:1.7.0'
implementation 'androidx.constraintlayout:constraintlayout:2.1.4'
testImplementation 'junit:junit:4.13.2'
androidTestImplementation 'androidx.test.ext:junit:1.1.5'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.5.1'
}

View File

@@ -1,36 +0,0 @@
package com.highcapable.yukihookapi.demo_app.test;
public class Main extends SuperMain {
private final String content;
public Main() {
super("");
content = "";
}
public Main(String content) {
super(content);
this.content = content;
}
public String getTestResultFirst() {
return "The world is beautiful";
}
public String getTestResultFirst(String string) {
return string;
}
public String getTestResultLast() {
return "The world is fantastic";
}
public final String getTestResultLast(String string) {
return string;
}
public String getContent() {
return content;
}
}

View File

@@ -1,22 +0,0 @@
package com.highcapable.yukihookapi.demo_app.test;
public class SuperMain {
private final String content;
public SuperMain(String content) {
this.content = content;
}
public String getSuperString() {
return "The sea is blue";
}
public String getString() {
return getContent();
}
public String getContent() {
return content;
}
}

View File

@@ -1,72 +0,0 @@
plugins {
id 'com.android.application'
id 'org.jetbrains.kotlin.android'
id 'com.google.devtools.ksp' version '1.7.22-1.0.8'
}
android {
signingConfigs {
debug {
storeFile file('../keystore/public')
storePassword '123456'
keyAlias 'public'
keyPassword '123456'
v1SigningEnabled true
v2SigningEnabled true
}
}
compileSdk 33
defaultConfig {
applicationId "com.highcapable.yukihookapi.demo_module"
minSdk 21
targetSdk 33
versionCode 1
versionName "1.0"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled false
signingConfig signingConfigs.debug
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_11
targetCompatibility JavaVersion.VERSION_11
}
kotlinOptions {
jvmTarget = '11'
freeCompilerArgs = [
'-Xno-param-assertions',
'-Xno-call-assertions',
'-Xno-receiver-assertions'
]
}
buildFeatures {
viewBinding true
}
aaptOptions.additionalParameters '--allow-reserved-package-id', '--package-id', '0x64'
}
dependencies {
// Used 82 API Version
compileOnly 'de.robv.android.xposed:api:82'
// Implementation API
implementation project(':yukihookapi')
// Implementation Processor
ksp project(':yukihookapi-ksp-xposed')
implementation 'androidx.preference:preference-ktx:1.2.0'
implementation 'androidx.core:core-ktx:1.9.0'
implementation 'androidx.appcompat:appcompat:1.5.1'
implementation 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.5.1'
implementation 'com.google.android.material:material:1.7.0'
implementation 'androidx.constraintlayout:constraintlayout:2.1.4'
testImplementation 'junit:junit:4.13.2'
androidTestImplementation 'androidx.test.ext:junit:1.1.5'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.5.1'
}

View File

@@ -1 +0,0 @@
com.highcapable.yukihookapi.demo_module.hook.HookEntry_YukiHookXposedInit

View File

@@ -1 +0,0 @@
com.highcapable.yukihookapi.demo_module.hook.HookEntry

View File

@@ -1,39 +0,0 @@
/*
* YukiHookAPI - An efficient Hook API and Xposed Module solution built in Kotlin.
* Copyright (C) 2019-2023 HighCapable
* https://github.com/fankes/YukiHookAPI
*
* MIT License
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
* This file is Created by fankes on 2022/4/15.
*/
package com.highcapable.yukihookapi.demo_module.application
import com.highcapable.yukihookapi.hook.log.loggerD
import com.highcapable.yukihookapi.hook.xposed.application.ModuleApplication
class DemoApplication : ModuleApplication() {
override fun onCreate() {
super.onCreate()
loggerD(msg = "I am running in module space")
}
}

View File

@@ -1,38 +0,0 @@
/*
* YukiHookAPI - An efficient Hook API and Xposed Module solution built in Kotlin.
* Copyright (C) 2019-2023 HighCapable
* https://github.com/fankes/YukiHookAPI
*
* MIT License
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
* This file is Created by fankes on 2022/3/27.
*/
package com.highcapable.yukihookapi.demo_module.data
import com.highcapable.yukihookapi.hook.xposed.channel.data.ChannelData
import com.highcapable.yukihookapi.hook.xposed.prefs.data.PrefsData
object DataConst {
val TEST_KV_DATA = PrefsData("test_data", "Test data is nothing")
val TEST_CN_DATA = ChannelData<String>("key_from_host")
}

View File

@@ -1,3 +1,4 @@
node_modules
src/.vuepress/.cache
src/.vuepress/.temp
/node_modules
/src/.vuepress/.cache
/src/.vuepress/.temp
/dist

View File

@@ -1,15 +1,16 @@
{
"name": "yukihookapi_docs",
"license": "MIT",
"license": "Apache-2.0",
"devDependencies": {
"@mr-hope/vuepress-plugin-copy-code": "^1.30.0",
"@vuepress/plugin-prismjs": "^2.0.0-beta.51",
"@vuepress/plugin-search": "^2.0.0-beta.51",
"@vuepress/plugin-shiki": "^2.0.0-beta.51",
"vuepress": "^2.0.0-beta.51"
"@vuepress/plugin-prismjs": "2.0.0-beta.67",
"@vuepress/plugin-search": "2.0.0-beta.67",
"@vuepress/plugin-shiki": "2.0.0-beta.67",
"vuepress": "2.0.0-beta.67"
},
"scripts": {
"docs:dev": "vuepress dev src",
"docs:build": "vuepress build src"
"docs:build": "vuepress build src",
"docs:build-gh-pages": "vuepress build src && touch dist/.nojekyll"
}
}

View File

@@ -25,7 +25,7 @@ export default {
navbar: navBarItems['/en/'],
selectLanguageText: 'English (US)',
selectLanguageName: 'English',
editLinkText: 'Edit this page on Github',
editLinkText: 'Edit this page on GitHub',
tip: 'Tips',
warning: 'Notice',
danger: 'Pay Attention',
@@ -34,7 +34,7 @@ export default {
navbar: navBarItems['/zh-cn/'],
selectLanguageText: '简体中文 (CN)',
selectLanguageName: '简体中文',
editLinkText: '在 Github 上编辑此页',
editLinkText: '在 GitHub 上编辑此页',
notFound: ['这里什么都没有', '我们怎么到这来了?', '这是一个 404 页面', '看起来我们进入了错误的链接'],
backToHome: '回到首页',
contributorsText: '贡献者',

View File

@@ -5,6 +5,7 @@ const baseApiPath = '/api/public/com/highcapable/yukihookapi/';
const navigationLinks = {
start: [
'/guide/home',
'/guide/supportive',
'/guide/knowledge',
'/guide/quick-start',
'/guide/example',
@@ -15,6 +16,7 @@ const navigationLinks = {
'/config/api-exception',
'/config/xposed-using',
'/config/api-using',
'/config/move-to-api-1-2-x',
'/config/r8-proguard'
],
tools: '/tools/yukihookapi-projectbuilder',
@@ -29,7 +31,7 @@ const navigationLinks = {
baseApiPath + 'hook/param/HookParam',
baseApiPath + 'annotation/xposed/InjectYukiHookWithXposed',
baseApiPath + 'hook/xposed/proxy/IYukiHookXposedInit',
baseApiPath + 'hook/xposed/prefs/YukiHookModulePrefs',
baseApiPath + 'hook/xposed/prefs/YukiHookPrefsBridge',
baseApiPath + 'hook/xposed/prefs/ui/ModulePreferenceFragment',
baseApiPath + 'hook/xposed/prefs/data/PrefsData',
baseApiPath + 'hook/xposed/channel/YukiHookDataChannel',
@@ -40,19 +42,22 @@ const navigationLinks = {
baseApiPath + 'hook/xposed/parasitic/activity/base/ModuleAppCompatActivity',
baseApiPath + 'hook/xposed/parasitic/context/wrapper/ModuleContextThemeWrapper',
baseApiPath + 'hook/xposed/parasitic/reference/ModuleClassLoader',
baseApiPath + 'hook/xposed/bridge/dummy/YukiModuleResources',
baseApiPath + 'hook/xposed/bridge/dummy/YukiResources',
baseApiPath + 'hook/xposed/bridge/dummy/YukiResForwarder',
baseApiPath + 'hook/xposed/bridge/resources/YukiModuleResources',
baseApiPath + 'hook/xposed/bridge/resources/YukiResources',
baseApiPath + 'hook/xposed/bridge/resources/YukiResForwarder',
baseApiPath + 'hook/xposed/bridge/event/YukiXposedEvent',
baseApiPath + 'hook/type/android/ComponentTypeFactory',
baseApiPath + 'hook/type/android/GraphicsTypeFactory',
baseApiPath + 'hook/type/android/ViewTypeFactory',
baseApiPath + 'hook/type/java/VariableTypeFactory',
baseApiPath + 'hook/type/defined/DefinedTypeFactory',
baseApiPath + 'hook/log/LoggerFactory',
baseApiPath + 'hook/log/YLog',
baseApiPath + 'hook/log/data/YLogData',
baseApiPath + 'hook/factory/ReflectionFactory',
baseApiPath + 'hook/factory/YukiHookFactory',
baseApiPath + 'hook/entity/YukiBaseHooker',
baseApiPath + 'hook/core/api/compat/type/ExecutorType',
baseApiPath + 'hook/core/api/priority/YukiHookPriority',
baseApiPath + 'hook/core/YukiMemberHookCreator',
baseApiPath + 'hook/core/YukiResourcesHookCreator',
baseApiPath + 'hook/core/finder/members/MethodFinder',
@@ -93,7 +98,7 @@ const navigationLinks = {
export const configs = {
dev: {
dest: '../docs/',
dest: 'dist',
port: 9000
},
website: {
@@ -113,7 +118,7 @@ export const configs = {
}
},
github: {
repo: 'https://github.com/fankes/YukiHookAPI',
repo: 'https://github.com/HighCapable/YukiHookAPI',
branch: 'master',
dir: 'docs-source/src'
}
@@ -126,10 +131,11 @@ export const navBarItems = {
text: 'Get Started',
children: [
{ text: 'Introduce', link: i18n.string(navigationLinks.start[0], 'en') },
{ text: 'Basic Knowledge', link: i18n.string(navigationLinks.start[1], 'en') },
{ text: 'Quick Start', link: i18n.string(navigationLinks.start[2], 'en') },
{ text: 'Usage Example', link: i18n.string(navigationLinks.start[3], 'en') },
{ text: 'Migrate from Xposed API', link: i18n.string(navigationLinks.start[4], 'en') }
{ text: 'Supportive', link: i18n.string(navigationLinks.start[1], 'en') },
{ text: 'Basic Knowledge', link: i18n.string(navigationLinks.start[2], 'en') },
{ text: 'Quick Start', link: i18n.string(navigationLinks.start[3], 'en') },
{ text: 'Usage Example', link: i18n.string(navigationLinks.start[4], 'en') },
{ text: 'Migrate from Other Hook APIs', link: i18n.string(navigationLinks.start[5], 'en') }
]
}, {
text: 'Configs',
@@ -138,7 +144,8 @@ export const navBarItems = {
{ text: 'API Exception Handling', link: i18n.string(navigationLinks.config[1], 'en') },
{ text: 'Use as Xposed Module Configs', link: i18n.string(navigationLinks.config[2], 'en') },
{ text: 'Use as Hook API Configs', link: i18n.string(navigationLinks.config[3], 'en') },
{ text: 'R8 & Proguard Obfuscate', link: i18n.string(navigationLinks.config[4], 'en') }
{ text: 'Migrate to YukiHookAPI 1.2.x', link: i18n.string(navigationLinks.config[4], 'en') },
{ text: 'R8 & Proguard Obfuscate', link: i18n.string(navigationLinks.config[5], 'en') }
]
}, {
text: 'Tools',
@@ -175,10 +182,11 @@ export const navBarItems = {
text: '入门',
children: [
{ text: '介绍', link: i18n.string(navigationLinks.start[0], 'zh-cn') },
{ text: '基础知识', link: i18n.string(navigationLinks.start[1], 'zh-cn') },
{ text: '快速开始', link: i18n.string(navigationLinks.start[2], 'zh-cn') },
{ text: '用法示例', link: i18n.string(navigationLinks.start[3], 'zh-cn') },
{ text: '从 Xposed API 迁移', link: i18n.string(navigationLinks.start[4], 'zh-cn') }
{ text: '支持性', link: i18n.string(navigationLinks.start[1], 'zh-cn') },
{ text: '基础知识', link: i18n.string(navigationLinks.start[2], 'zh-cn') },
{ text: '快速开始', link: i18n.string(navigationLinks.start[3], 'zh-cn') },
{ text: '用法示例', link: i18n.string(navigationLinks.start[4], 'zh-cn') },
{ text: '从其它 Hook API 迁移', link: i18n.string(navigationLinks.start[5], 'zh-cn') }
]
}, {
text: '配置',
@@ -187,7 +195,8 @@ export const navBarItems = {
{ text: 'API 异常处理', link: i18n.string(navigationLinks.config[1], 'zh-cn') },
{ text: '作为 Xposed 模块使用的相关配置', link: i18n.string(navigationLinks.config[2], 'zh-cn') },
{ text: '作为 Hook API 使用的相关配置', link: i18n.string(navigationLinks.config[3], 'zh-cn') },
{ text: 'R8 与 Proguard 混淆', link: i18n.string(navigationLinks.config[4], 'zh-cn') }
{ text: '迁移到 YukiHookAPI 1.2.x', link: i18n.string(navigationLinks.config[4], 'zh-cn') },
{ text: 'R8 与 Proguard 混淆', link: i18n.string(navigationLinks.config[5], 'zh-cn') }
]
}, {
text: '工具',

View File

@@ -4,30 +4,24 @@
## License
[The MIT License (MIT)](https://github.com/fankes/YukiHookAPI/blob/master/LICENSE)
[Apache-2.0](https://github.com/HighCapable/YukiHookAPI/blob/master/LICENSE)
```:no-line-numbers
MIT License
Apache License Version 2.0
Copyright (C) 2019-2023 HighCapable
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
https://www.apache.org/licenses/LICENSE-2.0
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
```
Copyright © 2019-2023 HighCapable

View File

@@ -16,7 +16,101 @@ Time zone of version release date: **UTC+8**
:::
### 1.1.5 | 2023.01.13 &ensp;<Badge type="tip" text="latest" vertical="middle" />
### 1.2.0 | 2023.10.07 &ensp;<Badge type="tip" text="latest" vertical="middle" />
- The license agreement has been changed from `MIT` to `Apache-2.0`, subsequent versions will be distributed under this license agreement, you should change the relevant license agreement after using this version
- This is a breaking update, please refer to [Migrate to YukiHookAPI 1.2.x](https://highcapable.github.io/YukiHookAPI/en/config/move-to-api-1-2-x) for details
- Adapted to Android 14, thanks to [BlueCat300](https://github.com/BlueCat300) for [PR](https://github.com/HighCapable/YukiHookAPI/pull/44)
- Fixed `findAllInterfaces` related issues, thanks to [buffcow](https://github.com/buffcow) for [PR](https://github.com/HighCapable/YukiHookAPI/pull/38)
- Fixed the delayed callback problem in the Hook process, thanks to [cesaryuan](https://github.com/cesaryuan) for his [Issue](https://github.com/HighCapable/YukiHookAPI/issues/47)
- Added support for Resources Hook related functions, please refer to this [Issue](https://github.com/HighCapable/YukiHookAPI/issues/36) for details
- Added `YukiHookAPI.TAG`
- Obsolete ~~`YukiHookAPI.API_VERSION_NAME`~~, ~~`YukiHookAPI.API_VERSION_CODE`~~, merged into `YukiHookAPI.VERSION`
- Added `YukiHookAPI.TAG`
- Obsolete ~~`YYukiHookAPI.API_VERSION_NAME`~~, ~~`YukiHookAPI.API_VERSION_CODE`~~, merged into `YukiHookAPI.VERSION`
- Deprecated the `useDangerousOperation` method in `YukiMemberHookCreator`
- The `instanceClass` function in `YukiMemberHookCreator` is obsolete and is no longer recommended
- Modify `instanceClass` in `HookParam` to be a null safe return value type
- Detach all Hook objects created using `injectMember` to `LegacyCreator`
- Modify `appClassLoader` in `PackageParam` to be a null safe return value type
- Refactor all `logger...` methods to new usage `YLog`
- Removed the `-->` style behind the print log function
- Fixed and improved the problem that the module package name cannot be obtained through KSP after using `namespace`
- Functions such as whether to enable module activation status have now been moved to the `InjectYukiHookWithXposed` annotation
- Detached [FreeReflection](https://github.com/tiann/FreeReflection) will no longer be automatically generated and will be automatically imported as a dependency
- Added a warning log that will be automatically printed when the same Hook method is repeated
- The `findClass(...)` method in `PackageParam` is obsolete, please migrate to the `"...".toClass()` method
- The `String.hook { ... }` method in `PackageParam` is obsolete, and it is recommended to use a new method for Hook
- `AppLifecycle` can now be created repeatedly in different Hookers
- The old version of Hook priority writing is obsolete and migrated to `YukiHookPriority`
- Removed the `tag` function in the Hook process
- Refactored `remendy` functionality in find methods, which now prints exceptions in steps
- The multi-method find result type is changed from `HashSet` to `MutableList`
- Added `method()`, `constructor()`, `field()` to directly obtain all object functions in the class
- `constructor()` no longer behaves like `constructor { emptyParam() }`
- Added `lazyClass` and `lazyClassOrNull` methods to lazily load `Class`
### 1.1.11 | 2023.04.25 &ensp;<Badge type="warning" text="stale" vertical="middle" />
- Fixed a critical issue since `1.1.5` version where the `Member` cache did not take effect and persistent storage eventually caused app out of memory (OOM), thanks to [Art-Chen](https://github.com/Art-Chen)
- Remove the direct cache function of `Member` and deprecated ~~`YukiReflection.Configs.isEnableMemberCache`~~, keep the cache function of `Class`
- Modified finder to `Sequence`, optimize the finding speed and performance of `Member`
- Remove the `YukiHookPrefsBridge`'s direct key-value cache function and removed `LruCache` related functions
- Deprecated ~~`YukiHookAPI.Configs.isEnablePrefsBridgeCache`~~
- Deprecated ~~`direct`~~, ~~`clearCache`~~ functions in `YukiHookPrefsBridge`
### 1.1.10 | 2023.04.21 &ensp;<Badge type="warning" text="stale" vertical="middle" />
- The `Activity` proxy function adds the function of specifying a separate proxy `Activity` for each proxied `Activity`
- Fixed problem that the `contains` and `all` methods in `YukiHookPrefsBridge` did not judge the `native` function
- Integrate the cache function in `YukiHookPrefsBridge` into `PreferencesCacheManager` and use `LruCache` as a key-value pair cache
- Modify `YukiHookPrefsBridge` key-value pair caching function to take effect in all environments (Module Apps, Host Apps)
- Modify part of `HashMap` used for caching to `ArrayMap` to reduce memory consumption
- Fix some other possible problems
### 1.1.9 | 2023.04.17 &ensp;<Badge type="warning" text="stale" vertical="middle" />
- Change the type of dependent library from **Java Library** (jar) to **Android Library** (aar)
- Remove the inspection function of internal methods and parameters through Hook or reflection API
- Fixed the problem that `YukiHookDataChannel` automatically segmented data sending function could not work normally (exception would still be thrown)
- Added the ability to manually modify the maximum data byte size allowed by `YukiHookDataChannel` to be sent at one time according to the limitations of the target device
- Remove the restriction that `YukiHookDataChannel` can only be used in module `Activity`, now you can use it anywhere
- Modify and standardize the broadcast Action name used by `YukiHookDataChannel`
- Fix the problem that `BadParcelableException` occurs when `YukiHookDataChannel` has different modules with the same host
- Added `ExecutorType`, you can get the type of known Hook Framework through `YukiHookAPI.Status.Executor.type`
- ~~`YukiHookModulePrefs`~~ renamed to `YukiHookPrefsBridge`
- Modify `YukiHookPrefsBridge` to be implemented as a non-singleton, as a singleton may cause data confusion
- Deprecated ~~`Context.modulePrefs(...)`~~ method, please move to `Context.prefs(...)`
- `YukiHookPrefsBridge` adds `native` method, which supports storing private data in modules and hosts directly as native storage
- Integrate the storage method in `YukiHookPrefsBridge` to `YukiHookPrefsBridge.Editor`, please use `edit` method to store data
- `YukiHookPrefsBridge` adds `contains` method
- Cache dynamically created proxy objects in `YukiHookPrefsBridge`, try to fix problems that may cause OOM in the host and modules
- Modify the proxy class of the `Activity` proxy function to be dynamically generated to prevent conflicts caused by injecting different modules into the host
- Fixed some other possible problems
### 1.1.8 | 2023.02.01 &ensp;<Badge type="warning" text="stale" vertical="middle" />
- Fixed the problem that the underlying Hook method cannot update the modified state synchronously when modifying parameters such as `result` during callback, thanks to the [Issue](https://github.com/HighCapable/YukiHookAPI/issues/23) of [Yongzheng Lai](https://github.com/elvizlai)
- Move the entry class name file automatically generated by `YukiHookAPI` from `assets/yukihookapi_init` to `resources/META-INF/yukihookapi_init`
- When only printing the exception stack, the `msg` parameter is allowed to be empty and the `msg` parameter can not be set, and the log with the `msg` parameter left blank will not be logged unless the exception stack is not empty
- Fixed the bug that the log printed by the exception that occurs in the body of the Hook callback method has no specific method information
- `HookParam` adds `instanceOrNull` variable and method, which can be used on the premise that the Hook instance is not sure whether it is empty to prevent the Hook instance from being empty and throw an exception
- Decoupled all hookers in `Member` lookup functionality to `MemberBaseFinder.MemberHookerManager`
- Modified the usage of `by` condition in `YukiMemberHookCreator`, now you can reuse `by` method to set multiple conditions
- Removed wrong `Class` object declaration in Android `type`
- The `registerReceiver` method in `PackageParam.AppLifecycle` adds the function of directly using `IntentFilter` to create a system broadcast listener
- Fixed the problem that there may be multiple registration lifecycles in `PackageParam.AppLifecycle`
- Revert: The 1.1.7 version has been withdrawn due to a serious problem, please update to this version directly (the update log is the same as version 1.1.7)
### 1.1.6 | 2023.01.21 &ensp;<Badge type="warning" text="stale" vertical="middle" />
- Fixed the serious problem that `ClassLoader` does not match after `PackageParam` keeps a single instance when there may be multiple package names in the same process when Xposed Module is loaded
- When the package name is not distinguished when there are multiple package names in the same process, stop loading the singleton child Hooker and print a warning message
- Fixed the problem that the number of parameters is incorrect when methods such as `HookParam.callOriginal`, `HookParam.invokeOriginal` call the original method
- Modify the method parameter name `param` of reflection calls in `MethodFinder`, `ConstructorFinder`, `ReflectionFactory` to `args`
- Added the function of judging the parameters of the entry class constructor in the automatic processing program of the Xposed Module, the entry class needs to ensure that it does not have any constructor parameters
### 1.1.5 | 2023.01.13 &ensp;<Badge type="warning" text="stale" vertical="middle" />
- Standardize and optimize the overall code style
- Privatized some APIs called internally
@@ -113,7 +207,7 @@ Time zone of version release date: **UTC+8**
- Added `generic` function to reflect and call generics, you can use it in `Class` or `CurrentClass`
- obsolete the `buildOfAny` method, now use the `buildOf` method directly (without generics) to use the constructor to create a new object and get the result `Any`
- Fixed the issue of null pointer exception when using `hasExtends`
- `CurrentClass` added non-`lambda` method of calling
- `CurrentClass` added non-**lambda** method of calling
- `CurrentClass` adds `name` and `simpleName` functions
- Completely rewrite the core method of `ReflectionTool`, sorting and classifying different search conditions
- Fixed the problem that `Member` obtained by directly calling `declared` in `ReflectionTool` throws an exception
@@ -129,7 +223,7 @@ Time zone of version release date: **UTC+8**
- Added multiple search function in reflection search, you can use relative search conditions to obtain multiple search results at the same time, thanks to **AA** and [Kitsune](https://github.com/KyuubiRan) for suggestions
- Fixed the problem that the object obtained by `appClassLoader` is incorrect in system applications in some systems, thanks to [Luckyzyx](https://github.com/luckyzyx) for the feedback
- Modified the calling method of `XposedBridge.invokeOriginalMethod` and added `original` function in `MethodFinder.Result.Instance`
- Fixed the problem of wrong value of `getStringSet` method in `YukiHookModulePrefs` and optimize the code style, thanks to [Teddy_Zhu](https://github.com/Teddy-Zhu) [PR](https://github.com/fankes/YukiHookAPI/pull/19)
- Fixed the problem of wrong value of `getStringSet` method in `YukiHookModulePrefs` and optimize the code style, thanks to [Teddy_Zhu](https://github.com/Teddy-Zhu) [PR](https://github.com/HighCapable/YukiHookAPI/pull/19)
- Modify `YukiHookModulePrefs` to intercept exceptions that may not exist in `XSharePreference`
- Fixed the problem that `YukiHookDataChannel` could not be successfully registered in some third-party ROM system frameworks
- Secured `YukiHookDataChannel`, now it can only communicate between modules from the specified package name and the host
@@ -152,7 +246,7 @@ Time zone of version release date: **UTC+8**
- Added the function of removing Hook in the Hook process, you can use the `remove` and `removeSelf` methods to remove the hook
- Fixed the issue that caused the host to throw an exception when ReplaceHook failed, and now it is modified to call the original method to ensure the normal operation of the host function
- Added the function of checking the return value of the method in the Hook process. If the return value does not match, it will automatically throw an exception or print an error according to the situation
- Added `array` type to Resources Hook, thanks to [PR](https://github.com/fankes/YukiHookAPI/pull/12) of [GSWXXN](https://github.com/GSWXXN)
- Added `array` type to Resources Hook, thanks to [PR](https://github.com/HighCapable/YukiHookAPI/pull/12) of [GSWXXN](https://github.com/GSWXXN)
- Moved `me.weishu.reflection` to `thirdparty` to prevent conflicting dependencies of the same name introduced at the same time
- Remove the exception thrown when the Hook method body is empty, and modify it to print the warning log
- Modify the exception handling logic of `AppLifecycle` and throw it directly to the host when an exception occurs
@@ -242,7 +336,7 @@ Time zone of version release date: **UTC+8**
- ~~`YukiHookXposedInitProxy`~~ renamed to `IYukiHookXposedInit`, the original interface name has been invalidated and will be deleted directly in subsequent versions
- Added `initZygote` and Resources Hook functions to support Hook Layout
- Added `onXposedEvent` method to listen to all events of native Xposed API
- Perform `inline` processing on the `lambda` of the Hook function to avoid generating excessively broken anonymous classes and improve the running performance after compilation
- Perform `inline` processing on the **lambda** of the Hook function to avoid generating excessively broken anonymous classes and improve the running performance after compilation
- Fixed `PrefsData` compiled method body copy is too large
- Added `XSharePreference` readability test, which will automatically print a warning log if it fails
- `PackageParam` adds `appResources`, `moduleAppResources`, `moduleAppFilePath` functions
@@ -270,7 +364,7 @@ Time zone of version release date: **UTC+8**
- Fixed `YukiHookModulePrefs` working in `New XSharePreference` mode
- Added `ModulePreferenceFragment`, now you can completely replace `PreferenceFragmentCompat` and start using the new functionality
- Adapt the Sp data storage solution of `PreferenceFragmentCompat`, thanks to [mahoshojoHCG](https://github.com/mahoshojoHCG) for feedback
- Update autohandlers and `Kotlin` dependencies to the latest version
- Update autohandlers and Kotlin dependencies to the latest version
- Fixed some bugs in documentation and code comments
### 1.0.77 | 2022.04.15 &ensp;<Badge type="danger" text="outdate" vertical="middle" />
@@ -361,7 +455,7 @@ Time zone of version release date: **UTC+8**
- Added `MethodFinder` and `FieldFinder` new return value calling methods
- Fixed possible problems and fix possible problems during the use of Tai Chi
- Fixed possible problems with auto-generated Xposed entry classes
- Added `android` type and `java` type in `type`
- Added `android` type and Java type in `type`
### 1.0.6 | 2022.03.20 &ensp;<Badge type="danger" text="outdate" vertical="middle" />
@@ -378,7 +472,7 @@ Time zone of version release date: **UTC+8**
- Fixed an annotation error
- Temporarily fix a bug
- Added a large number of `android` types in `type` and a small number of `java` types
- Added a large number of `android` types in `type` and a small number of Java types
- Fixed compatibility issues between new and old Kotlin APIs
### 1.0.5 | 2022.03.18 &ensp;<Badge type="danger" text="outdate" vertical="middle" />
@@ -414,7 +508,7 @@ Time zone of version release date: **UTC+8**
- `RemedyPlan` adds `onFind` function
- Integrate and modify some reflection API code
- Added `java` type in `type`
- Added Java type in `type`
- Fixed the issue that ignored errors still output in the console
### 1.0 | 2022.02.14 &ensp;<Badge type="danger" text="outdate" vertical="middle" />

View File

@@ -2,12 +2,12 @@
> If you have any questions in use, or have any constructive suggestions, you can contact us.
Join us [Click to join Telegram group](https://t.me/YukiHookAPI)
Join us [Click to join Telegram group](https://t.me/YukiHookAPI), [Click to join Telegram group (Developer)](https://t.me/HighCapable_Dev).
Find me on **Twitter** [@fankesyooni](https://twitter.com/fankesyooni)
Find me on **Twitter** [@fankesyooni](https://twitter.com/fankesyooni).
## Help with Maintenance
Thank you for choosing and using `YukiHookAPI`.
If you have code-related suggestions and requests, you can submit a Pull Request on Github.
If you have code-related suggestions and requests, you can submit a Pull Request on GitHub.

View File

@@ -6,7 +6,7 @@
> Here are the unresolved issues with `YukiHookAPI`.
### YukiHookModulePrefs
### YukiHookPrefsBridge
Currently only supports LSPosed perfectly, other Xposed Framework need to downgrade the module target api.
@@ -16,17 +16,31 @@ Some Xposed Module developers currently choose the Hook target app self's Shared
In the later period, the permissions of the Android system will become more and more strict, and `selinux` is a big problem currently facing, which needs to be discussed and studied.
::: tip Updated on 2023.10.06
LSPosed has now experimentally launched [Modern Xposed API](https://github.com/libxposed), which uses Service to communicate with modules, which will solve the problem of module data storage.
In order to ensure the compatibility of most modules, **YukiHookAPI** plans to use a customized ContentProvider to realize data exchange between the Module App and the Host App in the future, so stay tuned.
:::
## Future Plans
> Features that `YukiHookAPI` may add later are included here.
### Lite Version Supported for Standalone Use
If you like the Reflection API of `YukiHookAPI`, but your project may not need related Hook functions.
Well here is some good news for you:
The core Reflection API of `YukiHookAPI` has been decoupled into [YukiReflection](https://github.com/HighCapable/YukiReflection) project, which can now be used in any Android project.
::: tip To be Discussed
At present, the API only supports binding to **xposed_init** through the automatic handler.
At present, the API only supports binding to **xposed_init** through the automatic builder.
If you don't like the automatic handler, you must implement the module loading entry yourself.
If you don't like the automatic builder, you must implement the module loading entry yourself.
In the future, the Lite version with only API functions will be launched according to the number of people required.
@@ -36,8 +50,12 @@ You can submit **issues** with us.
We have provided the Xposed native API listening interface, you can find or view the implementation method of the Demo [here](../config/xposed-using#native-xposed-api-events).
### Support for More Hook Framework
### Milestone Plan
As an API, currently only docking `XposedBridge` as a compatibility layer still has certain limitations.
The plans below have been published in `issues` on GitHub, and you can view the progress of each project.
Most `inline hook` do not have a `Java` compatibility layer, and the `Java` compatibility layer adaptation of `native hook` may be considered later.
All functions are expected to be completed in `2.0.0` version, so stay tuned.
- [New Xposed Module Config Plan](https://github.com/HighCapable/YukiHookAPI/issues/49)
- [New Hook Entry Class](https://github.com/HighCapable/YukiHookAPI/issues/48)
- [New Hook Code Style](https://github.com/HighCapable/YukiHookAPI/issues/33)

View File

@@ -24,33 +24,53 @@ object YukiHookAPI
> 这是 `YukiHookAPI` 的 API 调用总类Hook 相关功能的开始、Hook 相关功能的配置都在这里。
## API_VERSION_NAME <span class="symbol">- field</span>
## TAG <span class="symbol">- field</span>
```kotlin:no-line-numbers
const val API_VERSION_NAME: String
const val TAG: String
```
**Change Records**
`v1.0.4` `added`
`v1.2.0` `added`
**Function Illustrate**
> 获取当前 `YukiHookAPI` 的名称 (标签)。
## VERSION <span class="symbol">- field</span>
```kotlin:no-line-numbers
const val VERSION: String
```
**Change Records**
`v1.2.0` `added`
**Function Illustrate**
> 获取当前 `YukiHookAPI` 的版本。
## API_VERSION_CODE <span class="symbol">- field</span>
```kotlin:no-line-numbers
const val API_VERSION_CODE: Int
```
<h2 class="deprecated">API_VERSION_NAME - field</h2>
**Change Records**
`v1.0.4` `added`
**Function Illustrate**
`v1.2.0` `deprecated`
> 获取当前 `YukiHookAPI` 的版本号。
不再区分版本名称和版本号,请迁移到 `VERSION`
<h2 class="deprecated">API_VERSION_CODE - field</h2>
**Change Records**
`v1.0.4` `added`
`v1.2.0` `deprecated`
不再区分版本名称和版本号,请迁移到 `VERSION`
<h2 class="deprecated">executorName - field</h2>
@@ -60,7 +80,7 @@ const val API_VERSION_CODE: Int
`v1.0.91` `removed`
移到 `Status.Executor.name`
移到 `Status.Executor.name`
<h2 class="deprecated">executorVersion - field</h2>
@@ -70,7 +90,7 @@ const val API_VERSION_CODE: Int
`v1.0.91` `removed`
移到 `Status.Executor.apiLevel`、`Status.Executor.versionName`、`Status.Executor.versionCode`
移到 `Status.Executor.apiLevel`、`Status.Executor.versionName`、`Status.Executor.versionCode`
## Status <span class="symbol">- object</span>
@@ -114,7 +134,7 @@ val isXposedEnvironment: Boolean
> 获取当前是否为 (Xposed) 宿主环境。
<h3 class="deprecated">executorName - field</h3>
<h2 class="deprecated">executorName - field</h2>
**Change Records**
@@ -122,9 +142,9 @@ val isXposedEnvironment: Boolean
`v1.1.5` `deprecated`
移到 `Executor.name`
移到 `Executor.name`
<h3 class="deprecated">executorVersion - field</h3>
<h2 class="deprecated">executorVersion - field</h2>
**Change Records**
@@ -132,7 +152,7 @@ val isXposedEnvironment: Boolean
`v1.1.5` `deprecated`
移到 `Executor.apiLevel`、`Executor.versionName`、`Executor.versionCode`
移到 `Executor.apiLevel`、`Executor.versionName`、`Executor.versionCode`
### isModuleActive <span class="symbol">- field</span>
@@ -152,7 +172,7 @@ val isModuleActive: Boolean
在模块环境中你需要将 **Application** 继承于 **ModuleApplication**。
在模块环境中需要启用 **Configs.isEnableHookModuleStatus**。
在模块环境中需要启用 **InjectYukiHookWithXposed.isUsingXposedModuleStatus**。
在 (Xposed) 宿主环境中仅返回非 **isTaiChiModuleActive** 的激活状态。
@@ -174,7 +194,7 @@ val isXposedModuleActive: Boolean
::: warning
在模块环境中需要启用 **Configs.isEnableHookModuleStatus**。
在模块环境中需要启用 **InjectYukiHookWithXposed.isUsingXposedModuleStatus**。
在 (Xposed) 宿主环境中始终返回 true。
@@ -214,11 +234,11 @@ val isSupportResourcesHook: Boolean
**Function Illustrate**
> 判断当前 Hook Framework 是否支持资源钩子(Resources Hook)。
> 判断当前 Hook Framework 是否支持资源钩子 (Resources Hook)。
::: warning
在模块环境中需要启用 **Configs.isEnableHookModuleStatus**。
在模块环境中需要启用 **InjectYukiHookWithXposed.isUsingXposedModuleStatus**。
在 (Xposed) 宿主环境中可能会延迟等待事件回调后才会返回 true。
@@ -256,7 +276,27 @@ val name: String
::: warning
在模块环境中需要启用 **Configs.isEnableHookModuleStatus**。
在模块环境中需要启用 **InjectYukiHookWithXposed.isUsingXposedModuleStatus**。
:::
#### type <span class="symbol">- field</span>
```kotlin:no-line-numbers
val type: ExecutorType
```
**Change Records**
`v1.1.9` `added`
**Function Illustrate**
> 获取当前 Hook Framework 类型。
::: warning
在模块环境中需要启用 **InjectYukiHookWithXposed.isUsingXposedModuleStatus**。
:::
@@ -276,7 +316,7 @@ val apiLevel: Int
::: warning
在模块环境中需要启用 **Configs.isEnableHookModuleStatus**。
在模块环境中需要启用 **InjectYukiHookWithXposed.isUsingXposedModuleStatus**。
:::
@@ -296,7 +336,7 @@ val versionName: String
::: warning
在模块环境中需要启用 **Configs.isEnableHookModuleStatus**。
在模块环境中需要启用 **InjectYukiHookWithXposed.isUsingXposedModuleStatus**。
:::
@@ -316,7 +356,7 @@ val versionCode: Int
::: warning
在模块环境中需要启用 **Configs.isEnableHookModuleStatus**。
在模块环境中需要启用 **InjectYukiHookWithXposed.isUsingXposedModuleStatus**。
:::
@@ -337,7 +377,7 @@ object Configs
### debugLog <span class="symbol">- method</span>
```kotlin:no-line-numbers
inline fun debugLog(initiate: YukiHookLogger.Configs.() -> Unit)
inline fun debugLog(initiate: YLog.Configs.() -> Unit)
```
**Change Records**
@@ -346,7 +386,7 @@ inline fun debugLog(initiate: YukiHookLogger.Configs.() -> Unit)
**Function Illustrate**
> 配置 `YukiHookLogger.Configs` 相关参数。
> 配置 `YLog.Configs` 相关参数。
<h3 class="deprecated">debugTag - field</h3>
@@ -356,7 +396,7 @@ inline fun debugLog(initiate: YukiHookLogger.Configs.() -> Unit)
`v1.1.0` `deprecated`
移到 `YukiHookLogger.Configs.tag`
移到 `YLog.Configs.tag`
### isDebug <span class="symbol">- field</span>
@@ -370,9 +410,9 @@ var isDebug: Boolean
**Function Illustrate**
> 是否启用 DEBUG 模式。
> 是否启用 Debug 模式。
默认为开启状态,开启后模块将会向 `Logcat` 和 `XposedBridge.log` 打印详细的 Hook 日志,关闭后仅会打印 `E` 级别的日志。
默认不启用,启用后模块将会向 `Logcat` 和 (Xposed) 宿主环境中的日志功能打印详细的 Hook 日志,关闭后仅会打印 `E` 级别的日志。
<h3 class="deprecated">isAllowPrintingLogs - field</h3>
@@ -382,25 +422,27 @@ var isDebug: Boolean
`v1.1.0` `deprecated`
移到 `YukiHookLogger.Configs.isEnable`
移到 `YLog.Configs.isEnable`
### isEnableModulePrefsCache <span class="symbol">- field</span>
```kotlin:no-line-numbers
var isEnableModulePrefsCache: Boolean
```
<h3 class="deprecated">isEnableModulePrefsCache - field</h3>
**Change Records**
`v1.0.5` `added`
**Function Illustrate**
`v1.1.9` `deprecated`
> 是否启用 `YukiHookModulePrefs` 的键值缓存功能。
请迁移到 `isEnablePrefsBridgeCache`
为防止内存复用过高问题,此功能默认启用。
<h3 class="deprecated">isEnablePrefsBridgeCache - field</h3>
你可以手动在 `YukiHookModulePrefs` 中自由开启和关闭缓存功能以及清除缓存。
**Change Records**
`v1.1.9` `added`
`v1.1.11` `deprecated`
键值的直接缓存功能已被移除,因为其存在内存溢出 (OOM) 问题
### isEnableModuleAppResourcesCache <span class="symbol">- field</span>
@@ -426,27 +468,15 @@ var isEnableModuleAppResourcesCache: Boolean
:::
### isEnableHookModuleStatus <span class="symbol">- field</span>
<h3 class="deprecated">isEnableHookModuleStatus - field</h3>
```kotlin:no-line-numbers
var isEnableHookModuleStatus: Boolean
```
**Change Records**
**变更记录**
`v1.0.88` `added`
**Function Illustrate**
`v1.2.0` `deprecated`
> 是否启用 Hook Xposed 模块激活等状态功能.
为原生支持 Xposed 模块激活状态检测,此功能默认启用。
::: warning
关闭后你将不能再在模块环境中使用 **YukiHookAPI.Status** 中的激活状态判断功能。
:::
请手动迁移到 `InjectYukiHookWithXposed.isUsingXposedModuleStatus`
### isEnableHookSharedPreferences <span class="symbol">- field</span>
@@ -468,7 +498,7 @@ var isEnableHookSharedPreferences: Boolean
这是一个可选的实验性功能,此功能默认不启用。
仅用于修复某些系统可能会出现在启用了 **New XSharedPreferences** 后依然出现文件权限错误问题,若你能正常使用 **YukiHookModulePrefs** 就不建议启用此功能。
仅用于修复某些系统可能会出现在启用了 **New XSharedPreferences** 后依然出现文件权限错误问题,若你能正常使用 **YukiHookPrefsBridge** 就不建议启用此功能。
:::
@@ -490,33 +520,15 @@ var isEnableDataChannel: Boolean
此功能默认启用,关闭后将不会在功能初始化的时候装载 `YukiHookDataChannel`。
### isEnableMemberCache <span class="symbol">- field</span>
```kotlin:no-line-numbers
var isEnableMemberCache: Boolean
```
<h3 class="deprecated">isEnableMemberCache - field</h3>
**Change Records**
`v1.0.68` `added`
`v1.0.80` `modified`
`v1.1.11` `deprecated`
将方法体进行 inline
**Function Illustrate**
> 是否启用 `Member` 缓存功能。
为防止 `Member` 复用过高造成的系统 GC 问题,此功能默认启用。
启用后会缓存已经找到的 `Method`、`Constructor`、`Field`。
缓存的 `Member` 都将处于 `MemberCacheStore` 的全局静态实例中。
推荐使用 `MethodFinder`、`ConstructorFinder`、`FieldFinder` 来获取 `Member`。
除非缓存的 `Member` 发生了混淆的问题,例如使用 R8 混淆后的 APP 的目标 `Member`,否则建议启用。
`Member` 的直接缓存功能已被移除,因为其存在内存溢出 (OOM) 问题
## configs <span class="symbol">- method</span>
@@ -528,20 +540,24 @@ inline fun configs(initiate: Configs.() -> Unit)
`v1.0` `first`
`v1.0.80` `modified`
将方法体进行 inline
**Function Illustrate**
> 对 `Configs` 类实现了一个 `lambda` 方法体。
> 对 `Configs` 类实现了一个 **lambda** 方法体。
你可以轻松调用它进行配置。
你可以轻松调用它进行配置。
**Function Example**
你可以在 `HookEntryClass` 的 `onInit` 方法中调用 `configs` 方法和 `debugLog` 方法完成对 API 的功能配置,实时生效。
你可以在 Hook 入口类的 `onInit` 方法中调用 `configs` 方法和 `debugLog` 方法完成对 API 的功能配置,实时生效。
> The following example
```kotlin
class HookEntryClass : IYukiHookXposedInit {
object HookEntry : IYukiHookXposedInit {
override fun onInit() {
YukiHookAPI.configs {
@@ -552,12 +568,10 @@ class HookEntryClass : IYukiHookXposedInit {
elements(TAG, PRIORITY, PACKAGE_NAME, USER_ID)
}
isDebug = BuildConfig.DEBUG
isEnableModulePrefsCache = true
isEnableModuleAppResourcesCache = true
isEnableHookModuleStatus = true
isEnableHookSharedPreferences = false
isEnableDataChannel = true
isEnableMemberCache = true
}
}
@@ -572,7 +586,7 @@ class HookEntryClass : IYukiHookXposedInit {
> The following example
```kotlin
class HookEntryClass : IYukiHookXposedInit {
object HookEntry : IYukiHookXposedInit {
override fun onInit() = configs {
debugLog {
@@ -582,12 +596,10 @@ class HookEntryClass : IYukiHookXposedInit {
elements(TAG, PRIORITY, PACKAGE_NAME, USER_ID)
}
isDebug = BuildConfig.DEBUG
isEnableModulePrefsCache = true
isEnableModuleAppResourcesCache = true
isEnableHookModuleStatus = true
isEnableHookSharedPreferences = false
isEnableDataChannel = true
isEnableMemberCache = true
}
override fun onHook() {
@@ -601,25 +613,23 @@ class HookEntryClass : IYukiHookXposedInit {
> The following example
```kotlin
class HookEntryClass : IYukiHookXposedInit {
object HookEntry : IYukiHookXposedInit {
override fun onInit() {
YukiHookLogger.Configs.tag = "YukiHookAPI"
YukiHookLogger.Configs.isEnable = true
YukiHookLogger.Configs.isRecord = false
YukiHookLogger.Configs.elements(
YukiHookLogger.Configs.TAG,
YukiHookLogger.Configs.PRIORITY,
YukiHookLogger.Configs.PACKAGE_NAME,
YukiHookLogger.Configs.USER_ID
YLog.Configs.tag = "YukiHookAPI"
YLog.Configs.isEnable = true
YLog.Configs.isRecord = false
YLog.Configs.elements(
YLog.Configs.TAG,
YLog.Configs.PRIORITY,
YLog.Configs.PACKAGE_NAME,
YLog.Configs.USER_ID
)
YukiHookAPI.Configs.isDebug = BuildConfig.DEBUG
YukiHookAPI.Configs.isEnableModulePrefsCache = true
YukiHookAPI.Configs.isEnableModuleAppResourcesCache = true
YukiHookAPI.Configs.isEnableHookModuleStatus = true
YukiHookAPI.InjectYukiHookWithXposed.isUsingXposedModuleStatus = true
YukiHookAPI.Configs.isEnableHookSharedPreferences = false
YukiHookAPI.Configs.isEnableDataChannel = true
YukiHookAPI.Configs.isEnableMemberCache = true
}
override fun onHook() {

View File

@@ -17,6 +17,7 @@ annotation class InjectYukiHookWithXposed(
val sourcePath: String,
val modulePackageName: String,
val entryClassName: String,
val isUsingXposedModuleStatus: Boolean,
val isUsingResourcesHook: Boolean
)
```
@@ -33,6 +34,10 @@ annotation class InjectYukiHookWithXposed(
新增 `isUsingResourcesHook` 参数
`v1.2.0` `modified`
新增 `isUsingXposedModuleStatus` 参数
**Function Illustrate**
> 标识 `YukiHookAPI` 注入 Xposed 入口的类注解。

View File

@@ -13,7 +13,7 @@ You can use the **Chrome Translation Plugin** to translate entire pages for refe
# CurrentClass <span class="symbol">- class</span>
```kotlin:no-line-numbers
class CurrentClass internal constructor(internal val classSet: Class<*>, internal val instance: Any)
class CurrentClass internal constructor(private val classSet: Class<*>, internal val instance: Any)
```
**Change Records**
@@ -133,7 +133,7 @@ inline fun method(initiate: MethodConditions): MethodFinder.Result.Instance
## SuperClass <span class="symbol">- class</span>
```kotlin:no-line-numbers
inner class SuperClass internal constructor(internal val superClassSet: Class<*>)
inner class SuperClass internal constructor(private val superClassSet: Class<*>)
```
**Change Records**

View File

@@ -27,11 +27,11 @@ class GenericClass internal constructor(private val type: ParameterizedType)
## argument <span class="symbol">- method</span>
```kotlin:no-line-numbers
fun argument(index: Int): Class<*>
fun argument(index: Int): Class<*>?
```
```kotlin:no-line-numbers
inline fun <reified T> argument(index: Int): Class<T>
inline fun <reified T> argument(index: Int): Class<T>?
```
**Change Records**
@@ -42,6 +42,16 @@ inline fun <reified T> argument(index: Int): Class<T>
新增泛型返回值 `Class<T>` 方法
`v1.2.0` `modified`
方法的返回值可为 `null`
**Function Illustrate**
> 获得泛型参数数组下标的 `Class` 实例。
> 获得泛型参数数组下标的 `Class` 实例。
::: warning
在运行时局部变量的泛型会被擦除,获取不到时将会返回 **null**
:::

View File

@@ -13,7 +13,7 @@ You can use the **Chrome Translation Plugin** to translate entire pages for refe
# YukiMemberHookCreator <span class="symbol">- class</span>
```kotlin:no-line-numbers
class YukiMemberHookCreator internal constructor(internal val packageParam: PackageParam, internal val hookClass: HookClass)
class YukiMemberHookCreator internal constructor(private val packageParam: PackageParam, private val hookClass: HookClass)
```
**Change Records**
@@ -36,53 +36,37 @@ class YukiMemberHookCreator internal constructor(internal val packageParam: Pack
> `YukiHookAPI` 的 `Member` 核心 Hook 实现类。
## PRIORITY_DEFAULT <span class="symbol">- field</span>
```kotlin:no-line-numbers
val PRIORITY_DEFAULT: Int
```
<h2 class="deprecated">PRIORITY_DEFAULT - field</h2>
**Change Records**
`v1.0.80` `added`
**Function Illustrate**
`v1.2.0` `deprecated`
> 默认 Hook 回调优先级。
请迁移到 `YukiHookPriority`
## PRIORITY_LOWEST <span class="symbol">- field</span>
```kotlin:no-line-numbers
val PRIORITY_LOWEST: Int
```
<h2 class="deprecated">PRIORITY_LOWEST - field</h2>
**Change Records**
`v1.0.80` `added`
**Function Illustrate**
`v1.2.0` `deprecated`
> 延迟回调 Hook 方法结果。
请迁移到 `YukiHookPriority`
## PRIORITY_HIGHEST <span class="symbol">- field</span>
```kotlin:no-line-numbers
val PRIORITY_HIGHEST: Int
```
<h2 class="deprecated">PRIORITY_HIGHEST - field</h2>
**Change Records**
`v1.0.80` `added`
**Function Illustrate**
`v1.2.0` `deprecated`
> 更快回调 Hook 方法结果。
请迁移到 `YukiHookPriority`
## instanceClass <span class="symbol">- field</span>
```kotlin:no-line-numbers
val instanceClass: Class<*>
```
<h2 class="deprecated">instanceClass - field</h2>
**Change Records**
@@ -92,21 +76,11 @@ val instanceClass: Class<*>
~~`thisClass`~~ 更名为 `instanceClass`
**Function Illustrate**
`v1.2.0` `deprecated`
> 得到当前被 Hook 的 `Class`。
不再推荐使用
::: danger
不推荐直接使用,万一得不到 **Class** 对象则会无法处理异常导致崩溃。
:::
## injectMember <span class="symbol">- method</span>
```kotlin:no-line-numbers
inline fun injectMember(priority: Int, tag: String, initiate: MemberHookCreator.() -> Unit): MemberHookCreator.Result
```
<h2 class="deprecated">injectMember - method</h2>
**Change Records**
@@ -118,72 +92,38 @@ inline fun injectMember(priority: Int, tag: String, initiate: MemberHookCreator.
增加 `priority` Hook 优先级
`v1.2.0` `deprecated`
请迁移到另一个 `injectMember`
## injectMember <span class="symbol">- method</span>
```kotlin:no-line-numbers
inline fun injectMember(priority: YukiHookPriority, initiate: MemberHookCreator.LegacyCreator.() -> Unit): MemberHookCreator.Result
```
**Change Records**
`v1.2.0` `added`
**Function Illustrate**
> 注入要 Hook 的 `Method`、`Constructor`。
**Function Example**
你可以注入任意 `Method` 与 `Constructor`,使用 `injectMember` 即可创建一个 `Hook` 对象。
> The following example
```kotlin
injectMember {
// Your code here.
}
```
你还可以自定义 `tag`,方便你在调试的时候能够区分你的 `Hook` 对象。
> The following example
```kotlin
injectMember(tag = "KuriharaYuki") {
// Your code here.
}
```
你还可以自定义 `priority`,以控制当前 Hook 对象并列执行的优先级速度。
> The following example
```kotlin
injectMember(priority = PRIORITY_HIGHEST) {
// Your code here.
}
```
## useDangerousOperation <span class="symbol">- method</span>
```kotlin:no-line-numbers
fun useDangerousOperation(option: String)
```
<h2 class="deprecated">useDangerousOperation - method</h2>
**Change Records**
`v1.1.0` `added`
**Function Illustrate**
`v1.2.0` `deprecated`
> 允许 Hook 过程中的所有危险行为。
请在 `option` 中键入 `Yes do as I say!` 代表你同意允许所有危险行为。
你还需要在整个调用域中声明注解 `CauseProblemsApi` 以消除警告。
若你只需要 Hook `ClassLoader` 的 `loadClass` 方法,请参考 [ClassLoader.onLoadClass](../factory/ReflectionFactory#classloader-onloadclass-ext-method)。
::: danger
若你不知道允许此功能会带来何种后果,请勿使用。
:::
此功能已被弃用
## MemberHookCreator <span class="symbol">- class</span>
```kotlin:no-line-numbers
inner class MemberHookCreator internal constructor(private val priority: Int, internal val tag: String)
inner class MemberHookCreator internal constructor(private val priority: YukiHookPriority, private val hookMode: HookMode)
```
**Change Records**
@@ -204,343 +144,41 @@ inner class MemberHookCreator internal constructor(private val priority: Int, in
修正拼写错误的 **Creater** 命名到 **Creator**
`v1.2.0` `modified`
移除 `tag`
`priority` 类型由 `Int` 变更为 `YukiHookPriority`
增加 `hookMode` Hook 模式
**Function Illustrate**
> Hook 核心功能实现类,查找和处理需要 Hook 的 `Method`、`Constructor`。
<h3 class="deprecated">member - field</h3>
**Change Records**
`v1.0` `first`
`v1.1.0` `removed`
请转移到 `members`
### members <span class="symbol">- method</span>
### before <span class="symbol">- method</span>
```kotlin:no-line-numbers
fun members(vararg member: Member?)
fun before(initiate: HookParam.() -> Unit): HookCallback
```
**Change Records**
`v1.1.0` `added`
**Function Illustrate**
> 手动指定要 Hook 的 `Method`、`Constructor`。
::: warning
不建议使用此方法设置目标需要 Hook 的 **Member** 对象,你可以使用 **method** 或 **constructor** 方法。
:::
**Function Example**
你可以调用 `instanceClass` 来手动查找要 Hook 的 `Method`、`Constructor`。
> The following example
```kotlin
injectMember {
members(instanceClass.getDeclaredMethod("test", StringClass))
beforeHook {}
afterHook {}
}
```
同样地,你也可以传入一组 `Member` 同时进行 Hook。
> The following example
```kotlin
injectMember {
members(
instanceClass.getDeclaredMethod("test1", StringClass),
instanceClass.getDeclaredMethod("test2", StringClass),
instanceClass.getDeclaredMethod("test3", StringClass)
)
beforeHook {}
afterHook {}
}
```
<h3 class="deprecated">allMethods - method</h3>
**Change Records**
`v1.0` `first`
`v1.1.0` `deprecated`
请使用 `method { name = /** name */ }.all()` 来取代它
<h3 class="deprecated">allConstructors - method</h3>
**Change Records**
`v1.0` `first`
`v1.1.0` `deprecated`
请使用 `allMembers(MembersType.CONSTRUCTOR)` 来取代它
### allMembers <span class="symbol">- method</span>
```kotlin:no-line-numbers
fun allMembers(type: MembersType)
```
**Change Records**
`v1.1.0` `added`
**Function Illustrate**
> 查找并 Hook `hookClass` 中的全部 `Method`、`Constructor`。
::: warning
无法准确处理每个 **Member** 的返回值和 **param**,建议使用 **method** or **constructor** 对每个 **Member** 单独 Hook。
:::
### method <span class="symbol">- method</span>
```kotlin:no-line-numbers
inline fun method(initiate: MethodConditions): MethodFinder.Result
```
**Change Records**
`v1.0` `first`
`v1.0.80` `modified`
将方法体进行 inline
**Function Illustrate**
> 查找当前 `Class` 需要 Hook 的 `Method` 。
**Function Example**
你可参考 [MethodFinder](finder/members/MethodFinder) 查看详细用法。
> The following example
```kotlin
injectMember {
method {
name = "test"
param(StringClass)
returnType = UnitType
}
beforeHook {}
afterHook {}
}
```
若想 Hook 当前查找 `method { ... }` 条件的全部结果,你只需要在最后加入 `all` 即可。
> The following example
```kotlin
injectMember {
method {
name = "test"
paramCount(1..5)
}.all()
beforeHook {}
afterHook {}
}
```
此时 `beforeHook` 与 `afterHook` 会在每个查找到的结果中多次回调 Hook 方法体。
::: warning
若没有 **all**,默认只会 Hook 当前条件查找到的数组下标结果第一位。
:::
### constructor <span class="symbol">- method</span>
```kotlin:no-line-numbers
inline fun constructor(initiate: ConstructorConditions): ConstructorFinder.Result
```
**Change Records**
`v1.0` `first`
`v1.0.80` `modified`
将方法体进行 inline
**Function Illustrate**
> 查找当前 `Class` 需要 Hook 的 `Constructor`。
**Function Example**
你可参考 [ConstructorFinder](finder/members/ConstructorFinder) 查看详细用法。
> The following example
```kotlin
injectMember {
constructor { param(StringClass) }
beforeHook {}
afterHook {}
}
```
若想 Hook 当前查找 `constructor { ... }` 条件的全部结果,你只需要在最后加入 `all` 即可。
> The following example
```kotlin
injectMember {
constructor { paramCount(1..5) }.all()
beforeHook {}
afterHook {}
}
```
此时 `beforeHook` 与 `afterHook` 会在每个查找到的结果中多次回调 Hook 方法体。
::: warning
若没有 **all**,默认只会 Hook 当前条件查找到的数组下标结果第一位。
:::
### HookParam.field <span class="symbol">- i-ext-method</span>
```kotlin:no-line-numbers
inline fun HookParam.field(initiate: FieldConditions): FieldFinder.Result
```
**Change Records**
`v1.0` `first`
`v1.0.80` `modified`
将方法体进行 inline
**Function Illustrate**
> 使用当前 `hookClass` 查找并得到 `Field`。
**Function Example**
你可参考 [FieldFinder](finder/members/FieldFinder) 查看详细用法。
> The following example
```kotlin
injectMember {
method {
name = "test"
param(StringClass)
returnType = UnitType
}
afterHook {
// 这里不需要再调用 instanceClass.field 进行查找
field {
name = "isSweet"
type = BooleanType
}.get(instance).setTrue()
}
}
```
### HookParam.method <span class="symbol">- i-ext-method</span>
```kotlin:no-line-numbers
inline fun HookParam.method(initiate: MethodConditions): MethodFinder.Result
```
**Change Records**
`v1.0.2` `first`
`v1.0.80` `modified`
将方法体进行 inline
**Function Illustrate**
> 使用当前 `hookClass` 查找并得到 `Method` 。
### HookParam.constructor <span class="symbol">- i-ext-method</span>
```kotlin:no-line-numbers
inline fun HookParam.constructor(initiate: ConstructorConditions): ConstructorFinder.Result
```
**Change Records**
`v1.0.2` `first`
`v1.0.80` `modified`
将方法体进行 inline
**Function Illustrate**
> 使用当前 `hookClass` 查找并得到 `Constructor`。
### HookParam.injectMember <span class="symbol">- i-ext-method</span>
```kotlin:no-line-numbers
inline fun HookParam.injectMember(priority: Int, tag: String, initiate: MemberHookCreator.() -> Unit): MemberHookCreator.Result
```
**Change Records**
`v1.0.88` `added`
**Function Illustrate**
> 注入要 Hook 的 `Method`、`Constructor` (嵌套 Hook)。
### beforeHook <span class="symbol">- method</span>
```kotlin:no-line-numbers
fun beforeHook(initiate: HookParam.() -> Unit): HookCallback
```
**Change Records**
`v1.0` `first`
`v1.1.0` `modified`
新增 `HookCallback` 返回类型
`v1.2.0` `added`
**Function Illustrate**
> 在 `Member` 执行完成前 Hook。
### afterHook <span class="symbol">- method</span>
### after <span class="symbol">- method</span>
```kotlin:no-line-numbers
fun afterHook(initiate: HookParam.() -> Unit): HookCallback
fun after(initiate: HookParam.() -> Unit): HookCallback
```
**Change Records**
`v1.0` `first`
`v1.1.0` `modified`
新增 `HookCallback` 返回类型
`v1.2.0` `added`
**Function Illustrate**
@@ -670,6 +308,26 @@ fun removeSelf(result: (Boolean) -> Unit)
:::
### LegacyCreator <span class="symbol">- class</span>
```kotlin:no-line-numbers
inner class LegacyCreator internal constructor()
```
**Change Records**
`v1.2.0` `added`
**Function Illustrate**
> 使用 `injectMember` 创建的 Hook 核心功能实现类 (旧版本)。
::: warning
大部分旧版 API 已被迁移至此处,将不再特殊说明其中包含的旧版 API。
:::
### HookCallback <span class="symbol">- class</span>
```kotlin:no-line-numbers
@@ -734,24 +392,6 @@ inline fun result(initiate: Result.() -> Unit): Result
> 创建监听失败事件方法体。
**Function Example**
你可以使用此方法为 `Result` 类创建 `lambda` 方法体。
> The following example
```kotlin
injectMember {
// Your code here.
}.result {
onHooked {}
onAlreadyHooked {}
ignoredConductFailure()
onHookingFailure {}
// ...
}
```
#### by <span class="symbol">- method</span>
```kotlin:no-line-numbers

View File

@@ -291,6 +291,52 @@ injectResource {
}
```
### replaceTo <span class="symbol">- method</span>
```kotlin:no-line-numbers
fun replaceTo(result: (original: Any) -> Any?)
```
**Change Records**
`v1.2.0` `added`
**Function Illustrate**
> 替换指定 Resources 为指定的值。
::: warning
此方法只支持部分类型,例如 **String**、**Boolean**。
此方法不支持在 **HookEntryType.ZYGOTE** 时使用。
:::
### replaceToModuleResource <span class="symbol">- method</span>
```kotlin:no-line-numbers
fun replaceToModuleResource(result: (original: Any) -> Int)
```
**Change Records**
`v1.2.0` `added`
**Function Illustrate**
> 替换为当前 Xposed 模块的 Resources。
你可以直接使用模块的 `R.string.xxx`、`R.mipmap.xxx`、`R.drawable.xxx` 替换 Hook APP 的 Resources。
::: warning
此方法只支持部分类型,例如 **String**、**Boolean**。
此方法不支持在 **HookEntryType.ZYGOTE** 时使用。
:::
### injectAsLayout <span class="symbol">- method</span>
```kotlin:no-line-numbers

View File

@@ -0,0 +1,115 @@
---
pageClass: code-page
---
::: warning
The English translation of this page has not been completed, you are welcome to contribute translations to us.
You can use the **Chrome Translation Plugin** to translate entire pages for reference.
:::
# ExecutorType <span class="symbol">- class</span>
```kotlin:no-line-numbers
enum class ExecutorType
```
**Change Records**
`v1.1.9` `added`
**Function Illustrate**
> Hook Framework 类型定义。
定义了目前已知使用频率较高的 Hook Framework。
后期根据 Hook Framework 特征和使用情况将会继续添加新的类型。
无法识别的 Hook Framework 将被定义为 `UNKNOWN`。
## UNKNOWN <span class="symbol">- enum</span>
```kotlin:no-line-numbers
UNKNOWN
```
**Change Records**
`v1.1.9` `added`
**Function Illustrate**
> 未知类型。
## XPOSED <span class="symbol">- enum</span>
```kotlin:no-line-numbers
XPOSED
```
**Change Records**
`v1.1.9` `added`
**Function Illustrate**
> 原版、第三方 Xposed。
## LSPOSED_LSPATCH <span class="symbol">- enum</span>
```kotlin:no-line-numbers
LSPOSED_LSPATCH
```
**Change Records**
`v1.1.9` `added`
**Function Illustrate**
> LSPosed、LSPatch。
## ED_XPOSED <span class="symbol">- enum</span>
```kotlin:no-line-numbers
ED_XPOSED
```
**Change Records**
`v1.1.9` `added`
**Function Illustrate**
> EdXposed。
## TAICHI_XPOSED <span class="symbol">- enum</span>
```kotlin:no-line-numbers
TAICHI_XPOSED
```
**Change Records**
`v1.1.9` `added`
**Function Illustrate**
> TaiChi (太极)。
## BUG_XPOSED <span class="symbol">- enum</span>
```kotlin:no-line-numbers
BUG_XPOSED
```
**Change Records**
`v1.1.9` `added`
**Function Illustrate**
> BugXposed (应用转生)。

View File

@@ -0,0 +1,71 @@
---
pageClass: code-page
---
::: warning
The English translation of this page has not been completed, you are welcome to contribute translations to us.
You can use the **Chrome Translation Plugin** to translate entire pages for reference.
:::
# YukiHookPriority <span class="symbol">- class</span>
```kotlin:no-line-numbers
enum class YukiHookPriority
```
**Change Records**
`v1.1.5` `added`
`v1.2.0` `modified`
移除 `internal` 对外公开
**Function Illustrate**
> Hook 回调优先级配置类。
## DEFAULT <span class="symbol">- enum</span>
```kotlin:no-line-numbers
DEFAULT
```
**Change Records**
`v1.1.5` `added`
**Function Illustrate**
> 默认 Hook 回调优先级。
## LOWEST <span class="symbol">- enum</span>
```kotlin:no-line-numbers
LOWEST
```
**Change Records**
`v1.1.5` `added`
**Function Illustrate**
> 延迟回调 Hook 方法结果。
## HIGHEST <span class="symbol">- enum</span>
```kotlin:no-line-numbers
HIGHEST
```
**Change Records**
`v1.1.5` `added`
**Function Illustrate**
> 更快回调 Hook 方法结果。

View File

@@ -22,7 +22,7 @@ class NameRules private constructor()
`v1.1.0` `modified`
`NameConditions` 更名为 `NameRules`
~~`NameConditions`~~ 更名为 `NameRules`
作为 lambda 整体判断条件使用

View File

@@ -32,7 +32,7 @@ class DexClassFinder internal constructor(
::: warning
此功能尚在验阶段,性能与稳定性可能仍然存在问题,使用过程遇到问题请向我们报告并帮助我们改进。
此功能尚在验阶段,性能与稳定性可能仍然存在问题,使用过程遇到问题请向我们报告并帮助我们改进。
:::
@@ -441,7 +441,7 @@ fun enclosing(vararg name: String)
## FromPackageRules <span class="symbol">- class</span>
```kotlin:no-line-numbers
inner class FromPackageRules internal constructor(private val packages: ArrayList<ClassRulesData.PackageRulesData>)
inner class FromPackageRules internal constructor(private val packages: MutableList<ClassRulesData.PackageRulesData>)
```
**Change Records**
@@ -625,20 +625,24 @@ fun get(): Class<*>?
### all <span class="symbol">- method</span>
```kotlin:no-line-numbers
fun all(): HashSet<Class<*>>
fun all(): MutableList<Class<*>>
```
**Change Records**
`v1.1.0` `added`
`v1.2.0` `modified`
返回值类型由 `HashSet` 修改为 `MutableList`
**Function Illustrate**
> 得到 `Class` 本身数组。
返回全部查找条件匹配的多个 `Class` 实例。
在查找条件找不到任何结果的时候将返回空的 `HashSet`。
在查找条件找不到任何结果的时候将返回空的 `MutableList`。
若你设置了 `async` 请使用 [waitAll](#waitall-method) 方法。
@@ -685,20 +689,24 @@ fun wait(result: (Class<*>?) -> Unit): Result
### waitAll <span class="symbol">- method</span>
```kotlin:no-line-numbers
fun waitAll(result: (HashSet<Class<*>>) -> Unit): Result
fun waitAll(result: (MutableList<Class<*>>) -> Unit): Result
```
**Change Records**
`v1.1.0` `added`
`v1.2.0` `modified`
`result` 类型由 `HashSet` 修改为 `MutableList`
**Function Illustrate**
> 得到 `Class` 本身数组 (异步)。
回调全部查找条件匹配的多个 `Class` 实例。
在查找条件找不到任何结果的时候将回调空的 `HashSet`。
在查找条件找不到任何结果的时候将回调空的 `MutableList`。
你需要设置 `async` 后此方法才会被回调,否则请使用 [all](#all-method) 方法。

View File

@@ -13,7 +13,7 @@ You can use the **Chrome Translation Plugin** to translate entire pages for refe
# ConstructorRules <span class="symbol">- class</span>
```kotlin:no-line-numbers
class ConstructorRules internal constructor(internal val rulesData: ConstructorRulesData) : BaseRules
class ConstructorRules internal constructor(private val rulesData: ConstructorRulesData) : BaseRules
```
**Change Records**

View File

@@ -13,7 +13,7 @@ You can use the **Chrome Translation Plugin** to translate entire pages for refe
# FieldRules <span class="symbol">- class</span>
```kotlin:no-line-numbers
class FieldRules internal constructor(internal val rulesData: FieldRulesData) : BaseRules
class FieldRules internal constructor(private val rulesData: FieldRulesData) : BaseRules
```
**Change Records**

View File

@@ -13,7 +13,7 @@ You can use the **Chrome Translation Plugin** to translate entire pages for refe
# MemberRules <span class="symbol">- class</span>
```kotlin:no-line-numbers
class MemberRules internal constructor(internal val rulesData: MemberRulesData) : BaseRules
class MemberRules internal constructor(private val rulesData: MemberRulesData) : BaseRules
```
**Change Records**

View File

@@ -13,7 +13,7 @@ You can use the **Chrome Translation Plugin** to translate entire pages for refe
# MethodRules <span class="symbol">- class</span>
```kotlin:no-line-numbers
class MethodRules internal constructor(internal val rulesData: MethodRulesData) : BaseRules
class MethodRules internal constructor(private val rulesData: MethodRulesData) : BaseRules
```
**Change Records**

View File

@@ -13,7 +13,7 @@ You can use the **Chrome Translation Plugin** to translate entire pages for refe
# ConstructorFinder <span class="symbol">- class</span>
```kotlin:no-line-numbers
class ConstructorFinder internal constructor(override val hookInstance: YukiMemberHookCreator.MemberHookCreator?, override val classSet: Class<*>) : MemberBaseFinder
class ConstructorFinder internal constructor(override val classSet: Class<*>) : MemberBaseFinder
```
**Change Records**
@@ -28,6 +28,10 @@ class ConstructorFinder internal constructor(override val hookInstance: YukiMemb
合并到 `MemberBaseFinder`
`v1.1.8` `modified`
移动 `hookInstance` 参数到 `MemberBaseFinder.MemberHookerManager`
**Function Illustrate**
> `Constructor` 查找类。
@@ -287,7 +291,7 @@ inner class Result internal constructor()
#### onFind <span class="symbol">- method</span>
```kotlin:no-line-numbers
fun onFind(initiate: HashSet<Constructor<*>>.() -> Unit)
fun onFind(initiate: MutableList<Constructor<*>>.() -> Unit)
```
**Change Records**
@@ -298,6 +302,10 @@ fun onFind(initiate: HashSet<Constructor<*>>.() -> Unit)
`initiate` 参数 `Constructor` 变为 `HashSet<Constructor>`
`v1.2.0` `modified`
`initiate` 类型由 `HashSet` 修改为 `MutableList`
**Function Illustrate**
> 当在 `RemedyPlan` 中找到结果时。
@@ -328,7 +336,7 @@ inner class Process internal constructor(internal val isNoSuch: Boolean, interna
**Function Illustrate**
> `Constructor` 查找结果处理类,为 `hookInstance` 提供。
> `Constructor` 查找结果处理类,为 `hookManager` 提供。
### result <span class="symbol">- method</span>
@@ -346,7 +354,7 @@ inline fun result(initiate: Process.() -> Unit): Process
**Function Example**
你可以使用 `lambda` 形式创建 `Result` 类。
你可以使用 **lambda** 形式创建 `Result` 类。
> The following example
@@ -372,7 +380,7 @@ fun all(): Process
**Function Illustrate**
> 设置全部查找条件匹配的多个 `Constructor` 实例结果到 `hookInstance`。
> 设置全部查找条件匹配的多个 `Constructor` 实例结果到 `hookManager`。
### remedys <span class="symbol">- method</span>
@@ -463,7 +471,7 @@ inline fun result(initiate: Result.() -> Unit): Result
**Function Example**
你可以使用 `lambda` 形式创建 `Result` 类。
你可以使用 **lambda** 形式创建 `Result` 类。
> The following example
@@ -539,13 +547,17 @@ constructor {
### all <span class="symbol">- method</span>
```kotlin:no-line-numbers
fun all(): ArrayList<Instance>
fun all(): MutableList<Instance>
```
**Change Records**
`v1.1.0` `added`
`v1.2.0` `modified`
返回值类型由 `ArrayList` 修改为 `MutableList`
**Function Illustrate**
> 获得 `Constructor` 实例处理类数组。
@@ -587,20 +599,24 @@ fun give(): Constructor<*>?
### giveAll <span class="symbol">- method</span>
```kotlin:no-line-numbers
fun giveAll(): HashSet<Constructor<*>>
fun giveAll(): MutableList<Constructor<*>>
```
**Change Records**
`v1.1.0` `added`
`v1.2.0` `modified`
返回值类型由 `HashSet` 修改为 `MutableList`
**Function Illustrate**
> 得到 `Constructor` 本身数组。
返回全部查找条件匹配的多个 `Constructor` 实例。
在查找条件找不到任何结果的时候将返回空的 `HashSet`。
在查找条件找不到任何结果的时候将返回空的 `MutableList`。
### wait <span class="symbol">- method</span>
@@ -629,13 +645,17 @@ fun wait(initiate: Instance.() -> Unit)
### waitAll <span class="symbol">- method</span>
```kotlin:no-line-numbers
fun waitAll(initiate: ArrayList<Instance>.() -> Unit)
fun waitAll(initiate: MutableList<Instance>.() -> Unit)
```
**Change Records**
`v1.1.0` `added`
`v1.2.0` `modified`
`initiate` 类型由 `ArrayList` 修改为 `MutableList`
**Function Illustrate**
> 获得 `Constructor` 实例处理类数组,配合 `RemedyPlan` 使用。
@@ -723,7 +743,7 @@ fun ignored(): Result
> 忽略异常并停止打印任何错误日志。
若 `isNotIgnoredHookingFailure` 为 `false` 则自动忽略。
若 `MemberBaseFinder.MemberHookerManager.isNotIgnoredNoSuchMemberFailure` 为 `false` 则自动忽略。
::: warning
@@ -739,7 +759,7 @@ fun ignored(): Result
`v1.1.0` `deprecated`
移到新方法 `ignored()`
移到新方法 `ignored()`
### Instance <span class="symbol">- class</span>
@@ -762,13 +782,17 @@ inner class Instance internal constructor(private val constructor: Constructor<*
#### call <span class="symbol">- method</span>
```kotlin:no-line-numbers
fun call(vararg param: Any?): Any?
fun call(vararg args: Any?): Any?
```
**Change Records**
`v1.0.2` `added`
`v1.1.6` `modified`
修改参数命名 `param` 为 `args`
**Function Illustrate**
> 执行 `Constructor` 创建目标实例,不指定目标实例类型。
@@ -776,13 +800,17 @@ fun call(vararg param: Any?): Any?
#### newInstance <span class="symbol">- method</span>
```kotlin:no-line-numbers
fun <T> newInstance(vararg param: Any?): T?
fun <T> newInstance(vararg args: Any?): T?
```
**Change Records**
`v1.0.2` `added`
`v1.1.6` `modified`
修改参数命名 `param` 为 `args`
**Function Illustrate**
> 执行 `Constructor` 创建目标实例 ,指定 `T` 目标实例类型。

View File

@@ -13,7 +13,7 @@ You can use the **Chrome Translation Plugin** to translate entire pages for refe
# FieldFinder <span class="symbol">- class</span>
```kotlin:no-line-numbers
class FieldFinder internal constructor(override val hookInstance: YukiMemberHookCreator.MemberHookCreator?, override val classSet: Class<*>?) : MemberBaseFinder
class FieldFinder internal constructor(override val classSet: Class<*>?) : MemberBaseFinder
```
**Change Records**
@@ -28,6 +28,10 @@ class FieldFinder internal constructor(override val hookInstance: YukiMemberHook
合并到 `MemberBaseFinder`
`v1.1.8` `modified`
移动 `hookInstance` 参数到 `MemberBaseFinder.MemberHookerManager`
**Function Illustrate**
> `Field` 查找类。
@@ -40,7 +44,7 @@ class FieldFinder internal constructor(override val hookInstance: YukiMemberHook
`v1.0` `first`
`v1.0.2` `removed`
`v1.0.2` `移除`
## name <span class="symbol">- field</span>
@@ -285,22 +289,26 @@ inner class Result internal constructor()
#### onFind <span class="symbol">- method</span>
```kotlin:no-line-numbers
fun onFind(initiate: HashSet<Field>.() -> Unit)
fun onFind(initiate: MutableList<Field>.() -> Unit)
```
**Change Records**
`v1.1.0` `added`
`v1.2.0` `modified`
`initiate` 类型由 `HashSet` 修改为 `MutableList`
**Function Illustrate**
> 当在 `RemedyPlan` 中找到结果时。
**Function Example**
**功能示例**
你可以方便地对重查找的 `Field` 实现 `onFind` 方法。
> The following example
> 示例如下
```kotlin
field {
@@ -313,7 +321,7 @@ field {
## Result <span class="symbol">- class</span>
```kotlin:no-line-numbers
inner class Result internal constructor(internal val isNoSuch: Boolean, private val throwable: Throwable?) : BaseResult
inner class Result internal constructor(internal val isNoSuch: Boolean, internal val throwable: Throwable?) : BaseResult
```
**Change Records**
@@ -346,11 +354,11 @@ inline fun result(initiate: Result.() -> Unit): Result
> 创建监听结果事件方法体。
**Function Example**
**功能示例**
你可以使用 `lambda` 形式创建 `Result` 类。
你可以使用 **lambda** 形式创建 `Result` 类。
> The following example
> 示例如下
```kotlin
field {
@@ -383,11 +391,11 @@ fun get(instance: Any?): Instance
若有多个 `Field` 结果只会返回第一个。
**Function Example**
**功能示例**
你可以轻松地得到 `Field` 的实例以及使用它进行设置实例。
> The following example
> 示例如下
```kotlin
field {
@@ -397,7 +405,7 @@ field {
如果你取到的是静态 `Field`,可以不需要设置实例。
> The following example
> 示例如下
```kotlin
field {
@@ -408,24 +416,28 @@ field {
### all <span class="symbol">- method</span>
```kotlin:no-line-numbers
fun all(instance: Any?): ArrayList<Instance>
fun all(instance: Any?): MutableList<Instance>
```
**Change Records**
`v1.1.0` `added`
`v1.2.0` `modified`
返回值类型由 `ArrayList` 修改为 `MutableList`
**Function Illustrate**
> 获得 `Field` 实例处理类数组。
返回全部查找条件匹配的多个 `Field` 实例结果。
**Function Example**
**功能示例**
你可以通过此方法来获得当前条件结果中匹配的全部 `Field`,其 `Field` 所在实例用法与 `get` 相同。
> The following example
> 示例如下
```kotlin
field {
@@ -456,20 +468,24 @@ fun give(): Field?
### giveAll <span class="symbol">- method</span>
```kotlin:no-line-numbers
fun giveAll(): HashSet<Field>
fun giveAll(): MutableList<Field>
```
**Change Records**
`v1.1.0` `added`
`v1.2.0` `modified`
返回值类型由 `HashSet` 修改为 `MutableList`
**Function Illustrate**
> 得到 `Field` 本身数组。
返回全部查找条件匹配的多个 `Field` 实例。
在查找条件找不到任何结果的时候将返回空的 `HashSet`。
在查找条件找不到任何结果的时候将返回空的 `MutableList`。
### wait <span class="symbol">- method</span>
@@ -498,13 +514,17 @@ fun wait(instance: Any?, initiate: Instance.() -> Unit)
### waitAll <span class="symbol">- method</span>
```kotlin:no-line-numbers
fun waitAll(instance: Any?, initiate: ArrayList<Instance>.() -> Unit)
fun waitAll(instance: Any?, initiate: MutableList<Instance>.() -> Unit)
```
**Change Records**
`v1.1.0` `added`
`v1.2.0` `modified`
`initiate` 类型由 `ArrayList` 修改为 `MutableList`
**Function Illustrate**
> 获得 `Field` 实例处理类数组,配合 `RemedyPlan` 使用。
@@ -533,13 +553,13 @@ inline fun remedys(initiate: RemedyPlan.() -> Unit): Result
> 创建 `Field` 重查找功能。
**Function Example**
**功能示例**
当你遇到一种 `Field` 可能存在不同形式的存在时,可以使用 `RemedyPlan` 重新查找它,而没有必要使用 `onNoSuchField` 捕获异常二次查找 `Field`。
若第一次查找失败了,你还可以在这里继续添加此方法体直到成功为止。
> The following example
> 示例如下
```kotlin
field {
@@ -582,7 +602,7 @@ fun ignored(): Result
> 忽略异常并停止打印任何错误日志。
若 `isNotIgnoredHookingFailure` 为 `false` 则自动忽略。
若 `MemberBaseFinder.MemberHookerManager.isNotIgnoredNoSuchMemberFailure` 为 `false` 则自动忽略。
::: warning
@@ -598,7 +618,7 @@ fun ignored(): Result
`v1.1.0` `deprecated`
移到新方法 `ignored()`
移到新方法 `ignored()`
### Instance <span class="symbol">- class</span>
@@ -626,7 +646,7 @@ inner class Instance internal constructor(private val instance: Any?, private va
`v1.0` `first`
`v1.1.0` `removed`
`v1.1.0` `移除`
请直接使用 `any` 方法得到 `Field` 自身的实例化对象

View File

@@ -13,7 +13,7 @@ You can use the **Chrome Translation Plugin** to translate entire pages for refe
# MethodFinder <span class="symbol">- class</span>
```kotlin:no-line-numbers
class MethodFinder internal constructor(override val hookInstance: YukiMemberHookCreator.MemberHookCreator?, override val classSet: Class<*>) : MemberBaseFinder
class MethodFinder internal constructor(override val classSet: Class<*>) : MemberBaseFinder
```
**Change Records**
@@ -28,6 +28,10 @@ class MethodFinder internal constructor(override val hookInstance: YukiMemberHoo
合并到 `MemberBaseFinder`
`v1.1.8` `modified`
移动 `hookInstance` 参数到 `MemberBaseFinder.MemberHookerManager`
**Function Illustrate**
> `Method` 查找类。
@@ -431,7 +435,7 @@ inner class Result internal constructor()
#### onFind <span class="symbol">- method</span>
```kotlin:no-line-numbers
fun onFind(initiate: HashSet<Method>.() -> Unit)
fun onFind(initiate: MutableList<Method>.() -> Unit)
```
**Change Records**
@@ -442,6 +446,10 @@ fun onFind(initiate: HashSet<Method>.() -> Unit)
`initiate` 参数 `Method` 变为 `HashSet<Method>`
`v1.2.0` `modified`
`initiate` 类型由 `HashSet` 修改为 `MutableList`
**Function Illustrate**
> 当在 `RemedyPlan` 中找到结果时。
@@ -472,7 +480,7 @@ inner class Process internal constructor(internal val isNoSuch: Boolean, interna
**Function Illustrate**
> `Method` 查找结果处理类,为 `hookInstance` 提供。
> `Method` 查找结果处理类,为 `hookManager` 提供。
### result <span class="symbol">- method</span>
@@ -490,7 +498,7 @@ inline fun result(initiate: Process.() -> Unit): Process
**Function Example**
你可以使用 `lambda` 形式创建 `Result` 类。
你可以使用 **lambda** 形式创建 `Result` 类。
> The following example
@@ -516,7 +524,7 @@ fun all(): Process
**Function Illustrate**
> 设置全部查找条件匹配的多个 `Method` 实例结果到 `hookInstance`。
> 设置全部查找条件匹配的多个 `Method` 实例结果到 `hookManager`。
### remedys <span class="symbol">- method</span>
@@ -607,7 +615,7 @@ inline fun result(initiate: Result.() -> Unit): Result
**Function Example**
你可以使用 `lambda` 形式创建 `Result` 类。
你可以使用 **lambda** 形式创建 `Result` 类。
> The following example
@@ -669,13 +677,17 @@ method {
### all <span class="symbol">- method</span>
```kotlin:no-line-numbers
fun all(instance: Any?): ArrayList<Instance>
fun all(instance: Any?): MutableList<Instance>
```
**Change Records**
`v1.1.0` `added`
`v1.2.0` `modified`
返回值类型由 `ArrayList` 修改为 `MutableList`
**Function Illustrate**
> 获得 `Method` 实例处理类数组。
@@ -717,20 +729,24 @@ fun give(): Method?
### giveAll <span class="symbol">- method</span>
```kotlin:no-line-numbers
fun giveAll(): HashSet<Method>
fun giveAll(): MutableList<Method>
```
**Change Records**
`v1.1.0` `added`
`v1.2.0` `modified`
返回值类型由 `HashSet` 修改为 `MutableList`
**Function Illustrate**
> 得到 `Method` 本身数组。
返回全部查找条件匹配的多个 `Method` 实例。
在查找条件找不到任何结果的时候将返回空的 `HashSet`。
在查找条件找不到任何结果的时候将返回空的 `MutableList`。
### wait <span class="symbol">- method</span>
@@ -759,13 +775,17 @@ fun wait(instance: Any?, initiate: Instance.() -> Unit)
### waitAll <span class="symbol">- method</span>
```kotlin:no-line-numbers
fun waitAll(instance: Any?, initiate: ArrayList<Instance>.() -> Unit)
fun waitAll(instance: Any?, initiate: MutableList<Instance>.() -> Unit)
```
**Change Records**
`v1.1.0` `added`
`v1.2.0` `modified`
`initiate` 类型由 `ArrayList` 修改为 `MutableList`
**Function Illustrate**
> 获得 `Method` 实例处理类数组,配合 `RemedyPlan` 使用。
@@ -853,7 +873,7 @@ fun ignored(): Result
> 忽略异常并停止打印任何错误日志。
若 `isNotIgnoredHookingFailure` 为 `false` 则自动忽略。
若 `MemberBaseFinder.MemberHookerManager.isNotIgnoredNoSuchMemberFailure` 为 `false` 则自动忽略。
::: warning
@@ -869,7 +889,7 @@ fun ignored(): Result
`v1.1.0` `deprecated`
移到新方法 `ignored()`
移到新方法 `ignored()`
### Instance <span class="symbol">- class</span>
@@ -914,13 +934,17 @@ fun original(): Instance
#### call <span class="symbol">- method</span>
```kotlin:no-line-numbers
fun call(vararg param: Any?): Any?
fun call(vararg args: Any?): Any?
```
**Change Records**
`v1.0.2` `added`
`v1.1.6` `modified`
修改参数命名 `param` 为 `args`
**Function Illustrate**
> 执行 `Method`,不指定返回值类型。
@@ -928,13 +952,17 @@ fun call(vararg param: Any?): Any?
#### invoke <span class="symbol">- method</span>
```kotlin:no-line-numbers
fun <T> invoke(vararg param: Any?): T?
fun <T> invoke(vararg args: Any?): T?
```
**Change Records**
`v1.0.2` `added`
`v1.1.6` `modified`
修改参数命名 `param` 为 `args`
**Function Illustrate**
> 执行 `Method`,指定 `T` 返回值类型。
@@ -942,13 +970,17 @@ fun <T> invoke(vararg param: Any?): T?
#### byte <span class="symbol">- method</span>
```kotlin:no-line-numbers
fun byte(vararg param: Any?): Byte?
fun byte(vararg args: Any?): Byte?
```
**Change Records**
`v1.0.68` `added`
`v1.1.6` `modified`
修改参数命名 `param` 为 `args`
**Function Illustrate**
> 执行 `Method`,指定 Byte 返回值类型。
@@ -956,7 +988,7 @@ fun byte(vararg param: Any?): Byte?
#### int <span class="symbol">- method</span>
```kotlin:no-line-numbers
fun int(vararg param: Any?): Int
fun int(vararg args: Any?): Int
```
**Change Records**
@@ -967,6 +999,10 @@ fun int(vararg param: Any?): Int
修改 ~~`callInt`~~ 为 `int`
`v1.1.6` `modified`
修改参数命名 `param` 为 `args`
**Function Illustrate**
> 执行 `Method`,指定 Int 返回值类型。
@@ -974,7 +1010,7 @@ fun int(vararg param: Any?): Int
#### long <span class="symbol">- method</span>
```kotlin:no-line-numbers
fun long(vararg param: Any?): Long
fun long(vararg args: Any?): Long
```
**Change Records**
@@ -985,6 +1021,10 @@ fun long(vararg param: Any?): Long
修改 ~~`callLong`~~ 为 `long`
`v1.1.6` `modified`
修改参数命名 `param` 为 `args`
**Function Illustrate**
> 执行 `Method`,指定 Long 返回值类型。
@@ -992,7 +1032,7 @@ fun long(vararg param: Any?): Long
#### short <span class="symbol">- method</span>
```kotlin:no-line-numbers
fun short(vararg param: Any?): Short
fun short(vararg args: Any?): Short
```
**Change Records**
@@ -1003,6 +1043,10 @@ fun short(vararg param: Any?): Short
修改 ~~`callShort`~~ 为 `short`
`v1.1.6` `modified`
修改参数命名 `param` 为 `args`
**Function Illustrate**
> 执行 `Method`,指定 Short 返回值类型。
@@ -1010,7 +1054,7 @@ fun short(vararg param: Any?): Short
#### double <span class="symbol">- method</span>
```kotlin:no-line-numbers
fun double(vararg param: Any?): Double
fun double(vararg args: Any?): Double
```
**Change Records**
@@ -1021,6 +1065,10 @@ fun double(vararg param: Any?): Double
修改 ~~`callDouble`~~ 为 `double`
`v1.1.6` `modified`
修改参数命名 `param` 为 `args`
**Function Illustrate**
> 执行 `Method`,指定 Double 返回值类型。
@@ -1028,7 +1076,7 @@ fun double(vararg param: Any?): Double
#### float <span class="symbol">- method</span>
```kotlin:no-line-numbers
fun float(vararg param: Any?): Float
fun float(vararg args: Any?): Float
```
**Change Records**
@@ -1039,6 +1087,10 @@ fun float(vararg param: Any?): Float
修改 ~~`callFloat`~~ 为 `float`
`v1.1.6` `modified`
修改参数命名 `param` 为 `args`
**Function Illustrate**
> 执行 `Method`,指定 Float 返回值类型。
@@ -1046,7 +1098,7 @@ fun float(vararg param: Any?): Float
#### string <span class="symbol">- method</span>
```kotlin:no-line-numbers
fun string(vararg param: Any?): String
fun string(vararg args: Any?): String
```
**Change Records**
@@ -1057,6 +1109,10 @@ fun string(vararg param: Any?): String
修改 ~~`callString`~~ 为 `string`
`v1.1.6` `modified`
修改参数命名 `param` 为 `args`
**Function Illustrate**
> 执行 `Method`,指定 String 返回值类型。
@@ -1064,13 +1120,17 @@ fun string(vararg param: Any?): String
#### char <span class="symbol">- method</span>
```kotlin:no-line-numbers
fun char(vararg param: Any?): Char
fun char(vararg args: Any?): Char
```
**Change Records**
`v1.0.68` `added`
`v1.1.6` `modified`
修改参数命名 `param` 为 `args`
**Function Illustrate**
> 执行 `Method`,指定 Char 返回值类型。
@@ -1078,7 +1138,7 @@ fun char(vararg param: Any?): Char
#### boolean <span class="symbol">- method</span>
```kotlin:no-line-numbers
fun boolean(vararg param: Any?): Boolean
fun boolean(vararg args: Any?): Boolean
```
**Change Records**
@@ -1089,6 +1149,10 @@ fun boolean(vararg param: Any?): Boolean
修改 ~~`callBoolean`~~ 为 `boolean`
`v1.1.6` `modified`
修改参数命名 `param` 为 `args`
**Function Illustrate**
> 执行 `Method`,指定 Boolean 返回值类型。
@@ -1096,13 +1160,17 @@ fun boolean(vararg param: Any?): Boolean
### array <span class="symbol">- method</span>
```kotlin:no-line-numbers
inline fun <reified T> array(vararg param: Any?): Array<T>
inline fun <reified T> array(vararg args: Any?): Array<T>
```
**Change Records**
`v1.0.68` `added`
`v1.1.6` `modified`
修改参数命名 `param` 为 `args`
**Function Illustrate**
> 执行 `Method`,指定 Array 返回值类型。
@@ -1110,13 +1178,17 @@ inline fun <reified T> array(vararg param: Any?): Array<T>
### list <span class="symbol">- method</span>
```kotlin:no-line-numbers
inline fun <reified T> list(vararg param: Any?): List<T>
inline fun <reified T> list(vararg args: Any?): List<T>
```
**Change Records**
`v1.0.68` `added`
`v1.1.6` `modified`
修改参数命名 `param` 为 `args`
**Function Illustrate**
> 执行 `Method`,指定 List 返回值类型。

View File

@@ -76,6 +76,24 @@ CONSTRUCTOR
> 全部 `Constructor`。
## LazyClass <span class="symbol">- class</span>
```kotlin:no-line-numbers
open class LazyClass<T> internal constructor(
private val instance: Any,
private val initialize: Boolean,
private val loader: ClassLoaderInitializer?
)
```
**Change Records**
`v1.2.0` `added`
**Function Illustrate**
> 懒装载 `Class` 实例。
## ClassLoader.listOfClasses <span class="symbol">- ext-method</span>
```kotlin:no-line-numbers
@@ -118,7 +136,7 @@ inline fun ClassLoader.searchClass(name: String, async: Boolean, initiate: Class
建议启用 **async** 或设置 **name** 参数,**name** 参数将在 Hook APP (宿主) 不同版本中自动进行本地缓存以提升效率。
此功能尚在验阶段,性能与稳定性可能仍然存在问题,使用过程遇到问题请向我们报告并帮助我们改进。
此功能尚在验阶段,性能与稳定性可能仍然存在问题,使用过程遇到问题请向我们报告并帮助我们改进。
:::
@@ -536,10 +554,10 @@ inline fun <reified T> classOf(loader: ClassLoader?, initialize: Boolean): Class
**Function Example**
我们要获取一个 `Class` 在 `Kotlin` 下不通过反射时应该这样做。
我们要获取一个 `Class` 在 Kotlin 下不通过反射时应该这样做。
> The following example
>
```kotlin
DemoClass::class.java
```
@@ -561,6 +579,50 @@ val customClassLoader: ClassLoader? = ... // 假设这个就是你的 ClassLoade
classOf<DemoClass>(customClassLoader)
```
## lazyClass <span class="symbol">- method</span>
```kotlin:no-line-numbers
fun lazyClass(name: String, initialize: Boolean, loader: ClassLoaderInitializer?): LazyClass.NonNull<Any>
```
```kotlin:no-line-numbers
inline fun <reified T> lazyClass(name: String, initialize: Boolean, loader: ClassLoaderInitializer?): LazyClass.NonNull<T>
```
```kotlin:no-line-numbers
fun lazyClass(variousClass: VariousClass, initialize: Boolean, loader: ClassLoaderInitializer?): LazyClass.NonNull<Any>
```
**Change Records**
`v1.2.0` `added`
**Function Illustrate**
> 懒装载 `Class`。
## lazyClassOrNull <span class="symbol">- method</span>
```kotlin:no-line-numbers
fun lazyClassOrNull(name: String, initialize: Boolean, loader: ClassLoaderInitializer?): LazyClass.Nullable<Any>
```
```kotlin:no-line-numbers
inline fun <reified T> lazyClassOrNull(name: String, initialize: Boolean, loader: ClassLoaderInitializer?): LazyClass.Nullable<T>
```
```kotlin:no-line-numbers
fun lazyClassOrNull(variousClass: VariousClass, initialize: Boolean, loader: ClassLoaderInitializer?): LazyClass.Nullable<Any>
```
**Change Records**
`v1.2.0` `added`
**Function Illustrate**
> 懒装载 `Class`。
## String.hasClass <span class="symbol">- ext-method</span>
```kotlin:no-line-numbers
@@ -904,16 +966,16 @@ inline fun <reified T : Any> T.current(ignored: Boolean, initiate: CurrentClass.
`v1.1.0` `deprecated`
移到 `buildOf` 方法
移到 `buildOf` 方法
## Class.buildOf <span class="symbol">- ext-method</span>
```kotlin:no-line-numbers
inline fun Class<*>.buildOf(vararg param: Any?, initiate: ConstructorConditions): Any?
inline fun Class<*>.buildOf(vararg args: Any?, initiate: ConstructorConditions): Any?
```
```kotlin:no-line-numbers
inline fun <T> Class<*>.buildOf(vararg param: Any?, initiate: ConstructorConditions): T?
inline fun <T> Class<*>.buildOf(vararg args: Any?, initiate: ConstructorConditions): T?
```
**Change Records**
@@ -928,6 +990,10 @@ inline fun <T> Class<*>.buildOf(vararg param: Any?, initiate: ConstructorConditi
加入无泛型方法 `buildOf`
`v1.1.6` `modified`
修改参数命名 `param` 为 `args`
**Function Illustrate**
> 通过构造方法创建新实例,指定类型 `T` 或任意类型 `Any`。

View File

@@ -22,7 +22,7 @@ You can use the **Chrome Translation Plugin** to translate entire pages for refe
**Function Illustrate**
> 这是 `YukiHookAPI` 相关 `lambda` 方法的封装类以及部分 API 用法。
> 这是 `YukiHookAPI` 相关 **lambda** 方法的封装类以及部分 API 用法。
## IYukiHookXposedInit.configs <span class="symbol">- ext-method</span>
@@ -64,33 +64,45 @@ fun IYukiHookXposedInit.encase(vararg hooker: YukiBaseHooker)
> 在 `IYukiHookXposedInit` 中调用 `YukiHookAPI`。
## Context.modulePrefs <span class="symbol">- ext-field</span>
```kotlin:no-line-numbers
val Context.modulePrefs: YukiHookModulePrefs
```
<h2 class="deprecated">Context.modulePrefs - ext-field</h2>
**Change Records**
`v1.0` `first`
**Function Illustrate**
`v1.1.9` `deprecated`
> 获取模块的存取对象。
请迁移到 `prefs` 方法
## Context.modulePrefs <span class="symbol">- ext-method</span>
```kotlin:no-line-numbers
fun Context.modulePrefs(name: String): YukiHookModulePrefs
```
<h2 class="deprecated">Context.modulePrefs - ext-method</h2>
**Change Records**
`v1.0` `first`
`v1.1.9` `deprecated`
请迁移到 `prefs` 方法
## Context.prefs <span class="symbol">- ext-method</span>
```kotlin:no-line-numbers
fun Context.prefs(name: String): YukiHookPrefsBridge
```
**Change Records**
`v1.1.9` `added`
**Function Illustrate**
> 获取模块的存取对象,可设置 `name` 为自定义 Sp 存储名称
> 创建 `YukiHookPrefsBridge` 对象
可以同时在模块与 (Xposed) 宿主环境中使用。
如果你想在 (Xposed) 宿主环境将数据存入当前宿主的私有空间,请使用 `YukiHookPrefsBridge.native` 方法。
在未声明任何条件的情况下 (Xposed) 宿主环境默认读取模块中的数据。
## Context.dataChannel <span class="symbol">- ext-method</span>
@@ -104,7 +116,7 @@ fun Context.dataChannel(packageName: String): YukiHookDataChannel.NameSpace
**Function Illustrate**
> 获取模块的数据通讯桥命名空间对象。
> 获取 `YukiHookDataChannel` 对象。
::: danger
@@ -212,7 +224,7 @@ fun Context.applyModuleTheme(theme: Int, configuration: Configuration?): ModuleC
`v1.0.91` `removed`
移到 `YukiHookAPI.Status.isSupportResourcesHook`
移到 `YukiHookAPI.Status.isSupportResourcesHook`
<h2 class="deprecated">isModuleActive - field</h2>
@@ -222,7 +234,7 @@ fun Context.applyModuleTheme(theme: Int, configuration: Configuration?): ModuleC
`v1.0.91` `removed`
移到 `YukiHookAPI.Status.isModuleActive`
移到 `YukiHookAPI.Status.isModuleActive`
<h2 class="deprecated">isXposedModuleActive - field</h2>
@@ -232,7 +244,7 @@ fun Context.applyModuleTheme(theme: Int, configuration: Configuration?): ModuleC
`v1.0.91` `removed`
移到 `YukiHookAPI.Status.isXposedModuleActive`
移到 `YukiHookAPI.Status.isXposedModuleActive`
<h2 class="deprecated">isTaiChiModuleActive - field</h2>
@@ -242,7 +254,7 @@ fun Context.applyModuleTheme(theme: Int, configuration: Configuration?): ModuleC
`v1.0.91` `removed`
移到 `YukiHookAPI.Status.isTaiChiModuleActive`
移到 `YukiHookAPI.Status.isTaiChiModuleActive`
<h1 class="deprecated">YukiHookModuleStatus - class</h1>
@@ -252,4 +264,4 @@ fun Context.applyModuleTheme(theme: Int, configuration: Configuration?): ModuleC
`v1.0.91` `deprecated`
移到 `YukiHookAPI.Status`
移到 `YukiHookAPI.Status`

View File

@@ -10,29 +10,391 @@ You can use the **Chrome Translation Plugin** to translate entire pages for refe
:::
# LoggerFactory <span class="symbol">- kt</span>
**Change Records**
`v1.0` `first`
**Function Illustrate**
> 这是 `YukiHookAPI` 的日志封装类,可实现同时向 `Logcat` 和 (Xposed) 宿主环境打印日志的功能。
## LoggerType <span class="symbol">- class</span>
# YLog <span class="symbol">- object</span>
```kotlin:no-line-numbers
enum class LoggerType
object YLog
```
**Change Records**
`v1.1.0` `added`
`v1.2.0` `added`
**Function Illustrate**
> 需要打印的日志类型
> 全局 Log 管理类
## inMemoryData <span class="symbol">- field</span>
```kotlin:no-line-numbers
val inMemoryData: MutableList<YLogData>
```
**Change Records**
`v1.2.0` `added`
**Function Illustrate**
> 当前全部已记录的日志数据。
::: danger
获取到的日志数据在 Hook APP (宿主) 及模块进程中是相互隔离的。
:::
## contents <span class="symbol">- field</span>
```kotlin:no-line-numbers
val contents: String
```
**Change Records**
`v1.2.0` `added`
**Function Illustrate**
> 获取当前日志文件内容。
如果当前没有已记录的日志会返回空字符串。
::: danger
获取到的日志数据在 Hook APP (宿主) 及模块进程中是相互隔离的。
:::
## contents <span class="symbol">- method</span>
```kotlin:no-line-numbers
fun contents(data: List<YLogData>): String
```
**Change Records**
`v1.2.0` `added`
**Function Illustrate**
> 获取、格式化当前日志文件内容。
如果当前没有已记录的日志 (`data` 为空) 会返回空字符串。
::: danger
获取到的日志数据在 Hook APP (宿主) 及模块进程中是相互隔离的。
:::
## clear <span class="symbol">- method</span>
```kotlin:no-line-numbers
fun clear()
```
**Change Records**
`v1.2.0` `added`
**Function Illustrate**
> 清除全部已记录的日志。
你也可以直接获取 [inMemoryData](#inmemorydata-field) 来清除。
::: danger
获取到的日志数据在 Hook APP (宿主) 及模块进程中是相互隔离的。
:::
## saveToFile <span class="symbol">- method</span>
```kotlin:no-line-numbers
fun saveToFile(fileName: String, data: List<YLogData>)
```
**Change Records**
`v1.2.0` `added`
**Function Illustrate**
> 保存当前日志到文件。
若当前未开启 `Configs.isRecord` 或记录为空则不会进行任何操作。
日志文件会追加到 `fileName` 的文件结尾,若文件不存在会自动创建。
::: danger
文件读写权限取决于当前宿主、模块已获取的权限。
:::
## Configs <span class="symbol">- object</span>
```kotlin:no-line-numbers
object Configs
```
**Change Records**
`v1.2.0` `added`
**Function Illustrate**
> 配置 `YLog`
### TAG <span class="symbol">- field</span>
```kotlin:no-line-numbers
const val TAG: Int
```
**Change Records**
`v1.2.0` `added`
**Function Illustrate**
> 标签。
### PRIORITY <span class="symbol">- field</span>
```kotlin:no-line-numbers
const val PRIORITY: Int
```
**Change Records**
`v1.2.0` `added`
**Function Illustrate**
> 优先级。
### PACKAGE_NAME <span class="symbol">- field</span>
```kotlin:no-line-numbers
const val PACKAGE_NAME: Int
```
**Change Records**
`v1.2.0` `added`
**Function Illustrate**
> 当前宿主的包名。
### USER_ID <span class="symbol">- field</span>
```kotlin:no-line-numbers
const val USER_ID: Int
```
**Change Records**
`v1.2.0` `added`
**Function Illustrate**
> 当前宿主的用户 ID (主用户不显示)。
### tag <span class="symbol">- field</span>
```kotlin:no-line-numbers
var tag: String
```
**Change Records**
`v1.2.0` `added`
**Function Illustrate**
> 这是一个调试日志的全局标识。
默认文案为 `YukiHookAPI`
你可以修改为你自己的文案。
### isEnable <span class="symbol">- field</span>
```kotlin:no-line-numbers
var isEnable: Boolean
```
**Change Records**
`v1.2.0` `added`
**Function Illustrate**
> 是否启用调试日志的输出功能。
关闭后将会停用 `YukiHookAPI` 对全部日志的输出。
但是不影响当你手动调用下面这些方法输出日志。
`debug``info``warn``error`
`isEnable` 关闭后 `YukiHookAPI.Configs.isDebug` 也将同时关闭。
### isRecord <span class="symbol">- field</span>
```kotlin:no-line-numbers
var isRecord: Boolean
```
**Change Records**
`v1.2.0` `added`
**Function Illustrate**
> 是否启用调试日志的记录功能。
开启后将会在内存中记录全部可用的日志和异常堆栈。
需要同时启用 [isEnable](#isenable-field) 才能有效。
::: danger
过量的日志可能会导致宿主运行缓慢或造成频繁 GC。
:::
开启后你可以调用 [YLog.saveToFile](#savetofile-method) 实时保存日志到文件或使用 [YLog.contents](#contents-field) 获取实时日志文件。
### elements <span class="symbol">- method</span>
```kotlin:no-line-numbers
fun elements(vararg item: Int)
```
**Change Records**
`v1.2.0` `added`
**Function Illustrate**
> 自定义调试日志对外显示的元素。
只对日志记录和 (Xposed) 宿主环境的日志生效。
日志元素的排列将按照你在 `item` 中设置的顺序进行显示。
你还可以留空 `item` 以不显示除日志内容外的全部元素。
可用的元素有:`TAG``PRIORITY``PACKAGE_NAME``USER_ID`
**功能示例**
打印的日志样式将按照你设置的排列顺序和元素内容进行。
> 示例如下
```kotlin
elements(TAG, PRIORITY, PACKAGE_NAME, USER_ID)
```
以上内容定义的日志将显示为如下样式。
> 示例如下
```:no-line-numbers
[YukiHookAPI][D][com.demo.test][999]--> This is a log
```
如果我们调整元素顺序以及减少个数,那么结果又会不一样。
> 示例如下
```kotlin
elements(PACKAGE_NAME, USER_ID, PRIORITY)
```
以上内容定义的日志将显示为如下样式。
> 示例如下
```:no-line-numbers
[com.demo.test][999][D]--> This is a log
```
## debug <span class="symbol">- method</span>
```kotlin:no-line-numbers
fun debug(msg: String, e: Throwable?, tag: String, env: EnvType)
```
**Change Records**
`v1.2.0` `added`
**Function Illustrate**
> 打印 Debug 级别 Log。
## info <span class="symbol">- method</span>
```kotlin:no-line-numbers
fun info(msg: String, e: Throwable?, tag: String, env: EnvType)
```
**Change Records**
`v1.2.0` `added`
**Function Illustrate**
> 打印 Info 级别 Log。
## warn <span class="symbol">- method</span>
```kotlin:no-line-numbers
fun warn(msg: String, e: Throwable?, tag: String, env: EnvType)
```
**Change Records**
`v1.2.0` `added`
**Function Illustrate**
> 打印 Warn 级别 Log。
## error <span class="symbol">- method</span>
```kotlin:no-line-numbers
fun error(msg: String, e: Throwable?, tag: String, env: EnvType)
```
**Change Records**
`v1.2.0` `added`
**Function Illustrate**
> 打印 Error 级别 Log。
## EnvType <span class="symbol">- class</span>
```kotlin:no-line-numbers
enum class EnvType
```
**Change Records**
`v1.2.0` `added`
**Function Illustrate**
> 需要打印的日志环境类型。
决定于模块与 (Xposed) 宿主环境使用的打印方式。
@@ -44,22 +406,12 @@ LOGD
**Change Records**
`v1.1.0` `added`
`v1.2.0` `added`
**Function Illustrate**
> 仅使用 `android.util.Log`
<h3 class="deprecated">XPOSEDBRIDGE - enum</h3>
**Change Records**
`v1.1.0` `added`
`v1.1.5` `deprecated`
请转移到 `XPOSED_ENVIRONMENT`
### XPOSED_ENVIRONMENT <span class="symbol">- enum</span>
```kotlin:no-line-numbers
@@ -68,7 +420,7 @@ XPOSED_ENVIRONMENT
**Change Records**
`v1.1.5` `added`
`v1.2.0` `added`
**Function Illustrate**
@@ -88,7 +440,7 @@ SCOPE
**Change Records**
`v1.1.0` `added`
`v1.2.0` `added`
**Function Illustrate**
@@ -106,7 +458,7 @@ BOTH
**Change Records**
`v1.1.0` `added`
`v1.2.0` `added`
**Function Illustrate**
@@ -116,433 +468,12 @@ BOTH
模块环境仅使用 `LOGD`
## YukiLoggerData <span class="symbol">- class</span>
```kotlin:no-line-numbers
data class YukiLoggerData internal constructor(
var timestamp: Long,
var time: String,
var tag: String,
var priority: String,
var packageName: String,
var userId: Int,
var msg: String,
var throwable: Throwable?
) : Serializable
```
**Change Records**
`v1.1.2` `added`
`v1.1.4` `modified`
实现 `Serializable` 接口并标识为 `data class`
**Function Illustrate**
> 调试日志数据实现类。
## YukiHookLogger <span class="symbol">- object</span>
```kotlin:no-line-numbers
object YukiHookLogger
```
**Change Records**
`v1.1.0` `added`
**Function Illustrate**
> 调试日志实现类。
### inMemoryData <span class="symbol">- field</span>
```kotlin:no-line-numbers
val inMemoryData: ArrayList<YukiLoggerData>
```
**Change Records**
`v1.1.2` `added`
`v1.1.4` `modified`
类型由 `HashSet` 修改为 `ArrayList`
**Function Illustrate**
> 当前全部已记录的日志数据。
::: danger
获取到的日志数据在 Hook APP (宿主) 及模块进程中是相互隔离的。
:::
### contents <span class="symbol">- field</span>
```kotlin:no-line-numbers
val contents: String
```
**Change Records**
`v1.1.0` `added`
**Function Illustrate**
> 获取当前日志文件内容。
如果当前没有已记录的日志会返回空字符串。
::: danger
获取到的日志数据在 Hook APP (宿主) 及模块进程中是相互隔离的。
:::
### contents <span class="symbol">- method</span>
```kotlin:no-line-numbers
fun contents(data: ArrayList<YukiLoggerData>): String
```
**Change Records**
`v1.1.5` `added`
**Function Illustrate**
> 获取、格式化当前日志文件内容。
如果当前没有已记录的日志 (`data` 为空) 会返回空字符串。
::: danger
获取到的日志数据在 Hook APP (宿主) 及模块进程中是相互隔离的。
:::
### clear <span class="symbol">- method</span>
```kotlin:no-line-numbers
fun clear()
```
**Change Records**
`v1.1.0` `added`
**Function Illustrate**
> 清除全部已记录的日志。
::: danger
获取到的日志数据在 Hook APP (宿主) 及模块进程中是相互隔离的。
:::
你也可以直接获取 [inMemoryData](#inmemorydata-field) 来清除。
### saveToFile <span class="symbol">- method</span>
```kotlin:no-line-numbers
fun saveToFile(fileName: String, data: ArrayList<YukiLoggerData>)
```
**Change Records**
`v1.1.0` `added`
`v1.1.5` `modified`
新增 `data` 参数
**Function Illustrate**
> 保存当前日志到文件。
若当前未开启 `Configs.isRecord` 或记录为空则不会进行任何操作。
日志文件会追加到 `fileName` 的文件结尾,若文件不存在会自动创建。
::: danger
文件读写权限取决于当前宿主、模块已获取的权限。
:::
### Configs <span class="symbol">- object</span>
```kotlin:no-line-numbers
object Configs
```
**Change Records**
`v1.1.0` `added`
**Function Illustrate**
> 配置 `YukiHookLogger`
#### TAG <span class="symbol">- field</span>
```kotlin:no-line-numbers
const val TAG: Int
```
**Change Records**
`v1.1.0` `added`
**Function Illustrate**
> 标签。
#### PRIORITY <span class="symbol">- field</span>
```kotlin:no-line-numbers
const val PRIORITY: Int
```
**Change Records**
`v1.1.0` `added`
**Function Illustrate**
> 优先级。
#### PACKAGE_NAME <span class="symbol">- field</span>
```kotlin:no-line-numbers
const val PACKAGE_NAME: Int
```
**Change Records**
`v1.1.0` `added`
**Function Illustrate**
> 当前宿主的包名。
#### USER_ID <span class="symbol">- field</span>
```kotlin:no-line-numbers
const val USER_ID: Int
```
**Change Records**
`v1.1.0` `added`
**Function Illustrate**
> 当前宿主的用户 ID (主用户不显示)。
#### isEnable <span class="symbol">- field</span>
```kotlin:no-line-numbers
var isEnable: Boolean
```
**Change Records**
`v1.1.0` `added`
**Function Illustrate**
> 是否启用调试日志的输出功能。
关闭后将会停用 `YukiHookAPI` 对全部日志的输出。
但是不影响当你手动调用下面这些方法输出日志。
`loggerD``loggerI``loggerW``loggerE`
`isEnable` 关闭后 `YukiHookAPI.Configs.isDebug` 也将同时关闭。
#### isRecord <span class="symbol">- field</span>
```kotlin:no-line-numbers
var isRecord: Boolean
```
**Change Records**
`v1.1.0` `added`
**Function Illustrate**
> 是否启用调试日志的记录功能。
开启后将会在内存中记录全部可用的日志和异常堆栈。
需要同时启用 [isEnable](#isenable-field) 才能有效。
::: danger
过量的日志可能会导致宿主运行缓慢或造成频繁 GC。
:::
开启后你可以调用 [YukiHookLogger.saveToFile](#savetofile-method) 实时保存日志到文件或使用 [YukiHookLogger.contents](#contents-field) 获取实时日志文件。
#### tag <span class="symbol">- field</span>
```kotlin:no-line-numbers
var tag: String
```
**Change Records**
`v1.1.0` `added`
**Function Illustrate**
> 这是一个调试日志的全局标识。
默认文案为 `YukiHookAPI`
你可以修改为你自己的文案。
#### elements <span class="symbol">- method</span>
```kotlin:no-line-numbers
fun elements(vararg item: Int)
```
**Change Records**
`v1.1.0` `added`
**Function Illustrate**
> 自定义调试日志对外显示的元素。
只对日志记录和 (Xposed) 宿主环境的日志生效。
日志元素的排列将按照你在 `item` 中设置的顺序进行显示。
你还可以留空 `item` 以不显示除日志内容外的全部元素。
可用的元素有:`TAG``PRIORITY``PACKAGE_NAME``USER_ID`
**Function Example**
打印的日志样式将按照你设置的排列顺序和元素内容进行。
> The following example
```kotlin
elements(TAG, PRIORITY, PACKAGE_NAME, USER_ID)
```
以上内容定义的日志将显示为如下样式。
> The following example
```:no-line-numbers
[YukiHookAPI][D][com.demo.test][999]--> This is a log
```
如果我们调整元素顺序以及减少个数,那么结果又会不一样。
> The following example
```kotlin
elements(PACKAGE_NAME, USER_ID, PRIORITY)
```
以上内容定义的日志将显示为如下样式。
> The following example
```:no-line-numbers
[com.demo.test][999][D]--> This is a log
```
## loggerD <span class="symbol">- method</span>
```kotlin:no-line-numbers
fun loggerD(tag: String, msg: String, type: LoggerType)
```
<h1 class="deprecated">LoggerFactory - kt</h1>
**Change Records**
`v1.0` `first`
`v1.1.0` `modified`
`v1.2.0` `deprecated`
新增 `type` 参数
**Function Illustrate**
> 向 `Logcat` 和 (Xposed) 宿主环境打印日志,级别 `D`
`tag` 的默认参数为 `YukiHookAPI.Configs.debugTag`,你可以进行自定义。
## loggerI <span class="symbol">- method</span>
```kotlin:no-line-numbers
fun loggerI(tag: String, msg: String, type: LoggerType)
```
**Change Records**
`v1.0` `first`
`v1.1.0` `modified`
新增 `type` 参数
**Function Illustrate**
> 向 `Logcat` 和 (Xposed) 宿主环境打印日志,级别 `I`
`tag` 的默认参数为 `YukiHookAPI.Configs.debugTag`,你可以进行自定义。
## loggerW <span class="symbol">- method</span>
```kotlin:no-line-numbers
fun loggerW(tag: String, msg: String, type: LoggerType)
```
**Change Records**
`v1.0` `first`
`v1.1.0` `modified`
新增 `type` 参数
**Function Illustrate**
> 向 `Logcat` 和 (Xposed) 宿主环境打印日志,级别 `W`
`tag` 的默认参数为 `YukiHookAPI.Configs.debugTag`,你可以进行自定义。
## loggerE <span class="symbol">- method</span>
```kotlin:no-line-numbers
fun loggerE(tag: String, msg: String, e: Throwable?, type: LoggerType)
```
**Change Records**
`v1.0` `first`
`v1.1.0` `modified`
新增 `type` 参数
**Function Illustrate**
> 向 `Logcat` 和 (Xposed) 宿主环境打印日志,级别 `E`,可携带 `e` 异常信息,将打印异常堆栈。
`tag` 的默认参数为 `YukiHookAPI.Configs.debugTag`,你可以进行自定义。
请迁移到 `YLog`

View File

@@ -0,0 +1,34 @@
---
pageClass: code-page
---
::: warning
The English translation of this page has not been completed, you are welcome to contribute translations to us.
You can use the **Chrome Translation Plugin** to translate entire pages for reference.
:::
# YLogData <span class="symbol">- class</span>
```kotlin:no-line-numbers
data class YLogData internal constructor(
var timestamp: Long,
var time: String,
var tag: String,
var priority: String,
var packageName: String,
var userId: Int,
var msg: String,
var throwable: Throwable?
) : Serializable
```
**Change Records**
`v1.2.0` `added`
**Function Illustrate**
> 调试日志数据实现类。

View File

@@ -13,7 +13,7 @@ You can use the **Chrome Translation Plugin** to translate entire pages for refe
# HookParam <span class="symbol">- class</span>
```kotlin:no-line-numbers
class HookParam internal constructor(
class HookParam private constructor(
private val creatorInstance: YukiMemberHookCreator,
private var paramId: String,
private var param: YukiHookCallback.Param?
@@ -34,6 +34,10 @@ class HookParam internal constructor(
新增 `paramId` 参数
`v1.2.0` `modified`
不再开放构造方法
**Function Illustrate**
> Hook 方法、构造方法的目标对象实现类。
@@ -94,20 +98,52 @@ val instance: Any
:::
如果你不确定当前实例的对象是否为 `null`,你可以使用 `instanceOrNull`。
## instanceOrNull <span class="symbol">- field</span>
```kotlin:no-line-numbers
val instanceOrNull: Any?
```
**Change Records**
`v1.1.8` `added`
**Function Illustrate**
> 获取当前 Hook 实例的对象。
::: danger
如果你当前 Hook 的对象是一个静态,那么它将不存在实例的对象。
:::
## instanceClass <span class="symbol">- field</span>
```kotlin:no-line-numbers
val instanceClass: Class<*>
val instanceClass: Class<*>?
```
**Change Records**
`v1.0` `first`
`v1.2.0` `modified`
加入可空类型 (空安全)
**Function Illustrate**
> 获取当前 Hook 实例的类对象。
::: danger
如果你当前 Hook 的对象是一个静态,那么它将不存在实例的对象。
:::
## member <span class="symbol">- field</span>
```kotlin:no-line-numbers
@@ -226,7 +262,7 @@ fun Throwable.throwToApp()
使用 `throwable` 获取当前设置的方法调用抛出异常。
仅会在回调方法的 `MemberHookCreator.beforeHook` 或 `MemberHookCreator.afterHook` 中生效。
仅会在回调方法的 `MemberHookCreator.before` 或 `MemberHookCreator.after` 中生效。
::: danger
@@ -243,11 +279,8 @@ Hook 过程中的异常仅会作用于 (Xposed) 宿主环境,目标 Hook APP
> The following example
```kotlin
injectMember {
method {
// ...
}
beforeHook {
hook {
before {
RuntimeException("Test Exception").throwToApp()
}
}
@@ -313,6 +346,24 @@ inline fun <reified T> instance(): T
instance<Activity>().finish()
```
## instanceOrNull <span class="symbol">- method</span>
```kotlin:no-line-numbers
inline fun <reified T> instanceOrNull(): T?
```
**Function Illustrate**
`v1.1.8` `added`
**Function Illustrate**
> 获取当前 Hook 实例的对象 `T`。
**Function Example**
用法请参考 [instance](#instance-method) 方法。
## args <span class="symbol">- method</span>
```kotlin:no-line-numbers
@@ -439,20 +490,19 @@ fun <T> callOriginal(): T?
此方法可以 `invoke` 原始未经 Hook 的 `Member` 对象,取决于原始 `Member` 的参数。
调用自身原始的方法不会再经过当前 `beforeHook`、`afterHook` 以及 `replaceUnit`、`replaceAny`。
调用自身原始的方法不会再经过当前 `before`、`after` 以及 `replaceUnit`、`replaceAny`。
比如我们 Hook 的这个方法被这样调用 `test("test value")`,使用此方法会调用其中的 `"test value"` 作为参数。
> The following example
```kotlin
injectMember {
method {
name = "test"
param(StringClass)
returnType = StringClass
}
afterHook {
method {
name = "test"
param(StringClass)
returnType = StringClass
}.hook {
after {
// <方案1> 不使用泛型,不获取方法执行结果,调用将使用原方法传入的 args 自动传参
callOriginal()
// <方案2> 使用泛型,已知方法执行结果参数类型进行 cast
@@ -490,20 +540,19 @@ fun <T> invokeOriginal(vararg args: Any?): T?
此方法可以 `invoke` 原始未经 Hook 的 `Member` 对象,可自定义需要调用的参数内容。
调用自身原始的方法不会再经过当前 `beforeHook`、`afterHook` 以及 `replaceUnit`、`replaceAny`。
调用自身原始的方法不会再经过当前 `before`、`after` 以及 `replaceUnit`、`replaceAny`。
比如我们 Hook 的这个方法被这样调用 `test("test value")`,使用此方法可自定义其中的 `args` 作为参数。
> The following example
```kotlin
injectMember {
method {
name = "test"
param(StringClass)
returnType = StringClass
}
afterHook {
method {
name = "test"
param(StringClass)
returnType = StringClass
}.hook {
after {
// <方案1> 不使用泛型,不获取方法执行结果
invokeOriginal("test value")
// <方案2> 使用泛型,已知方法执行结果参数类型进行 cast假设返回值为 String失败会返回 null

View File

@@ -10,6 +10,10 @@ You can use the **Chrome Translation Plugin** to translate entire pages for refe
:::
---
pageClass: code-page
---
# PackageParam <span class="symbol">- class</span>
```kotlin:no-line-numbers
@@ -27,7 +31,7 @@ open class PackageParam internal constructor(internal var wrapper: PackageParamW
## appClassLoader <span class="symbol">- field</span>
```kotlin:no-line-numbers
var appClassLoaderClassLoader
var appClassLoaderClassLoader?
```
**Change Records**
@@ -38,6 +42,10 @@ var appClassLoaderClassLoader
可以动态修改此变量的值
`v1.2.0` `modified`
加入可空类型 (空安全)
**Function Illustrate**
> 获取、设置当前 Hook APP 的 `ClassLoader`。
@@ -243,7 +251,7 @@ val moduleAppResources: YukiModuleResources
## prefs <span class="symbol">- field</span>
```kotlin:no-line-numbers
val prefs: YukiHookModulePrefs
val prefs: YukiHookPrefsBridge
```
**Change Records**
@@ -252,7 +260,7 @@ val prefs: YukiHookModulePrefs
**Function Illustrate**
> 获得当前使用的存取数据对象缓存实例
> 创建 `YukiHookPrefsBridge` 对象
::: danger
@@ -263,7 +271,7 @@ val prefs: YukiHookModulePrefs
## prefs <span class="symbol">- method</span>
```kotlin:no-line-numbers
fun prefs(name: String): YukiHookModulePrefs
fun prefs(name: String): YukiHookPrefsBridge
```
**Change Records**
@@ -276,7 +284,7 @@ fun prefs(name: String): YukiHookModulePrefs
**Function Illustrate**
> 获得当前使用的存取数据对象缓存实例
> 创建 `YukiHookPrefsBridge` 对象
你可以通过 `name` 来自定义 Sp 存储的名称。
@@ -298,7 +306,7 @@ val dataChannel: YukiHookDataChannel.NameSpace
**Function Illustrate**
> 获得当前使用的数据通讯桥命名空间对象。
> 获取 `YukiHookDataChannel` 对象。
::: danger
@@ -412,7 +420,7 @@ fun loadApp(isExcludeSelf: Boolean, vararg hooker: YukiBaseHooker)
> 装载并 Hook 指定、全部包名的 APP。
`name` 为 APP 的包名,后方的两个参数一个可作为 `lambda` 方法体使用,一个可以直接装载子 Hooker。
`name` 为 APP 的包名,后方的两个参数一个可作为 **lambda** 方法体使用,一个可以直接装载子 Hooker。
装载并 Hook 指定、全部包名的 APP。
@@ -422,7 +430,7 @@ fun loadApp(isExcludeSelf: Boolean, vararg hooker: YukiBaseHooker)
**Function Example**
你可以使用 `loadApp` 的 `lambda` 方法体形式或直接装载一个 Hooker。
你可以使用 `loadApp` 的 **lambda** 方法体形式或直接装载一个 Hooker。
> The following example
@@ -450,7 +458,7 @@ loadApp(hooker = CustomHooker)
若要在全部可被 Hook 的 APP 中过滤掉模块自身,你只需加入 `isExcludeSelf = true`。
> 示例如下
> The following example
```kotlin
// 使用 lambda
@@ -507,7 +515,7 @@ fun loadZygote(vararg hooker: YukiBaseHooker)
> 装载 APP Zygote 事件。
方法中的两个参数一个可作为 `lambda` 方法体使用,一个可以直接装载子 Hooker。
方法中的两个参数一个可作为 **lambda** 方法体使用,一个可以直接装载子 Hooker。
## loadSystem <span class="symbol">- method</span>
@@ -535,7 +543,7 @@ fun loadSystem(vararg hooker: YukiBaseHooker)
> 装载并 Hook 系统框架。
方法中的两个参数一个可作为 `lambda` 方法体使用,一个可以直接装载子 Hooker。
方法中的两个参数一个可作为 **lambda** 方法体使用,一个可以直接装载子 Hooker。
## withProcess <span class="symbol">- method</span>
@@ -567,7 +575,7 @@ fun withProcess(name: String, vararg hooker: YukiBaseHooker)
> 装载并 Hook APP 的指定进程。
`name` 为 APP 的进程名称,后方的两个参数一个可作为 `lambda` 方法体使用,一个可以直接装载子 Hooker。
`name` 为 APP 的进程名称,后方的两个参数一个可作为 **lambda** 方法体使用,一个可以直接装载子 Hooker。
## loadHooker <span class="symbol">- method</span>
@@ -605,7 +613,7 @@ inline fun searchClass(name: String, async: Boolean, initiate: ClassConditions):
建议启用 **async** 或设置 **name** 参数,**name** 参数将在 Hook APP (宿主) 不同版本中自动进行本地缓存以提升效率。
此功能尚在验阶段,性能与稳定性可能仍然存在问题,使用过程遇到问题请向我们报告并帮助我们改进。
此功能尚在验阶段,性能与稳定性可能仍然存在问题,使用过程遇到问题请向我们报告并帮助我们改进。
:::
@@ -617,7 +625,7 @@ inline fun searchClass(name: String, async: Boolean, initiate: ClassConditions):
`v1.1.0` `deprecated`
移到 `toClass(...)` 方法
移到 `toClass(...)` 方法
<h2 class="deprecated">String.hasClass - i-ext-field</h2>
@@ -627,7 +635,7 @@ inline fun searchClass(name: String, async: Boolean, initiate: ClassConditions):
`v1.1.0` `deprecated`
移到 `hasClass(...)` 方法
移到 `hasClass(...)` 方法
## String+VariousClass.toClass <span class="symbol">- i-ext-method</span>
@@ -768,6 +776,50 @@ fun VariousClass.toClassOrNull(loader: ClassLoader?, initialize: Boolean): Class
用法请参考 [String+VariousClass.toClass](#string-variousclass-toclass-i-ext-method) 方法。
## lazyClass <span class="symbol">- method</span>
```kotlin:no-line-numbers
fun lazyClass(name: String, initialize: Boolean, loader: ClassLoaderInitializer?): LazyClass.NonNull<Any>
```
```kotlin:no-line-numbers
inline fun <reified T> lazyClass(name: String, initialize: Boolean, loader: ClassLoaderInitializer?): LazyClass.NonNull<T>
```
```kotlin:no-line-numbers
fun lazyClass(variousClass: VariousClass, initialize: Boolean, loader: ClassLoaderInitializer?): LazyClass.NonNull<Any>
```
**Change Records**
`v1.2.0` `added`
**Function Illustrate**
> 懒装载 `Class`。
## lazyClassOrNull <span class="symbol">- method</span>
```kotlin:no-line-numbers
fun lazyClassOrNull(name: String, initialize: Boolean, loader: ClassLoaderInitializer?): LazyClass.Nullable<Any>
```
```kotlin:no-line-numbers
inline fun <reified T> lazyClassOrNull(name: String, initialize: Boolean, loader: ClassLoaderInitializer?): LazyClass.Nullable<T>
```
```kotlin:no-line-numbers
fun lazyClassOrNull(variousClass: VariousClass, initialize: Boolean, loader: ClassLoaderInitializer?): LazyClass.Nullable<Any>
```
**Change Records**
`v1.2.0` `added`
**Function Illustrate**
> 懒装载 `Class`。
## String.hasClass <span class="symbol">- i-ext-method</span>
```kotlin:no-line-numbers
@@ -807,15 +859,7 @@ if("com.example.demo.DemoClass".hasClass(customClassLoader)) {
}
```
## findClass <span class="symbol">- method</span>
```kotlin:no-line-numbers
fun findClass(name: String, loader: ClassLoader?): HookClass
```
```kotlin:no-line-numbers
fun findClass(vararg name: String, loader: ClassLoader?): VariousClass
```
<h2 class="deprecated">findClass - method</h2>
**Change Records**
@@ -829,67 +873,11 @@ fun findClass(vararg name: String, loader: ClassLoader?): VariousClass
新增 `loader` 参数
**Function Illustrate**
`v1.2.0` `deprecated`
> 通过完整包名+名称查找需要被 Hook 的 `Class`
请直接使用 `String.toClass(...)` 或 `VariousClass(...)`
::: warning
使用此方法会得到一个 **HookClass** 仅用于 Hook若想查找 **Class** 请使用 [toClass](#string-variousclass-toclass-i-ext-method) 功能。
:::
**Function Example**
你可以使用三种方式查找你需要 Hook 的目标 `Class`。
你可以直接将被查找的 `Class` 完整包名+名称填入 `name` 中。
> The following example
```kotlin
findClass(name = "com.example.demo.DemoClass")
```
若你不确定多个版本的 `Class` 以及不同名称,你可以将多个完整包名+名称填入 `name` 中。
> The following example
```kotlin
findClass("com.example.demo.DemoClass1", "com.example.demo.DemoClass2", "com.example.demo.DemoClass3")
```
你还可以创建一个 `VariousClass`,将 `Class` 的完整包名+名称填入 `VariousClass` 的 `name` 中并填入 `various` 参数中。
> The following example
```kotlin
val variousClass = VariousClass("com.example.demo.DemoClass1", "com.example.demo.DemoClass2", "com.example.demo.DemoClass3")
```
若你当前需要查找的 `Class` 不属于 `appClassLoader`,你可以使用 `loader` 参数指定你要装载的 `ClassLoader`。
> The following example
```kotlin
val outsideLoader: ClassLoader? = ... // 假设这就是你的 ClassLoader
findClass(name = "com.example.demo.OutsideClass", loader = outsideLoader)
```
同样地,在不确定多个版本的 `Class` 以及不同名称时,也可以使用 `loader` 参数指定你要装载的 `ClassLoader`。
> The following example
```kotlin
val outsideLoader: ClassLoader? = ... // 假设这就是你的 ClassLoader
findClass("com.example.demo.OutsideClass1", "com.example.demo.OutsideClass2", "com.example.demo.OutsideClass3", loader = outsideLoader)
```
## String+Class+VariousClass+HookClass.hook <span class="symbol">- i-ext-method</span>
```kotlin:no-line-numbers
inline fun String.hook(initiate: YukiMemberHookCreator.() -> Unit): YukiMemberHookCreator.Result
```
## Class+VariousClass+HookClass.hook <span class="symbol">- i-ext-method</span>
```kotlin:no-line-numbers
inline fun Class<*>.hook(isForceUseAbsolute: Boolean, initiate: YukiMemberHookCreator.() -> Unit): YukiMemberHookCreator.Result
@@ -933,76 +921,86 @@ inline fun HookClass.hook(initiate: YukiMemberHookCreator.() -> Unit): YukiMembe
添加了 `isForceUseAbsolute` 参数到 `Class.hook` 方法
`v1.2.0` `modified`
作废了 ~~`String.hook`~~ 方法
**Function Illustrate**
> 这是一切 Hook 的入口创建方法,Hook 方法、构造方法。
> Hook 方法、构造方法。
**Function Example**
## Member+BaseFinder.BaseResult.hook <span class="symbol">- i-ext-method</span>
如你所见Hook 方法体的创建可使用 4 种方式。
通过字符串类名得到 `HookClass` 实例进行创建。
> The following example
```kotlin
"com.example.demo.DemoClass".hook {
// Your code here.
}
```
通过 `findClass` 得到 `HookClass` 实例进行创建。
> The following example
```kotlin
findClass(name = "com.example.demo.DemoClass").hook {
// Your code here.
}
```kotlin:no-line-numbers
inline fun Member.hook(priority: YukiHookPriority): YukiMemberHookCreator.MemberHookCreator
```
使用 `stub` 或直接拿到 `Class` 实例进行创建。
默认情况下 API 会将 `Class` 实例转换为类名并绑定到 `appClassLoader`,若失败,则会使用原始 `Class` 实例直接进行 Hook。
> The following example
```kotlin
Stub::class.java.hook {
// Your code here.
}
```kotlin:no-line-numbers
inline fun Member.hook(priority: YukiHookPriority, initiate: YukiMemberHookCreator.MemberHookCreator.() -> Unit): YukiMemberHookCreator.MemberHookCreator.Result
```
若当前 `Class` 不在 `appClassLoader` 且自动匹配无法找到该 `Class`,请启用 `isForceUseAbsolute`。
> The following example
```kotlin
YourClass::class.java.hook(isForceUseAbsolute = true) {
// Your code here.
}
```kotlin:no-line-numbers
inline fun BaseFinder.BaseResult.hook(priority: YukiHookPriority): YukiMemberHookCreator.MemberHookCreator
```
使用 `VariousClass` 实例进行创建。
> The following example
```kotlin
VariousClass("com.example.demo.DemoClass1", "com.example.demo.DemoClass2").hook {
// Your code here.
}
```kotlin:no-line-numbers
inline fun BaseFinder.BaseResult.hook(priority: YukiHookPriority, initiate: YukiMemberHookCreator.MemberHookCreator.() -> Unit): YukiMemberHookCreator.MemberHookCreator.Result
```
或者直接使用可变字符串数组进行创建。
**Change Records**
> The following example
`v1.2.0` `added`
```kotlin
findClass("com.example.demo.DemoClass1", "com.example.demo.DemoClass2").hook {
// Your code here.
}
**Function Illustrate**
> 直接 Hook 方法、构造方法。
::: warning
此功能尚在实验阶段,在 **1.x.x** 版本将暂定于此,在 **2.0.0** 版本将完全合并到新 API。
:::
## Array&lt;Member&gt;+List&lt;Member&gt;+BaseFinder.BaseResult.hookAll <span class="symbol">- i-ext-method</span>
```kotlin:no-line-numbers
inline fun Array<Member>.hookAll(priority: YukiHookPriority): YukiMemberHookCreator.MemberHookCreator
```
```kotlin:no-line-numbers
inline fun Array<Member>.hookAll(priority: YukiHookPriority, initiate: YukiMemberHookCreator.MemberHookCreator.() -> Unit): YukiMemberHookCreator.MemberHookCreator.Result
```
```kotlin:no-line-numbers
inline fun List<Member>.hookAll(priority: YukiHookPriority): YukiMemberHookCreator.MemberHookCreator
```
```kotlin:no-line-numbers
inline fun List<Member>.hookAll(priority: YukiHookPriority, initiate: YukiMemberHookCreator.MemberHookCreator.() -> Unit): YukiMemberHookCreator.MemberHookCreator.Result
```
```kotlin:no-line-numbers
inline fun BaseFinder.BaseResult.hookAll(priority: YukiHookPriority): YukiMemberHookCreator.MemberHookCreator
```
```kotlin:no-line-numbers
inline fun BaseFinder.BaseResult.hookAll(priority: YukiHookPriority, initiate: YukiMemberHookCreator.MemberHookCreator.() -> Unit): YukiMemberHookCreator.MemberHookCreator.Result
```
**Change Records**
`v1.2.0` `added`
**Function Illustrate**
> 直接 Hook 方法、构造方法 (批量)。
::: warning
此功能尚在实验阶段,在 **1.x.x** 版本将暂定于此,在 **2.0.0** 版本将完全合并到新 API。
:::
## HookResources.hook <span class="symbol">- i-ext-method</span>
```kotlin:no-line-numbers
@@ -1019,7 +1017,7 @@ inline fun HookResources.hook(initiate: YukiResourcesHookCreator.() -> Unit)
::: danger
请注意你需要确保当前 Hook Framework 支持且 **InjectYukiHookWithXposed.isUsingResourcesHook** 已启用
此功能将不再默认启用,如需启用,请手动设置 **InjectYukiHookWithXposed.isUsingResourcesHook**。
:::
@@ -1041,7 +1039,7 @@ resources().hook {
:::
将 Resources 的 Hook 设置为这样是为了与 `findClass(...).hook` 做到统一,使得调用起来逻辑不会混乱。
将 Resources 的 Hook 设置为这样是为了与 `String.toClass(...).hook` 做到统一,使得调用起来逻辑不会混乱。
## AppLifecycle <span class="symbol">- class</span>
@@ -1151,10 +1149,18 @@ fun onConfigurationChanged(result: (self: Application, config: Configuration) ->
fun registerReceiver(vararg action: String, result: (context: Context, intent: Intent) -> Unit)
```
```kotlin:no-line-numbers
fun registerReceiver(filter: IntentFilter, result: (context: Context, intent: Intent) -> Unit)
```
**Change Records**
`v1.0.88` `added`
`v1.1.8` `modified`
新增直接使用 `IntentFilter` 注册系统广播监听
**Function Illustrate**
> 注册系统广播监听。

View File

@@ -18,6 +18,6 @@ You can use the **Chrome Translation Plugin** to translate entire pages for refe
**Function Illustrate**
> 这是一个预置 Hook 类型的常量类,主要为 `Android` 相关组件的 `Class` 内容,跟随版本更新会逐一进行增加。
> 这是一个预置反射类型的常量类,主要为 `Android` 相关组件的 `Class` 内容,跟随版本更新会逐一进行增加。
详情可 [点击这里](https://github.com/fankes/YukiHookAPI/blob/master/yukihookapi/src/api/kotlin/com/highcapable/yukihookapi/hook/type/android/ComponentTypeFactory.kt) 进行查看。
详情可 [点击这里](https://github.com/HighCapable/YukiHookAPI/blob/master/yukihookapi-core/src/main/java/com/highcapable/yukihookapi/hook/type/android/ComponentTypeFactory.kt) 进行查看。

View File

@@ -18,6 +18,6 @@ You can use the **Chrome Translation Plugin** to translate entire pages for refe
**Function Illustrate**
> 这是一个预置 Hook 类型的常量类,主要为 `Android` 相关 `Graphics` 的 `Class` 内容,跟随版本更新会逐一进行增加。
> 这是一个预置反射类型的常量类,主要为 `Android` 相关 `Graphics` 的 `Class` 内容,跟随版本更新会逐一进行增加。
详情可 [点击这里](https://github.com/fankes/YukiHookAPI/blob/master/yukihookapi/src/api/kotlin/com/highcapable/yukihookapi/hook/type/android/GraphicsTypeFactory.kt) 进行查看。
详情可 [点击这里](https://github.com/HighCapable/YukiHookAPI/blob/master/yukihookapi-core/src/main/java/com/highcapable/yukihookapi/hook/type/android/GraphicsTypeFactory.kt) 进行查看。

View File

@@ -18,6 +18,6 @@ You can use the **Chrome Translation Plugin** to translate entire pages for refe
**Function Illustrate**
> 这是一个预置 Hook 类型的常量类,主要为 `Android` 相关 `Widget` 的 `Class` 内容,跟随版本更新会逐一进行增加。
> 这是一个预置反射类型的常量类,主要为 `Android` 相关 `Widget` 的 `Class` 内容,跟随版本更新会逐一进行增加。
详情可 [点击这里](https://github.com/fankes/YukiHookAPI/blob/master/yukihookapi/src/api/kotlin/com/highcapable/yukihookapi/hook/type/android/ViewTypeFactory.kt) 进行查看。
详情可 [点击这里](https://github.com/HighCapable/YukiHookAPI/blob/master/yukihookapi-core/src/main/java/com/highcapable/yukihookapi/hook/type/android/ViewTypeFactory.kt) 进行查看。

View File

@@ -18,6 +18,6 @@ You can use the **Chrome Translation Plugin** to translate entire pages for refe
**Function Illustrate**
> 这是一个预置 Hook 类型的常量类,主要为 `Java` 相关基本变量类型的 `Class` 内容,跟随版本更新会逐一进行增加。
> 这是一个预置反射类型的常量类,主要为 Java 相关基本变量类型的 `Class` 内容,跟随版本更新会逐一进行增加。
详情可 [点击这里](https://github.com/fankes/YukiHookAPI/blob/master/yukihookapi/src/api/kotlin/com/highcapable/yukihookapi/hook/type/java/VariableTypeFactory.kt) 进行查看。
详情可 [点击这里](https://github.com/HighCapable/YukiHookAPI/blob/master/yukihookapi-core/src/main/java/com/highcapable/yukihookapi/hook/type/java/VariableTypeFactory.kt) 进行查看。

View File

@@ -27,7 +27,7 @@ class YukiResources private constructor(private val baseInstance: XResources) :
## LayoutInflatedParam <span class="symbol">- class</span>
```kotlin:no-line-numbers
class LayoutInflatedParam(internal val baseParam: XC_LayoutInflated.LayoutInflatedParam)
class LayoutInflatedParam(private val baseParam: XC_LayoutInflated.LayoutInflatedParam)
```
**Change Records**

View File

@@ -37,7 +37,7 @@ class YukiHookDataChannel private constructor()
## NameSpace <span class="symbol">- class</span>
```kotlin:no-line-numbers
inner class NameSpace internal constructor(private val context: Context?, private val packageName: String, private val isSecure: Boolean)
inner class NameSpace internal constructor(private val context: Context?, private val packageName: String)
```
**Change Records**
@@ -48,6 +48,10 @@ inner class NameSpace internal constructor(private val context: Context?, privat
新增 `isSecure` 参数
`v1.1.9` `modified`
移除 `isSecure` 参数
**Function Illustrate**
> `YukiHookDataChannel` 命名空间。
@@ -66,23 +70,79 @@ inline fun with(initiate: NameSpace.() -> Unit): NameSpace
> 创建一个调用空间。
### dataMaxByteSize <span class="symbol">- field</span>
```kotlin:no-line-numbers
var dataMaxByteSize: Int
```
**Change Records**
`v1.1.9` `added`
**Function Illustrate**
> `YukiHookDataChannel` 允许发送的最大数据字节大小。
默认为 `500 KB (500 * 1024)`,详情请参考 `receiverDataMaxByteSize` 的注释。
最小不能低于 `100 KB (100 * 1024)`,否则会被重新设置为 `100 KB (100 * 1024)`。
设置后将在全局生效,直到当前进程结束。
超出最大数据字节大小后的数据将被自动分段发送。
::: danger
请谨慎调整此参数,如果超出了系统能够允许的大小会引发 **TransactionTooLargeException** 异常。
:::
### dataMaxByteCompressionFactor <span class="symbol">- field</span>
```kotlin:no-line-numbers
var dataMaxByteCompressionFactor: Int
```
**Change Records**
`v1.1.9` `added`
**Function Illustrate**
> `YukiHookDataChannel` 允许发送的最大数据字节大小倍数 (分段数据)。
默认为 `3`,详情请参考 `receiverDataMaxByteCompressionFactor` 的注释。
最小不能低于 `2`,否则会被重新设置为 `2`。
设置后将在全局生效,直到当前进程结束。
超出最大数据字节大小后的数据将按照此倍数自动划分 `receiverDataMaxByteSize` 的大小。
::: danger
请谨慎调整此参数,如果超出了系统能够允许的大小会引发 **TransactionTooLargeException** 异常。
:::
### allowSendTooLargeData <span class="symbol">- method</span>
```kotlin:no-line-numbers
fun allowSendTooLargeData(): NameSpace
```
**变更记录**
**Change Records**
`v1.1.5` `added`
**功能描述**
**Function Illustrate**
> 解除发送数据的大小限制并禁止开启分段发送功能。
仅会在每次调用时生效,下一次没有调用此方法则此功能将被自动关闭。
你还需要在整个调用域中声明注解 `CauseProblemsApi` 以消除警告。
你还需要在整个调用域中声明注解 `SendTooLargeChannelData` 以消除警告。
::: danger
@@ -199,7 +259,7 @@ fun checkingVersionEquals(priority: ChannelPriority?, result: (Boolean) -> Unit)
### obtainLoggerInMemoryData <span class="symbol">- method</span>
```kotlin:no-line-numbers
fun obtainLoggerInMemoryData(priority: ChannelPriority?, result: (ArrayList<YukiLoggerData>) -> Unit)
fun obtainLoggerInMemoryData(priority: ChannelPriority?, result: (List<YLogData>) -> Unit)
```
**Change Records**
@@ -212,14 +272,14 @@ fun obtainLoggerInMemoryData(priority: ChannelPriority?, result: (ArrayList<Yuki
**Function Illustrate**
> 获取模块与宿主之间的 `ArrayList<YukiLoggerData>` 数据。
> 获取模块与宿主之间的 `List<YLogData>` 数据。
由于模块与宿主处于不同的进程,我们可以使用数据通讯桥访问各自的调试日志数据。
::: danger
模块与宿主必须启用 [YukiHookLogger.Configs.isRecord](../../log/LoggerFactory#isrecord-field) 才能获取到调试日志数据。
模块与宿主必须启用 [YLog.Configs.isRecord](../../log/YLog#isrecord-field) 才能获取到调试日志数据。
由于 Android 限制了数据传输大小的最大值,如果调试日志过多可能会造成 **TransactionTooLargeException** 异常
由于 Android 限制了数据传输大小的最大值,如果调试日志过多将会自动进行分段发送,数据越大速度越慢
:::

View File

@@ -26,4 +26,26 @@ open class ModuleAppActivity : Activity()
继承于此类的 `Activity` 可以同时在宿主与模块中启动。
在 (Xposed) 宿主环境需要在宿主启动时调用 `Context.registerModuleAppActivities` 进行注册。
在 (Xposed) 宿主环境需要在宿主启动时调用 `Context.registerModuleAppActivities` 进行注册。
## proxyClassName <span class="symbol">- field</span>
```kotlin:no-line-numbers
open val proxyClassName: String
```
**Change Records**
`v1.1.10` `added`
**Function Illustrate**
> 设置当前代理的 `Activity` 类名。
留空则使用 `Context.registerModuleAppActivities` 时设置的类名
::: danger
代理的 **Activity** 类名必须存在于宿主的 AndroidMainifest 清单中。
:::

View File

@@ -42,4 +42,26 @@ open val moduleTheme: Int
**Function Illustrate**
> 设置当前代理的 `Activity` 主题。
> 设置当前代理的 `Activity` 主题。
## proxyClassName <span class="symbol">- field</span>
```kotlin:no-line-numbers
open val proxyClassName: String
```
**Change Records**
`v1.1.10` `added`
**Function Illustrate**
> 设置当前代理的 `Activity` 类名。
留空则使用 `Context.registerModuleAppActivities` 时设置的类名
::: danger
代理的 **Activity** 类名必须存在于宿主的 AndroidMainifest 清单中。
:::

View File

@@ -10,25 +10,29 @@ You can use the **Chrome Translation Plugin** to translate entire pages for refe
:::
# YukiHookModulePrefs <span class="symbol">- class</span>
# YukiHookPrefsBridge <span class="symbol">- class</span>
```kotlin:no-line-numbers
class YukiHookModulePrefs private constructor(private var context: Context?)
class YukiHookPrefsBridge private constructor(private var context: Context?)
```
**Change Records**
`v1.0` `first`
`v1.1.9` `modified`
~~`YukiHookModulePrefs`~~ 更名为 `YukiHookPrefsBridge`
**Function Illustrate**
> 实现 Xposed 模块的数据存取,对接 `SharedPreferences``XSharedPreferences`
> `YukiHookAPI` `SharedPreferences``XSharedPreferences` 的扩展存储桥实现
在不同环境智能选择存取使用的对象。
::: danger
此功能为实验性功能,仅在 LSPosed 环境测试通过EdXposed 理论也可以使用但不再推荐。
模块与宿主之前共享数据存储为实验性功能,仅在 LSPosed 环境测试通过EdXposed 理论也可以使用但不再推荐。
:::
@@ -42,13 +46,7 @@ class YukiHookModulePrefs private constructor(private var context: Context?)
太极请参阅 [文件权限/配置/XSharedPreference](https://taichi.cool/zh/doc/for-xposed-dev.html#文件权限-配置-xsharedpreference)。
::: danger
当你在 Xposed 模块中存取数据的时候 **context** 必须不能是空的。
:::
若你正在使用 `PreferenceFragmentCompat`,请迁移到 `ModulePreferenceFragment` 以适配上述功能特性。
对于在模块环境中使用 `PreferenceFragmentCompat``YukiHookAPI` 提供了 `ModulePreferenceFragment` 来实现同样的功能。
**Optional Configuration**
@@ -72,7 +70,7 @@ class YukiHookModulePrefs private constructor(private var context: Context?)
`v1.1.5` `deprecated`
移到 `isPreferencesAvailable`
移到 `isPreferencesAvailable`
<h2 class="deprecated">isRunInNewXShareMode - field</h2>
@@ -82,7 +80,7 @@ class YukiHookModulePrefs private constructor(private var context: Context?)
`v1.1.5` `deprecated`
移到 `isPreferencesAvailable`
移到 `isPreferencesAvailable`
## isPreferencesAvailable <span class="symbol">- field</span>
@@ -96,7 +94,7 @@ val isPreferencesAvailable: Boolean
**Function Illustrate**
> 获取当前 `YukiHookModulePrefs` 的可用状态。
> 获取当前 `YukiHookPrefsBridge` 的可用状态。
在 (Xposed) 宿主环境中返回 `XSharedPreferences` 可用状态 (可读)。
@@ -105,7 +103,7 @@ val isPreferencesAvailable: Boolean
## name <span class="symbol">- method</span>
```kotlin:no-line-numbers
fun name(name: String): YukiHookModulePrefs
fun name(name: String): YukiHookPrefsBridge
```
**Change Records**
@@ -123,7 +121,7 @@ fun name(name: String): YukiHookModulePrefs
> The following example
```kotlin
modulePrefs("custom_name").getString("custom_key")
prefs("custom_name").getString("custom_key")
```
在 (Xposed) 宿主环境 `PackageParam` 中的使用方法。
@@ -134,23 +132,29 @@ modulePrefs("custom_name").getString("custom_key")
prefs("custom_name").getString("custom_key")
```
## direct <span class="symbol">- method</span>
```kotlin:no-line-numbers
fun direct(): YukiHookModulePrefs
```
<h2 class="deprecated">direct - method</h2>
**Change Records**
`v1.0.5` `added`
`v1.1.11` `deprecated`
键值的直接缓存功能已被移除,因为其存在内存溢出 (OOM) 问题
## native <span class="symbol">- method</span>
```kotlin:no-line-numbers
fun native(): YukiHookPrefsBridge
```
**Change Records**
`v1.1.9` `added`
**Function Illustrate**
> 忽略缓存直接读取键值
无论是否开启 `YukiHookAPI.Configs.isEnableModulePrefsCache`
仅在 `XSharedPreferences` 下生效。
> 忽略当前环境直接使用 `Context.getSharedPreferences` 存取数据
## getString <span class="symbol">- method</span>
@@ -236,10 +240,26 @@ fun getFloat(key: String, value: Float): Float
> 获取 `Float` 键值。
## contains <span class="symbol">- method</span>
```kotlin:no-line-numbers
fun contains(key: String): Boolean
```
**Change Records**
`v1.1.9` `added`
**Function Illustrate**
> 判断当前是否包含 `key` 键值的数据。
智能识别对应环境读取键值数据。
## all <span class="symbol">- method</span>
```kotlin:no-line-numbers
fun all(): HashMap<String, Any?>
fun all(): MutableMap<String, Any?>
```
**Change Records**
@@ -258,185 +278,85 @@ fun all(): HashMap<String, Any?>
:::
## remove <span class="symbol">- method</span>
```kotlin:no-line-numbers
fun remove(key: String)
```
<h2 class="deprecated">remove - method</h2>
**Change Records**
`v1.0` `first`
**Function Illustrate**
`v1.1.9` `deprecated`
> 移除全部包含 `key` 的存储数据。
请迁移到 `edit` 方法
::: warning
在 (Xposed) 宿主环境下只读,无法使用。
:::
## remove <span class="symbol">- method</span>
```kotlin:no-line-numbers
inline fun <reified T> remove(prefs: PrefsData<T>)
```
**Change Records**
`v1.0.67` `added`
**Function Illustrate**
> 移除 `PrefsData.key` 的存储数据。
::: warning
在 (Xposed) 宿主环境下只读,无法使用。
:::
## clear <span class="symbol">- method</span>
```kotlin:no-line-numbers
fun clear()
```
<h2 class="deprecated">clear - method</h2>
**Change Records**
`v1.0.77` `added`
**Function Illustrate**
`v1.1.9` `deprecated`
> 移除全部存储数据。
请迁移到 `edit` 方法
::: warning
在 (Xposed) 宿主环境下只读,无法使用。
:::
## putString <span class="symbol">- method</span>
```kotlin:no-line-numbers
fun putString(key: String, value: String)
```
<h2 class="deprecated">putString - method</h2>
**Change Records**
`v1.0` `first`
**Function Illustrate**
`v1.1.9` `deprecated`
> 存储 `String` 键值。
请迁移到 `edit` 方法
::: warning
在 (Xposed) 宿主环境下只读,无法使用。
:::
## putStringSet <span class="symbol">- method</span>
```kotlin:no-line-numbers
fun putStringSet(key: String, value: Set<String>)
```
<h2 class="deprecated">putStringSet - method</h2>
**Change Records**
`v1.0.77` `added`
**Function Illustrate**
`v1.1.9` `deprecated`
> 存储 `Set<String>` 键值。
请迁移到 `edit` 方法
::: warning
在 (Xposed) 宿主环境下只读,无法使用。
:::
## putBoolean <span class="symbol">- method</span>
```kotlin:no-line-numbers
fun putBoolean(key: String, value: Boolean)
```
<h2 class="deprecated">putBoolean - method</h2>
**Change Records**
`v1.0` `first`
**Function Illustrate**
`v1.1.9` `deprecated`
> 存储 `Boolean` 键值。
请迁移到 `edit` 方法
::: warning
在 (Xposed) 宿主环境下只读,无法使用。
:::
## putInt <span class="symbol">- method</span>
```kotlin:no-line-numbers
fun putInt(key: String, value: Int)
```
<h2 class="deprecated">putInt - method</h2>
**Change Records**
`v1.0` `first`
**Function Illustrate**
`v1.1.9` `deprecated`
> 存储 `Int` 键值。
请迁移到 `edit` 方法
::: warning
在 (Xposed) 宿主环境下只读,无法使用。
:::
## putLong <span class="symbol">- method</span>
```kotlin:no-line-numbers
fun putLong(key: String, value: Long)
```
<h2 class="deprecated">putLong - method</h2>
**Change Records**
`v1.0` `first`
**Function Illustrate**
`v1.1.9` `deprecated`
> 存储 `Long` 键值。
请迁移到 `edit` 方法
::: warning
在 (Xposed) 宿主环境下只读,无法使用。
:::
## putFloat <span class="symbol">- method</span>
```kotlin:no-line-numbers
fun putFloat(key: String, value: Float)
```
<h2 class="deprecated">putFloat - method</h2>
**Change Records**
`v1.0` `first`
**Function Illustrate**
`v1.1.9` `deprecated`
> 存储 `Float` 键值。
::: warning
在 (Xposed) 宿主环境下只读,无法使用。
:::
请迁移到 `edit` 方法
## get <span class="symbol">- method</span>
@@ -452,19 +372,31 @@ inline fun <reified T> get(prefs: PrefsData<T>, value: T): T
> 智能获取指定类型的键值。
## put <span class="symbol">- method</span>
```kotlin:no-line-numbers
inline fun <reified T> put(prefs: PrefsData<T>, value: T)
```
<h2 class="deprecated">put - method</h2>
**Change Records**
`v1.0.67` `added`
`v1.1.9` `deprecated`
请迁移到 `edit` 方法
## edit <span class="symbol">- method</span>
```kotlin:no-line-numbers
fun edit(): Editor
```
**Change Records**
`v1.1.9` `added`
**Function Illustrate**
> 智能存储指定类型的键值
> 创建新的 `Editor`
在模块环境中或启用了 `isUsingNativeStorage` 后使用。
::: warning
@@ -472,24 +404,228 @@ inline fun <reified T> put(prefs: PrefsData<T>, value: T)
:::
## clearCache <span class="symbol">- method</span>
## edit <span class="symbol">- method</span>
```kotlin:no-line-numbers
fun clearCache()
fun edit(initiate: Editor.() -> Unit)
```
**Change Records**
`v1.1.9` `added`
**Function Illustrate**
> 创建新的 `Editor`
自动调用 `Editor.apply` 方法。
在模块环境中或启用了 `isUsingNativeStorage` 后使用。
::: warning
在 (Xposed) 宿主环境下只读,无法使用。
:::
<h2 class="deprecated">clearCache - method</h2>
**Change Records**
`v1.0.5` `added`
`v1.1.11` `deprecated`
键值的直接缓存功能已被移除,因为其存在内存溢出 (OOM) 问题
## Editor <span class="symbol">- class</span>
```kotlin:no-line-numbers
inner class Editor internal constructor()
```
**Change Records**
`v1.1.9` `added`
**Function Illustrate**
> 清除 `XSharedPreferences` 中缓存的键值数据
> `YukiHookPrefsBridge` 的存储代理类
无论是否开启 `YukiHookAPI.Configs.isEnableModulePrefsCache`
请使用 `edit` 方法来获取 `Editor`
调用此方法将清除当前存储的全部键值缓存
在模块环境中或启用了 `isUsingNativeStorage` 后使用
下次将从 `XSharedPreferences` 重新读取。
::: warning
在 (Xposed) 宿主环境使用。
在 (Xposed) 宿主环境下只读,无法使用。
:::
### remove <span class="symbol">- method</span>
```kotlin:no-line-numbers
fun remove(key: String): Editor
```
**Change Records**
`v1.1.9` `added`
**Function Illustrate**
> 移除全部包含 `key` 的存储数据。
### remove <span class="symbol">- method</span>
```kotlin:no-line-numbers
inline fun <reified T> remove(prefs: PrefsData<T>): Editor
```
**Change Records**
`v1.1.9` `added`
**Function Illustrate**
> 移除 `PrefsData.key` 的存储数据。
### clear <span class="symbol">- method</span>
```kotlin:no-line-numbers
fun clear(): Editor
```
**Change Records**
`v1.1.9` `added`
**Function Illustrate**
> 移除全部存储数据。
### putString <span class="symbol">- method</span>
```kotlin:no-line-numbers
fun putString(key: String, value: String): Editor
```
**Change Records**
`v1.1.9` `added`
**Function Illustrate**
> 存储 `String` 键值。
### putStringSet <span class="symbol">- method</span>
```kotlin:no-line-numbers
fun putStringSet(key: String, value: Set<String>): Editor
```
**Change Records**
`v1.1.9` `added`
**Function Illustrate**
> 存储 `Set<String>` 键值。
### putBoolean <span class="symbol">- method</span>
```kotlin:no-line-numbers
fun putBoolean(key: String, value: Boolean): Editor
```
**Change Records**
`v1.1.9` `added`
**Function Illustrate**
> 存储 `Boolean` 键值。
### putInt <span class="symbol">- method</span>
```kotlin:no-line-numbers
fun putInt(key: String, value: Int): Editor
```
**Change Records**
`v1.1.9` `added`
**Function Illustrate**
> 存储 `Int` 键值。
### putLong <span class="symbol">- method</span>
```kotlin:no-line-numbers
fun putLong(key: String, value: Long): Editor
```
**Change Records**
`v1.1.9` `added`
**Function Illustrate**
> 存储 `Long` 键值。
### putFloat <span class="symbol">- method</span>
```kotlin:no-line-numbers
fun putFloat(key: String, value: Float): Editor
```
**Change Records**
`v1.1.9` `added`
**Function Illustrate**
> 存储 `Float` 键值。
### put <span class="symbol">- method</span>
```kotlin:no-line-numbers
inline fun <reified T> put(prefs: PrefsData<T>, value: T): Editor
```
**Change Records**
`v1.1.9` `added`
**Function Illustrate**
> 智能存储指定类型的键值。
### commit <span class="symbol">- method</span>
```kotlin:no-line-numbers
fun commit(): Boolean
```
**Change Records**
`v1.1.9` `added`
**Function Illustrate**
> 提交更改 (同步)。
### apply <span class="symbol">- method</span>
```kotlin:no-line-numbers
fun apply()
```
**Change Records**
`v1.1.9` `added`
**Function Illustrate**
> 提交更改 (异步)。

View File

@@ -28,7 +28,7 @@ data class PrefsData<T>(var key: String, var value: T) : Serializable
> 键值对存储构造类。
这个类是对 `YukiHookModulePrefs` 的一个扩展用法。
这个类是对 `YukiHookPrefsBridge` 的一个扩展用法。
**Function Example**
@@ -51,9 +51,9 @@ object DataConst {
```kotlin
// 读取
val data = modulePrefs.get(DataConst.TEST_KV_DATA_1)
val data = prefs().get(DataConst.TEST_KV_DATA_1)
// 写入
modulePrefs.put(DataConst.TEST_KV_DATA_1, "written value")
prefs().edit { put(DataConst.TEST_KV_DATA_1, "written value") }
```
> 宿主示例如下

View File

@@ -24,7 +24,7 @@ interface IYukiHookXposedInit
作废了 ~~`YukiHookXposedInitProxy`~~ 名称但保留接口
移到 `IYukiHookXposedInit` 新名称
移到 `IYukiHookXposedInit` 新名称
**Function Illustrate**
@@ -106,4 +106,4 @@ fun onXposedEvent()
`v1.0.80` `deprecated`
移到 `IYukiHookXposedInit`
移到 `IYukiHookXposedInit`

View File

@@ -4,24 +4,26 @@
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 `build.gradle` of the current Xposed Module project.
- Kotlin Gradle DSL
> Kotlin DSL
```kotlin
android {
androidResources.additionalParameters("--allow-reserved-package-id", "--package-id", "0x64")
androidResources.additionalParameters += listOf("--allow-reserved-package-id", "--package-id", "0x64")
}
```
- Groovy
> Groovy DSL
```groovy
android {
aaptOptions.additionalParameters '--allow-reserved-package-id', '--package-id', '0x64'
androidResources.additionalParameters += ['--allow-reserved-package-id', '--package-id', '0x64']
}
```
::: warning
**aaptOptions.additionalParameters** in previous versions has been deprecated, please refer to the above writing method and keep your **Android Gradle Plugin** to the latest version.
The sample Resource Id value provided is for reference only, **0x7f** cannot be used, the default is **0x64**.
In order to prevent the existence of multiple Xposed Modules in the current Host App, it is recommended to customize your own Resource Id.
@@ -35,12 +37,11 @@ After the Host App is hooked, we can directly inject the `Context` obtained in t
> The following example
```kotlin
injectMember {
method {
name = "onCreate"
param(BundleClass)
}
afterHook {
method {
name = "onCreate"
param(BundleClass)
}.hook {
after {
instance<Activity>().also {
// <Scenario 1> Inject Module App's Resources through Context
it.injectModuleAppResources()
@@ -89,12 +90,11 @@ After the Host App is hooked, we can directly register the `Activity` proxy of t
> The following example
```kotlin
injectMember {
method {
name = "onCreate"
param(BundleClass)
}
afterHook {
method {
name = "onCreate"
param(BundleClass)
}.hook {
after {
instance<Activity>().registerModuleAppActivities()
}
}
@@ -193,6 +193,28 @@ val context: Context = ... // Assume this is your Context
context.startActivity(context, HostTestActivity::class.java)
```
The `proxy` parameter we set in the `registerModuleAppActivities` method above is the default global proxy `Activity`.
If you need to specify a delegated `Activity` to use another Host App's `Activity` as a proxy, you can refer to the following method.
> The following example
```kotlin
class HostTestActivity : ModuleAppActivity() {
// Specify an additional proxy Activity class name
// Which must also exist in the Host App's AndroidManifest
override val proxyClassName get() = "com.demo.test.activity.OtherActivity"
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
// Module App's Resources have been injected automatically
// You can directly use xml to load the layout
setContentView(R. layout. activity_main)
}
}
```
::: tip
For more functions, please refer to the [Context.registerModuleAppActivities](../public/com/highcapable/yukihookapi/hook/factory/YukiHookFactory#context-registermoduleappactivities-ext-method) method.
@@ -214,12 +236,11 @@ At this time, we want to use `MaterialAlertDialogBuilder` to create a dialog in
> The following example
```kotlin
injectMember {
method {
name = "onCreate"
param(BundleClass)
}
afterHook {
method {
name = "onCreate"
param(BundleClass)
}.hook {
after {
// Use applyModuleTheme to create a theme resource in the current Module App
val appCompatContext = instance<Activity>().applyModuleTheme(R.style.Theme_AppCompat)
// Directly use this Context that wraps the Module App's theme to create a dialog
@@ -239,12 +260,11 @@ Which requires at least Android 10 and above system version support and the curr
> The following example
```kotlin
injectMember {
method {
name = "onCreate"
param(BundleClass)
}
afterHook {
method {
name = "onCreate"
param(BundleClass)
}.hook {
after {
// Define the theme resource in the current Module App
var appCompatContext: ModuleContextThemeWrapper
// <Scenario 1> Get the Configuration object directly to set
@@ -274,7 +294,7 @@ This way, we can create dialogs in the Host App very simply using `MaterialAlert
Because some **androidx** dependent libraries or custom themes used by some apps may interfere with the actual style of the current **MaterialAlertDialog**, such as the button style of the dialog.
You can refer to the **Module App Demo** in this case and see [here is the sample code](https://github.com/fankes/YukiHookAPI/tree/master/demo-module/src/main/java/com/highcapable/yukihookapi/demo_module/hook/factory/ComponentCompatFactory.kt) to fix this problem.
You can refer to the **Module App Demo** in this case and see [here is the sample code](https://github.com/HighCapable/YukiHookAPI/tree/master/samples/demo-module/src/main/java/com/highcapable/yukihookapi/demo_module/hook/factory/ComponentCompatFactory.kt) to fix this problem.
**ClassCastException** may occur when some apps are created, please manually specify a new **Configuration** instance to fix.
@@ -303,7 +323,7 @@ The exclusion list determines whether these `Class` need to be loaded by the Mod
```kotlin
// Exclude Class names belonging to the Host App
// They will be loaded by the Host App's ClassLoader
// The following content is for demonstration only
// The following content is for demonstration only
// DO NOT USE IT DIRECTLY, please refer to your actual situation
ModuleClassLoader.excludeHostClasses(
"androidx.core.app.ActivityCompat",
@@ -311,7 +331,7 @@ ModuleClassLoader.excludeHostClasses(
)
// Exclude Class names belonging to the Module App
// They will be loaded by the ClassLoader of the Module App (the current Hook process)
// The following content is for demonstration only
// The following content is for demonstration only
// DO NOT USE IT DIRECTLY, please refer to your actual situation
ModuleClassLoader.excludeModuleClasses(
"com.demo.entry.HookEntry",

View File

@@ -4,26 +4,26 @@
## Normal Logs
You can call `loggerD`, `loggerI`, `loggerW` to print normal logs to the console.
You can call `YLog.debug`, `YLog.info`, `YLog.warn` to print normal logs to the console.
The usage method is as follows.
> The following example
```kotlin
loggerD(msg = "This is a log")
YLog.debug(msg = "This is a log")
```
At this ponit, `YukiHookAPI` will call `android.util.Log` and log function in (Xposed) Host environment to print this log at the same time.
The default `TAG` of the log is the value you set in `YukiHookLogger.Configs.tag`.
The default `TAG` of the log is the value you set in `YLog.Configs.tag`.
You can also customize this value dynamically, but it is not recommended to modify `TAG` easily to prevent logs from being filtered.
> The following example
```kotlin
loggerD(tag = "YukiHookAPI", msg = "This is a log")
YLog.debug(tag = "YukiHookAPI", msg = "This is a log")
```
The printed result is as shown below.
@@ -31,29 +31,29 @@ The printed result is as shown below.
> The following example
```:no-line-numbers
[YukiHookAPI][D][host package name]--> This is a log
[YukiHookAPI][D][host package name] This is a log
```
You can also use `LoggerType` to customize the type of log printing.
You can also use `YLog.EnvType` to customize the type of log printing.
You can choose to use `android.util.Log` or the log function in the (Xposed) Host environment to print logs.
The default type is `LoggerType.BOTH`, which means that both methods are used to print logs.
The default type is `YLog.EnvType.BOTH`, which means that both methods are used to print logs.
For example we only use `android.util.Log` to print logs.
> The following example
```kotlin
loggerD(tag = "YukiHookAPI", msg = "This is a log", type = LoggerType.LOGD)
YLog.debug(tag = "YukiHookAPI", msg = "This is a log", env = YLog.EnvType.LOGD)
```
Or just use `XposedBridge.log` to print the log, this method can only be used in the (Xposed) Host environment.
Or just use the log function that in the (Xposed) Host environment to print the log, this method can only be used in the (Xposed) Host environment.
> The following example
```kotlin
loggerD(tag = "YukiHookAPI", msg = "This is a log", type = LoggerType.XPOSED_ENVIRONMENT)
YLog.debug(tag = "YukiHookAPI", msg = "This is a log", env = YLog.EnvType.XPOSED_ENVIRONMENT)
```
If you want to intelligently distinguish the (Xposed) Host environment from the Module environment, you can write it in the following form.
@@ -61,27 +61,27 @@ If you want to intelligently distinguish the (Xposed) Host environment from the
> The following example
```kotlin
loggerD(tag = "YukiHookAPI", msg = "This is a log", type = LoggerType.SCOPE)
YLog.debug(tag = "YukiHookAPI", msg = "This is a log", env = YLog.EnvType.SCOPE)
```
In this way, the API will intelligently select the specified method type to print this log in different environments.
::: tip
For more functions, please refer to [loggerD](../public/com/highcapable/yukihookapi/hook/log/LoggerFactory#loggerd-method), [loggerI](../public/com/highcapable/yukihookapi/hook/log/LoggerFactory#loggeri-method) and [loggerW](../public/com/highcapable/yukihookapi/hook/log/LoggerFactory#loggerw-method) methods.
For more functions, please refer to [YLog.debug](../public/com/highcapable/yukihookapi/hook/log/YLog#debug-method), [YLog.info](../public/com/highcapable/yukihookapi/hook/log/YLog#info-method) and [YLog.warn](../public/com/highcapable/yukihookapi/hook/log/YLog#warn-method) methods.
:::
## Error Logs
You can call `loggerE` to print `E` level logs to the console.
You can call `YLog.error` to print `E` level logs to the console.
The usage method is as follows.
> The following example
```kotlin
loggerE(msg = "This is an error")
YLog.error(msg = "This is an error")
```
The error log is the highest level, regardless of whether you have filtered only `E` level logs.
@@ -92,7 +92,7 @@ For error-level logging, you can also append an exception stack.
// Assume this is the exception that was thrown
val throwable = Throwable(...)
// Print log
loggerE(msg = "This is an error", e = throwable)
YLog.error(msg = "This is an error", e = throwable)
```
The printed result is as shown below.
@@ -100,7 +100,7 @@ The printed result is as shown below.
> The following example
```:no-line-numbers
[YukiHookAPI][E][host package name]--> This is an error
[YukiHookAPI][E][host package name] This is an error
```
At the same time, the log will help you print the entire exception stack.
@@ -109,25 +109,25 @@ At the same time, the log will help you print the entire exception stack.
```:no-line-numbers
java.lang.Throwable
at com.demo.Test.<init>(...)
at com.demo.Test.doTask(...)
at com.demo.Test.stop(...)
at com.demo.Test.init(...)
at a.a.a(...)
... 3 more
at com.demo.Test.<init>(...)
at com.demo.Test.doTask(...)
at com.demo.Test.stop(...)
at com.demo.Test.init(...)
at a.a.a(...)
... 3 more
```
In the error log, you can also use `LoggerType` to specify the method type currently used to print the log.
In the error log, you can also use `YLog.EnvType` to specify the method type currently used to print the log.
::: tip
For more functions, please refer to the [loggerE](../public/com/highcapable/yukihookapi/hook/log/LoggerFactory#loggere-method) method.
For more functions, please refer to the [YLog.error](../public/com/highcapable/yukihookapi/hook/log/YLog#error-method) method.
:::
## Save Logs and Custom Elements
You can save all currently printed logs directly to a file using the `YukiHookLogger.saveToFile` method.
You can save all currently printed logs directly to a file using the `YLog.saveToFile` method.
> The following example
@@ -135,25 +135,25 @@ You can save all currently printed logs directly to a file using the `YukiHookLo
// Please note
// The saved file path must have read and write permissions
// Otherwise an exception will be thrown
YukiHookLogger.saveToFile("/sdcard/Documents/debug_log.log")
YLog.saveToFile("/sdcard/Documents/debug_log.log")
```
You can also use `YukiHookLogger.contents` to get all the log file contents that have been printed so far.
You can also use `YLog.contents` to get all the log file contents that have been printed so far.
> The following example
```kotlin
// Get the contents of all log files that have been printed so far
val fileContent = YukiHookLogger.contents
val fileContent = YLog.contents
```
If you need an array of real-time log data structures, you can directly get the content of `YukiHookLogger.inMemoryData`.
If you need an array of real-time log data structures, you can directly get the content of `YLog.inMemoryData`.
> The following example
```kotlin
// Get the currently printed real-time log data structure array
YukiHookLogger.inMemoryData.forEach {
YLog.inMemoryData.forEach {
it.timestamp // Get timestamp
it.time // Get UTC time
it.priority // Get priority
@@ -169,19 +169,19 @@ If you want to format or save the obtained custom log data to a file, you only n
```kotlin
// Assume this is the custom log data you get
val data: ArrayList<YukiLoggerData>
val data: List<YLogData>
// Format log data to String
val dataString = YukiHookLogger.contents(data)
val dataString = YLog.contents(data)
// Save log data to file
// Please note
// The saved file path must have read and write permissions
// Otherwise an exception will be thrown
YukiHookLogger.saveToFile("/sdcard/Documents/debug_log.log", data)
YLog.saveToFile("/sdcard/Documents/debug_log.log", data)
```
::: danger
You need to enable **YukiHookLogger.Configs.isRecord** to get the contents of **YukiHookLogger.inMemoryData**.
You need to enable **YLog.Configs.isRecord** to get the contents of **YLog.inMemoryData**.
The obtained log data is isolated from each other in the Host App and the Module App's process.
@@ -193,7 +193,7 @@ If you only want to get log data in real time through Module App or Host App, Pl
:::
You can also use `YukiHookLogger.Configs.elements` to customize the elements that debug logs display externally.
You can also use `YLog.Configs.elements` to customize the elements that debug logs display externally.
This function requires `YukiHookAPI.Configs` to be configured in `onInit` of the Hook entry class.
@@ -211,6 +211,6 @@ override fun onInit() = configs {
::: tip
For more functions, please refer to [YukiHookLogger.inMemoryData](../public/com/highcapable/yukihookapi/hook/log/LoggerFactory#inmemorydata-field), [YukiHookLogger.contents](../public/com/highcapable/yukihookapi/hook/log/LoggerFactory#contents-field), [YukiHookLogger.contents](../public/com/highcapable/yukihookapi/hook/log/LoggerFactory#contents-method), [YukiHookLogger.saveToFile](../public/com/highcapable/yukihookapi/hook/log/LoggerFactory#savetofile-method) methods and [YukiHookLogger.Configs](../public/com/highcapable/yukihookapi/hook/log/LoggerFactory#configs-object).
For more functions, please refer to [YLog.inMemoryData](../public/com/highcapable/yukihookapi/hook/log/YLog#inmemorydata-field), [YLog.contents](../public/com/highcapable/yukihookapi/hook/log/YLog#contents-field), [YLog.contents](../public/com/highcapable/yukihookapi/hook/log/YLog#contents-method), [YLog.saveToFile](../public/com/highcapable/yukihookapi/hook/log/YLog#savetofile-method) methods and [YLog.Configs](../public/com/highcapable/yukihookapi/hook/log/YLog#configs-object).
:::

View File

@@ -2,6 +2,12 @@
> `YukiHookAPI` encapsulates a set of reflection API with near-zero reflection writing for developers, which can almost completely replace the usage of reflection API in Java.
The core part of this functionality has been decoupled into the [YukiReflection](https://github.com/HighCapable/YukiReflection) project, which can be used independently in any Java or Android project.
Now `YukiReflection` is integrated into `YukiHookAPI` as a core dependency.
`YukiHookAPI` adds related extensions for Hook functions on the basis of `YukiReflection`, and there is no need to introduce this dependency to use `YukiHookAPI`.
## Class Extensions
> Here are the extension functions related to the **Class** object itself.
@@ -72,6 +78,54 @@ For more functions, please refer to [classOf](../public/com/highcapable/yukihook
:::
### Lazy Loading
Suppose we want to get a `Class` that cannot be called directly, but we do not need this `Class` immediately.
At this time, you can use `lazyClass` to complete this function.
> The following example
```kotlin
// Lazy loading of this Class
// If you are currently in a PackageParam environment, then you do not need to consider ClassLoader
val instance by lazyClass("com.demo.Test")
// Customize the ClassLoader where the Class is located
val customClassLoader: ClassLoader? = ... // Assume this is your ClassLoader
val instance by lazyClass("com.demo.Test") { customClassLoader }
// Call this Class at the appropriate time
instance.method {
// ...
}
```
If the current `Class` does not exist, using the above method will throw an exception.
If you are not sure whether `Class` exists, you can refer to the following solution.
> The following example
```kotlin
// Lazy loading of this Class
// If you are currently in a PackageParam environment, then you do not need to consider ClassLoader
// If not available, the result will be null but no exception will be thrown
val instance by lazyClassOrNull("com.demo.Test")
// Customize the ClassLoader where the Class is located
val customClassLoader: ClassLoader? = ... // Assume this is your ClassLoader
// If not available, the result will be null but no exception will be thrown
val instance by lazyClassOrNull("com.demo.Test") { customClassLoader }
// Call this Class at the appropriate time
instance?.method {
// ...
}
```
::: tip
For more functions, please refer to [lazyClass](../public/com/highcapable/yukihookapi/hook/factory/ReflectionFactory#lazyclass-method), [lazyClassOrNull](../public/com/highcapable/yukihookapi/hook/factory/ReflectionFactory#lazyclassornull-method), [PackageParam → lazyClass](../public/com/highcapable/yukihookapi/hook/param/PackageParam#lazyclass-method), [PackageParam → lazyClassOrNull](../public/com/highcapable/yukihookapi/hook/param/PackageParam#lazyclassornull-method) methods.
:::
### Existential Judgment
Suppose we want to determine whether a `Class` exists.
@@ -145,6 +199,14 @@ Please note that the more the same type **Class** is matched, the slower the spe
:::
::: danger
After **YukiHookAPI** **2.0.0** released, this function will be deprecated and will no longer be migrated to [YukiReflection](https://github.com/HighCapable/YukiReflection).
We welcome all developers to start using [DexKit](https://github.com/LuckyPray/DexKit), which is a high-performance runtime parsing library for **Dex** implemented in C++, which is more efficient than the Java layer in terms of performance, efficient and excellent, it is still in the development stage, your valuable suggestions are welcome.
:::
#### Get Started
Below is a simple usage example.
@@ -892,7 +954,7 @@ By observing that there are two methods named `b` in `Class`, you can use the fo
```kotlin
// Assume this is an instance of this Class
val instance = Test()
// Call and execute using YukiHook API
// Call and execute using YukiHookAPI
Test::class.java.method {
name = "b"
}.all(instance).forEach { instance ->
@@ -1156,7 +1218,7 @@ instance.current {
name = "stop"
emptyParam()
}.call()
// Note that because current() returns the CurrentClass object itself
// Note that because current() returns the CurrentClass object itself
// It CANNOT BE CALLED like the following
instance.current().current()
```
@@ -1284,15 +1346,12 @@ Here's how the `getString` method in this `Class` Hooks.
> The following example
```kotlin
Test::class.java.hook {
injectMember {
method {
name = "getString"
emptyParam()
returnType = StringClass
}
replaceTo("Hooked")
}
Test::class.java.method {
name = "getString"
emptyParam()
returnType = StringClass
}.hook {
replaceTo("Hooked")
}
```
@@ -1433,34 +1492,8 @@ Test::class.java.method {
}
```
Take the current `Class` as an example, if [Multiple Find](#multiple-find) is used in conjunction with `RemedyPlan` when creating a Hook, you need to change the usage slightly.
> The following example
```kotlin
injectMember {
method {
name = "doTask"
emptyParam()
}.remedys {
method {
name = "doTask"
paramCount(0..1)
}
method {
name = "doTask"
paramCount(1..2)
}
}.all()
beforeHook {}
afterHook {}
}
```
::: tip
When creating a Hook, please refer to [MethodFinder.Process.all](../public/com/highcapable/yukihookapi/hook/core/finder/members/MethodFinder#all-method), [ConstructorFinder.Process.all]( ../public/com/highcapable/yukihookapi/hook/core/finder/members/ConstructorFinder#all-method) methods.
For more functions, please refer to [MethodFinder.RemedyPlan](../public/com/highcapable/yukihookapi/hook/core/finder/members/MethodFinder#remedyplan-class), [ConstructorFinder.RemedyPlan](../public/com/highcapable/yukihookapi/hook/core/finder/members/ConstructorFinder#remedyplan-class), [FieldFinder.RemedyPlan](../public/com/highcapable/yukihookapi/hook/core/finder/members/FieldFinder#remedyplan-class) .
:::
@@ -1564,15 +1597,7 @@ For more functions, please refer to [VariousClass](../public/com/highcapable/yuk
If it is used when creating a Hook, it can be more convenient, and it can also automatically intercept the exception that `Class` cannot be found.
> The following example
```kotlin
findClass("com.demo.ATest", "com.demo.BTest").hook {
// Your code here.
}
```
You can also define this `Class` as a constant type to use.
You can define this `Class` as a constant type to use.
> The following example
@@ -1585,12 +1610,6 @@ ABTestClass.hook {
}
```
::: tip
For more functions, please refer to the [PackageParam.findClass](../public/com/highcapable/yukihookapi/hook/param/PackageParam#findclass-method) method.
:::
### Calling Generics
In the process of reflection, we may encounter generic problems.
@@ -1671,11 +1690,7 @@ For more functions, please refer to [CurrentClass.generic](../public/com/highcap
#### Restrictive Find Conditions
::: danger
In find conditions you can only use **index** function once except **order**.
:::
In find conditions you can <u>**only**</u> use `index` function once except `order`.
> The following example
@@ -1683,7 +1698,7 @@ In find conditions you can only use **index** function once except **order**.
method {
name = "test"
param(BooleanType).index(num = 2)
// Wrong usage, please keep only one index method
// Wrong usage, please keep only one index method
returnType(StringClass).index(num = 1)
}
```
@@ -1702,12 +1717,8 @@ method {
#### Necessary Find Conditions
::: danger
In common method find conditions, <u>**even methods without parameters need to set find conditions**</u>.
:::
Suppose we have the following `Class`.
> The following example
@@ -1763,9 +1774,7 @@ In the past historical versions of the API, it was allowed to match the method w
:::
#### Abbreviated Find Conditions
> In the construction method find conditions, <u>**constructors without parameters do not need to fill in the find conditions**</u>.
In the find conditions for constructors, <u>**even constructors without parameters need to set find conditions**</u>.
Suppose we have the following `Class`.
@@ -1780,7 +1789,7 @@ public class TestFoo {
}
```
We want to get the `public TestFoo()` constructor, which can be written as follows.
To get the `public TestFoo()` constructor, we must write it in the following form.
> The following example
@@ -1788,31 +1797,57 @@ We want to get the `public TestFoo()` constructor, which can be written as follo
TestFoo::class.java.constructor { emptyParam() }
```
The above example can successfully obtain the `public TestFoo()` constructor, but it feels a bit cumbersome.
The above example can successfully obtain the `public TestFoo()` constructor.
Unlike normal methods, since the constructor does not need to consider the `name`, when the constructor has no parameters, we can omit the `emptyParam` parameter.
If you write `constructor()` and miss `emptyParam()`, the result found at this time will be the first one in bytecode order, <u>**may not be parameterless** </u>.
::: tip Compatibility Notes
In past historical versions of the API, if the constructor does not fill in any search parameters, the constructor will not be found directly.
<u>**This is a BUG and has been fixed in the latest version**</u>, please make sure you are using the latest API version.
:::
::: danger API Behavior Changes
In **1.2.0** and later versions, the behavior of **constructor()** is no longer **constructor { emptyParam() }** but **constructor {}**, please pay attention to the behavior change reasonably adjust the find parameters.
:::
#### No Find Conditions
Without setting find conditions, using `field()`, `constructor()`, `method()` will return all members under the current `Class`.
Using `get(...)` or `give()` will only get the first bit in bytecode order.
> The following example
```kotlin
TestFoo::class.java.constructor()
Test::class.java.field().get(...)
Test::class.java.method().give()
```
If you want to get all members, you can use `all(...)` or `giveAll()`
> The following example
```kotlin
Test::class.java.field().all(...)
Test::class.java.method().giveAll()
```
::: tip Compatibility Notes
In the past historical versions of the API, if the constructor does not fill in any find conditions, the constructor will not be found directly.
In past historical versions of the API, failure to set find conditions will throw an exception.
<u>**This is a bug, the latest version has been fixed**</u>, please make sure you are using the latest API version.
This feature was added in **1.2.0** and later versions.
:::
#### Bytecode Type
::: danger
In the bytecode call result, the **cast** method can only specify the type corresponding to the bytecode.
:::
In the bytecode call result, the **cast** method can <u>**only**</u> specify the type corresponding to the bytecode.
For example we want to get a field of type `Boolean` and cast it to `String`.
@@ -1824,7 +1859,7 @@ The following is the wrong way to use it.
field {
name = "test"
type = BooleanType
}.get().string() // Wrong usage, must be cast to the bytecode target type
}.get().string() // Wrong usage, must be cast to the bytecode target type
```
The following is the correct way to use it.
@@ -1851,7 +1886,7 @@ field {
}
```
Expressing the type of `Boolean::class.javaPrimitiveType` in `Kotlin` is very long and inconvenient.
Expressing the type of `Boolean::class.javaPrimitiveType` in Kotlin is very long and inconvenient.
Therefore, `YukiHookAPI` encapsulates common type calls for developers, including Android related types and Java common types and **primitive type keywords**.
@@ -1913,7 +1948,7 @@ At the same time, they all have their own corresponding package types in Java, s
Similarly, arrays also have corresponding wrapper types, which also need to be distinguished from Java **primitive type keywords**.
For example, the encapsulation type of **byte[]** is **ByteArrayType** or **ArrayClass(ByteType)**, and the encapsulation type of **Byte[]** is **ByteArrayClass** or **ArrayClass(ByteClass )**, these types are also <u>**unequal**</u>.
For example, the encapsulation type of **byte[]** is **ByteArrayType** or **ArrayClass(ByteType)**, and the encapsulation type of **Byte[]** is **ByteArrayClass** or **ArrayClass(ByteClass)**, these types are also <u>**unequal**</u>.
:::

View File

@@ -192,7 +192,7 @@ A callback event with the same **key** will only call back the callback event re
The same **key** registers **dataChannel** in the same **Activity** but different **Fragment**, they will still be called back in the current **Activity** at the same time.
In a Module App, you can only use **Context** of **Activity** to register **dataChannel**, you cannot use **dataChannel** in **Application** and **Service**.
In a Module App, you can use **dataChannel** in **Activity**, **Application** and **Service**, when used in places other than **Activity**, each callback event will instant callback, at which point you can use **ChannelPriority** to manage.
If you want to use **dataChannel** in **Fragment**, use **activity?.dataChannel(...)**.
@@ -259,7 +259,7 @@ class FragmentB : BaseFragment() {
## Security Instructions
In the Module environment, you can only receive the communication data sent by <u>**the Host App of the specified package name**</u> and can only send to <u>**the Host App of the specified package name**</u>, except for System Framework.
In the module environment, you can only receive the communication data sent by <u>**the Host App of the specified package name**</u> and can only send to <u>**the Host App of the specified package name**</u>, except for System Framework.
::: danger

View File

@@ -10,7 +10,7 @@ The native `Xposed` provides us with a `XSharedPreferences` for reading the `Sp`
## Use in Activity
> Loading `YukiHookModulePrefs` in `Activity` is described here.
> Loading `YukiHookPrefsBridge` in `Activity` is described here.
Usually we can initialize it in Host App like this.
@@ -29,7 +29,7 @@ When you store data in a Module App, you can use the following methods if you ar
> The following example
```kotlin
modulePrefs.putString("test_name", "saved_value")
prefs().edit { putString("test_name", "saved_value") }
```
When you read data in a Host App, you can use the following methods.
@@ -40,7 +40,7 @@ When you read data in a Host App, you can use the following methods.
val testName = prefs.getString("test_name", "default_value")
```
You don't need to consider the module package name and a series of complicated permission configurations, everything is handled by `YukiHookModulePrefs`.
You don't need to consider the module package name and a series of complicated permission configurations, everything is handled by `YukiHookPrefsBridge`.
To achieve localization of storage, you can specify the name of each `prefs` file.
@@ -50,9 +50,9 @@ This is used in the `Activity` of the Module App.
```kotlin
// Recommended usage
modulePrefs("specify_file_name").putString("test_name", "saved_value")
prefs("specify_file_name").edit { putString("test_name", "saved_value") }
// Can also be used like this
modulePrefs.name("specify_file_name").putString("test_name", "saved_value")
prefs().name("specify_file_name").edit { putString("test_name", "saved_value") }
```
Read like this in Host App.
@@ -68,21 +68,40 @@ val testName = prefs.name("specify_file_name").getString("test_name", "default_v
If your project has a lot of fixed data that needs to be stored and read, it is recommended to use `PrefsData` to create templates.
Through the above example, you can call the `edit` method to store data in batches in the following two ways.
> The following example
```kotlin
// <Scenario 1>
prefs().edit {
putString("test_name_1", "saved_value_1")
putString("test_name_2", "saved_value_2")
putString("test_name_3", "saved_value_3")
}
// <Scenario 2>
prefs(). edit()
.putString("test_name_1", "saved_value_1")
.putString("test_name_2", "saved_value_2")
.putString("test_name_3", "saved_value_3")
.apply()
```
::: tip
For more functions, please refer to [YukiHookModulePrefs](../public/com/highcapable/yukihookapi/hook/xposed/prefs/YukiHookModulePrefs), [PrefsData](../public/com/highcapable/yukihookapi/hook/xposed/prefs/data/PrefsData).
For more functions, please refer to [YukiHookPrefsBridge](../public/com/highcapable/yukihookapi/hook/xposed/prefs/YukiHookPrefsBridge), [PrefsData](../public/com/highcapable/yukihookapi/hook/xposed/prefs/data/PrefsData).
:::
## Use in PreferenceFragment
> Loading `YukiHookModulePrefs` in `PreferenceFragment` is described here.
> Loading `YukiHookPrefsBridge` in `PreferenceFragment` is described here.
If your Module App uses `PreferenceFragmentCompat`, you can now start migrating its extends `ModulePreferenceFragment`.
::: danger
You must extends **ModulePreferenceFragment** to implement the module storage function of **YukiHookModulePrefs**.
You must extends **ModulePreferenceFragment** to implement the module storage function of **YukiHookPrefsBridge**.
:::
@@ -90,4 +109,50 @@ You must extends **ModulePreferenceFragment** to implement the module storage fu
For more functions, please refer to [ModulePreferenceFragment](../public/com/highcapable/yukihookapi/hook/xposed/prefs/ui/ModulePreferenceFragment).
:::
## Use Native Storage
In the Module environment, `YukiHookPrefsBridge` will store data in the Module App's own private directory (or the shared directory provided by Hook Framework) by default.
Using `YukiHookPrefsBridge` in the Host environment will read the data in the Module App's own private directory (or the shared directory provided by Hook Framework) by default.
If you want to store data directly into a Module App or Host App's own private directory, you can use the `native` method.
For example, the directory of the Module App is `.../com.demo.test.module/shared_prefs`, and the directory of the Host App is `.../com.demo.test.host/shared_prefs`.
The following is the usage in `Activity`.
> The following example
```kotlin
// Store private data
prefs().native().edit { putBoolean("isolation_data", true) }
// Read private data
val privateData = prefs().native().getBoolean("isolation_data")
// Store shared data
prefs().edit { putBoolean("public_data", true) }
// Read shared data
val publicData = prefs().getBoolean("public_data")
```
The following is the usage in `PackageParam`.
> The following example
```kotlin
// Store private data
prefs.native().edit { putBoolean("isolation_data", true) }
// Read private data
val privateData = prefs.native().getBoolean("isolation_data")
// Read shared data
val publicData = prefs.getBoolean("public_data")
```
After using the `native` method, no matter in `Activity` or `PackageParam`, the data <u>**will be stored and read in the private directory of the corresponding environment**</u>, and the data will be isolated from each other.
::: tip
For more functions, please refer to [YukiHookPrefsBridge](../public/com/highcapable/yukihookapi/hook/xposed/prefs/YukiHookPrefsBridge).
:::

View File

@@ -12,7 +12,7 @@
fun configs(initiate: Configs.() -> Unit)
```
The `configs` method implements a `lambda` method body on the `Configs` class, which you can easily call for configuration.
The `configs` method implements a **lambda** method body on the `Configs` class, which you can easily call for configuration.
::: tip
@@ -51,9 +51,12 @@ The `encase` method can be created in the `onHook` method using two schemes.
```kotlin
YukiHookAPI.encase {
loadApp(name = "com.example.demo") {
findClass(name = "$packageName.DemoClass").hook {
// Your code here.
}
"$packageName.DemoClass".toClass()
.method {
// Your code here.
}.hook {
// Your code here.
}
}
}
```
@@ -63,9 +66,12 @@ YukiHookAPI.encase {
```kotlin
encase {
loadApp(name = "com.example.demo") {
findClass(name = "$packageName.DemoClass").hook {
// Your code here.
}
"$packageName.DemoClass".toClass()
.method {
// Your code here.
}.hook {
// Your code here.
}
}
}
```
@@ -105,7 +111,7 @@ object CustomHooker : YukiBaseHooker() {
}
```
Child Hooker **recommended** singleton `object` creation, you can also use `class` but not recommended.
Child Hooker **recommended** to use singleton `object` to create, you can also use `class` but it is generally not recommended.
::: warning
@@ -120,14 +126,20 @@ object CustomHooker : YukiBaseHooker() {
override fun onHook() {
loadApp(name = "com.example.demo1") {
findClass(name = "$packageName.DemoClass").hook {
// Your code here.
}
"$packageName.DemoClass".toClass()
.method {
// Your code here.
}.hook {
// Your code here.
}
}
loadApp(name = "com.example.demo2") {
findClass(name = "$packageName.CustomClass").hook {
// Your code here.
}
"$packageName.CustomClass".toClass()
.method {
// Your code here.
}.hook {
// Your code here.
}
}
}
}
@@ -138,7 +150,7 @@ As a child hooker, you can also call the `loadApp` method externally, and then d
> The following example
```kotlin
class HookEntry : IYukiHookXposedInit {
object HookEntry : IYukiHookXposedInit {
override fun onHook() = encase {
loadApp(name = "com.example.demo", ChildCustomHooker)
@@ -148,9 +160,12 @@ class HookEntry : IYukiHookXposedInit {
object ChildCustomHooker : YukiBaseHooker() {
override fun onHook() {
findClass(name = "$packageName.DemoClass").hook {
// Your code here.
}
"$packageName.DemoClass".toClass()
.method {
// Your code here.
}.hook {
// Your code here.
}
}
}
```
@@ -163,21 +178,24 @@ You can use the `loadHooker` method to load another Hooker in multiple layers in
object FirstHooker : YukiBaseHooker() {
override fun onHook() {
findClass(name = "$packageName.DemoClass").hook {
// Your code here.
}
"$packageName.DemoClass".toClass()
.method {
// Your code here.
}.hook {
// Your code here.
}
loadHooker(SecondHooker)
loadHooker(ThirdHooker)
}
}
```
Once all Hookers are set up, you can load your Hooker in the `onHook` method of your `HookEntryClass`.
Once all Hookers are set up, you can load your Hooker in the `onHook` method of your Hook entry class.
> The following example
```kotlin
class HookEntry : IYukiHookXposedInit {
object HookEntry : IYukiHookXposedInit {
override fun onHook() =
YukiHookAPI.encase(FirstHooker, SecondHooker, ThirdHooker ...)
@@ -189,12 +207,39 @@ Of course, we can also abbreviate it.
> The following example
```kotlin
class HookEntry : IYukiHookXposedInit {
object HookEntry : IYukiHookXposedInit {
override fun onHook() = encase(FirstHooker, SecondHooker, ThirdHooker ...)
}
```
#### Special Case
As we mentioned above, it is generally not recommended to use `class` to create child Hookers, but there is a special case where it may still be necessary to keep your Hooker supporting multiple instantiations.
There is a rare possibility that there are multiple package names in a process.
In this case, when `YukiHookAPI` finds that the child Hooker is a singleton, it will ignore it and print a warning message.
```: no-line-numbers
This Hooker "HOOKER" is singleton or reused, but the current process has multiple package name "NAME", the original is "NAME"
Make sure your Hooker supports multiple instances for this situation
The process with package name "NAME" will be ignored
```
In this case, we only need to modify `object` to `class` or determine the package name during loading and then load the child Hooker.
For example, in the above cases, the following forms can be used to load.
> The following example
```kotlin
encase {
// Assume this is the app package name and child Hooker you need to load
loadApp("com.example.demo", YourCustomHooker)
}
```
### Expansion Features
If your current Hook Framework supports and enables the Resources Hook feature, you can now create Resources Hooks directly in `encase`.
@@ -208,9 +253,12 @@ In `YukiHookAPI`, these functions **are seamless**.
```kotlin
encase {
loadApp(name = "com.example.demo") {
findClass(name = "$packageName.DemoClass").hook {
// Your code here.
}
"$packageName.DemoClass".toClass()
.method {
// Your code here.
}.hook {
// Your code here.
}
// Create a Resources Hook (fixed usage)
resources().hook {
// Your code here.
@@ -235,9 +283,12 @@ encase {
}
}
loadApp(name = "com.example.demo") {
findClass(name = "$packageName.DemoClass").hook {
// Your code here.
}
"$packageName.DemoClass".toClass()
.method {
// Your code here.
}.hook {
// Your code here.
}
// Create a Resources Hook in the app
resources().hook {
// Your code here.
@@ -271,11 +322,14 @@ Below are two **error** examples.
```kotlin
encase {
// Wrong usage, can't start Hook directly
findClass(name = "com.example.demo.DemoClass").hook {
// ...
}
// ❗ Wrong usage, can't start Hook directly
// Wrong usage, can't start Hook directly
"com.example.demo.DemoClass".toClass()
.method {
// Your code here.
}.hook {
// Your code here.
}
// Wrong usage, can't start Hook directly
resources().hook {
// ...
}
@@ -285,7 +339,7 @@ encase {
> Sample Code 2
```kotlin
class HookEntry : IYukiHookXposedInit {
object HookEntry : IYukiHookXposedInit {
override fun onHook() {
// <Scenario 1>
@@ -300,11 +354,14 @@ class HookEntry : IYukiHookXposedInit {
object CustomHooker : YukiBaseHooker() {
override fun onHook() {
// Wrong method of use
// Wrong method of use
// Because there is no judgment object in the outer layer, you cannot start Hook directly
findClass(name = "com.example.demo.DemoClass").hook {
// ...
}
"com.example.demo.DemoClass".toClass()
.method {
// Your code here.
}.hook {
// Your code here.
}
}
}
```
@@ -330,9 +387,12 @@ encase {
loadApp(/** name parameter optional */) {
loadHooker(CustomHooker)
// ✅ Correct usage, Hook in app scope
findClass(name = "com.example.demo.DemoClass").hook {
// ...
}
"com.example.demo.DemoClass".toClass()
.method {
// Your code here.
}.hook {
// Your code here.
}
// ✅ Correct usage, Hook in app scope
resources().hook {
// ...
@@ -344,7 +404,7 @@ encase {
> Sample Code 2
```kotlin
class HookEntry : IYukiHookXposedInit {
object HookEntry : IYukiHookXposedInit {
override fun onHook() {
encase(CustomHooker)
@@ -357,9 +417,12 @@ object CustomHooker : YukiBaseHooker() {
// ✅ The correct method of use, since there is no judgment object in the outer layer
// it is necessary to judge the scope of the app before performing Hook
loadApp(/** name parameter optional */) {
findClass(name = "com.example.demo.DemoClass").hook {
// ...
}
"com.example.demo.DemoClass".toClass()
.method {
// Your code here.
}.hook {
// Your code here.
}
}
}
}

View File

@@ -43,17 +43,17 @@ You try to load the `encase` method in the `onInit` or `onXposedEvent` method of
> The following example
```kotlin
class HookEntry : IYukiHookXposedInit {
object HookEntry : IYukiHookXposedInit {
override fun onInit() {
// Wrong usage
// Wrong usage
YukiHookAPI.encase {
// Your code here.
}
}
override fun onXposedEvent() {
// Wrong usage
// Wrong usage
YukiHookAPI.encase {
// Your code here.
}
@@ -72,7 +72,7 @@ Please load the `encase` method in the `onHook` method.
> The following example
```kotlin
class HookEntry : IYukiHookXposedInit {
object HookEntry : IYukiHookXposedInit {
override fun onInit() {
// Only the configs method can be loaded here
@@ -130,7 +130,7 @@ Usually, this kind of error does not happen easily. If this error occurs, you ca
::: danger loggerE
YukiHookAPI try to load HookEntryClass failed
YukiHookAPI try to load hook entry class failed
:::
@@ -226,7 +226,7 @@ If the problem persists, please bring detailed logs for feedback.
::: danger loggerE
Hooked Member with a finding error by **CLASS**
Hooked Member with a finding error / by **CLASS**
:::
@@ -242,7 +242,7 @@ Please check the previous error log before this error occurs, maybe there is an
::: danger loggerE
Hooked Member cannot be non-null by **CLASS**
Hooked Member cannot be null / by **CLASS**
:::
@@ -255,7 +255,7 @@ After the Hook is executed, the `member` of the Hook is `null` and the target Ho
```kotlin
injectMember {
// There are no search conditions for methods and constructors that require hooks
afterHook {
after {
// ...
}
}
@@ -273,7 +273,7 @@ injectMember {
method {
// Your code here.
}
afterHook {
after {
// ...
}
}
@@ -302,13 +302,12 @@ private boolean test()
Below is an error case.
```kotlin
injectMember {
method {
name = "test"
emptyParam()
}
method {
name = "test"
emptyParam()
}.hook {
// <Scenario 1> Set the wrong type, the original type is Boolean
beforeHook {
before {
result = 0
}
// <Scenario 2> Return the wrong type, the original type is Boolean
@@ -322,7 +321,7 @@ injectMember {
::: warning
If the above scenario occurs in **beforeHook** or **afterHook**, it will cause the Host App to throw an exception from **XposedBridge** (which will expose the fact of being Hooked).
If the above scenario occurs in **before** or **after**, it will cause the Host App to throw an exception from **XposedBridge** (which will expose the fact of being Hooked).
:::
@@ -334,7 +333,7 @@ Please confirm the correct return value type of the current Hook method, modify
::: danger loggerE
Hook initialization failed because got an Exception
Hook initialization failed because got an exception
:::
@@ -350,7 +349,7 @@ This is a reminder that an exception occurred during the Hook preparation stage,
::: danger loggerE
Try to hook **NAME**\[**NAME**\] got an Exception
Try to hook **NAME**\[**NAME**\] got an exception
:::
@@ -379,15 +378,15 @@ A disallowed parameter type was set when looking up methods, constructors, and v
```kotlin
// Find a method
method {
// Invalid type example is set
// Invalid type example is set
param(false, 1, 0)
// Invalid type example is set
// Invalid type example is set
returnType = false
}
// Find a variable
field {
// Invalid type example is set
// Invalid type example is set
type = false
}
```
@@ -452,30 +451,6 @@ Please confirm the `RemedyPlan` parameter you set and the `Class` that exists in
::: danger loggerE
You must set a condition when finding a Method/Constructor/Field
:::
**Abnormal**
No conditions are set when looking for methods, constructors, and variables.
> The following example
```kotlin
method {
// No conditions are set here
}
```
**Solution**
Please complete your search criteria and try again.
###### exception
::: danger loggerE
Can't find this Class in \[**CLASSLOADER**\]: **CONTENT** Generated by YukiHookAPI#ReflectionTool
:::
@@ -650,6 +625,36 @@ After troubleshooting your own code problems, please provide detailed logs for f
::: danger loggerE
Failed to got Host Resources
:::
**Abnormal**
Failed to obtain the Host App's original Resources instance object when using `replaceTo { ... }` or `replaceToModuleResource { ... }` when finding Resources.
> The following example
```kotlin
conditions {
name = "test"
string()
}
replaceTo { "${it}_some_text" }
```
**Solution**
Under normal circumstances, this error will basically not occur.
If this error occurs, it may be a problem with the currently used Hook Framework.
After troubleshooting your own code problems, please provide detailed logs for feedback.
###### exception
::: danger loggerE
Resources Hook condition name/type cannot be empty \[**TAG**\]
:::
@@ -704,7 +709,7 @@ The current Hook Framework needs to support and enable the Resources Hook functi
::: danger loggerE
Resources Hook got an Exception \[**TAG**\]
Resources Hook got an exception \[**TAG**\]
:::
@@ -892,7 +897,7 @@ If you must obtain the resources of the Module App itself, please use it directl
::: danger loggerE
Activity Proxy initialization failed because got an Exception
Activity Proxy initialization failed because got an exception
:::
@@ -912,7 +917,7 @@ If you cannot find the description of the relevant error log, after eliminating
::: danger loggerE
Activity Proxy got an Exception in msg.what \[**WHAT**\]
Activity Proxy got an exception in msg.what \[**WHAT**\]
:::
@@ -941,7 +946,7 @@ Invalid parameters were filled in when injecting Module App's `Activity` using `
> The following example
```kotlin
// The content filled in here is just an example
// The content filled in here is just an example
// And the proxy is filled with invalid parameters that cannot be understood
registerModuleAppActivities(proxy = false)
```
@@ -1075,97 +1080,6 @@ Please make sure you have loaded the `encase` method of `YukiHookAPI` in the cor
###### exception
::: danger RuntimeException
!!!DO NOT ALLOWED!!! You cannot hook or reflection to call the internal class of the YukiHookAPI itself, The called class is \[**CLASS**\]
:::
**Abnormal**
You have invoked the `Class` object of the API itself using `YukiHookAPI` related reflection or Hook function.
> The following example
```kotlin
// <Scenario 1>
YukiHookAPI.current()
// <Scenario 2>
PackageParam::class.java.hook {
// ...
}
// <Scenario 3>
MethodFinder::class.java.method {
name = "name"
param(StringClass)
}.get().call("name")
// ...
```
**Solution**
Please check the code section for errors, such as the case below.
> The following example
```kotlin
YourClass.method {
// ...
// ❗ The method execution is not called
// The actual method is called here is the MethodFinder.Result object
}.get(instance).current()
YourClass.method {
// ...
// ✅ The correct way to use it, assuming this method has no parameters
}.get(instance).call().current()
```
Inlining, reflection, Hook `YukiHookAPI`'s own `Class` and internal functions are not allowed to prevent errors.
###### exception
::: danger UnsupportedOperationException
!!!DANGEROUS!!! Hook \[**CLASS**\] Class is a dangerous behavior! \[**CONTENT**\] \[**SOLVE**\]
:::
**Abnormal**
You tried to hook a `Class` object in the list of dangerous behaviors, such as `Class`, `ClassLoader`, `Method`.
> The following example
```kotlin
// <Scenario 1>
JavaClassLoader.hook {
// ...
}
// <Scenario 2>
JavaClass.hook {
// ...
}
// <Scenario 3>
JavaMethod.hook {
// ...
}
// ...
```
**Solution**
These functions are internal to the system, <u>**they should not be hooked, may not be supported on some Hook Frameworks, and may cause other errors**</u>, please try to replace the hook point.
::: tip
If you still want to use this feature, please refer to [YukiMemberHookCreator.useDangerousOperation](../api/public/com/highcapable/yukihookapi/hook/core/YukiMemberHookCreator#usedangerousoperation-method) method.
But **It is strongly recommended not to do this, please do not report any problems, <u>all the consequences will be borne by yourself</u>**.
:::
###### exception
::: danger NoClassDefFoundError
Can't find this Class in \[**CLASSLOADER**\]: **CONTENT** Generated by YukiHookAPI#ReflectionTool
@@ -1275,13 +1189,13 @@ This situation basically does not exist, because `appContext` is assigned in `on
::: danger IllegalStateException
YukiHookModulePrefs not allowed in Custom Hook API
YukiHookPrefsBridge not allowed in Custom Hook API
:::
**Abnormal**
`YukiHookModulePrefs` is used in Hook's own app (not Xposed Module).
`YukiHookPrefsBridge` is used in Hook's own app (not Xposed Module).
> The following example
@@ -1290,7 +1204,7 @@ class MyApplication : Application() {
override fun attachBaseContext(base: Context?) {
YukiHookAPI.encase(base) {
// Can't use prefs in this case
// Can't use prefs in this case
prefs.getBoolean("test_data")
}
super.attachBaseContext(base)
@@ -1300,7 +1214,7 @@ class MyApplication : Application() {
**Solution**
You can only use `YukiHookModulePrefs` when [Use as Xposed Module Configs](../config/xposed-using), please use the native `Sp` storage in the Hook's own app.
You can only use `YukiHookPrefsBridge` when [Use as Xposed Module Configs](../config/xposed-using), please use the native `Sp` storage in the Hook's own app.
###### exception
@@ -1312,7 +1226,7 @@ Cannot load the XSharedPreferences, maybe is your Hook Framework not support it
**Abnormal**
Using `YukiHookModulePrefs` in (Xposed) Host environment but unable to get `XSharedPreferences` object.
Using `YukiHookPrefsBridge` in (Xposed) Host environment but unable to get `XSharedPreferences` object.
> The following example
@@ -1348,7 +1262,7 @@ class MyApplication : Application() {
override fun attachBaseContext(base: Context?) {
YukiHookAPI.encase(base) {
// dataChannel cannot be used in this case
// dataChannel cannot be used in this case
dataChannel.wait(key = "test_data") {
// ...
}
@@ -1366,29 +1280,13 @@ You can only use `YukiHookDataChannel` when [Use as Xposed Module Configs](../co
::: danger IllegalStateException
YukiHookDataChannel only support used on an Activity, but this current context is "**CLASSNAME**"
:::
**Abnormal**
`YukiHookDataChannel` is used in a non-`Activity` context of a Module App.
**Solution**
You can only use `YukiHookDataChannel` in `Activity` or `Fragment`.
###### exception
::: danger IllegalStateException
Xposed modulePackageName load failed, please reset and rebuild it
:::
**Abnormal**
When using `YukiHookModulePrefs` or `YukiHookDataChannel` in the Hook process, the `modulePackageName` at load time cannot be read, resulting in the package name of the own Module App cannot be determined.
When using `YYukiHookPrefsBridge` or `YukiHookDataChannel` in the Hook process, the `modulePackageName` at load time cannot be read, resulting in the package name of the own Module App cannot be determined.
**Solution**
@@ -1398,13 +1296,13 @@ Please read the help document [here](../config/xposed-using#modulepackagename-pa
::: danger IllegalStateException
YukiHookModulePrefs missing Context instance
YukiHookPrefsBridge missing Context instance
:::
**Abnormal**
`YukiHookModulePrefs` is used in the Module App to store data but no `Context` instance is passed in.
`YukiHookPrefsBridge` is used in the Module App to store data but no `Context` instance is passed in.
> The following example
@@ -1413,16 +1311,16 @@ class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
// Wrong usage
// Wrong usage
// Constructor has been set to private in API 1.0.88 and later
YukiHookModulePrefs().getBoolean("test_data")
YukiHookPrefsBridge().getBoolean("test_data")
}
}
```
**Solution**
It is recommended to use the `modulePrefs` method to load `YukiHookModulePrefs` in `Activity`.
It is recommended to use the `prefs(...)` method to load `YukiHookPrefsBridge` in `Activity`.
> The following example
@@ -1432,7 +1330,7 @@ class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
// ✅ Correct usage
modulePrefs.getBoolean("test_data")
prefs().getBoolean("test_data")
}
}
```
@@ -1441,17 +1339,42 @@ class MainActivity : AppCompatActivity() {
::: danger IllegalStateException
The Host App's Context has not yet initialized successfully, the native function cannot be used at this time
:::
**Abnormal**
In the (Xposed) Host environment `PackageParam`, `YukiHookPrefsBridge` is used and the `native` method is called, but the lifecycle of the Host App is not initialized at this time.
> The following example
```kotlin
encase {
// This method was called
prefs.native()
}
```
**Solution**
The `native` method requires an existing `Context` object to store data in, and you can use this method in listening to the Host App lifecycle state.
###### exception
::: danger IllegalStateException
Key-Value type **TYPE** is not allowed
:::
**Abnormal**
An unsupported storage type was passed in when using the `get` or `put` methods of `YukiHookModulePrefs` or the `wait` or `put` methods of `YukiHookDataChannel`.
An unsupported storage type was passed in when using the `get` or `put` methods of `YukiHookPrefsBridge` or the `wait` or `put` methods of `YukiHookDataChannel`.
**Solution**
The supported types of `YukiHookModulePrefs` are only `String`, `Set<String>`, `Int`, `Float`, `Long`, `Boolean`, please pass in the supported types.
The supported types of `YukiHookPrefsBridge` are only `String`, `Set<String>`, `Int`, `Float`, `Long`, `Boolean`, please pass in the supported types.
The supported types of `YukiHookDataChannel` are the types restricted by `Intent.putExtra`, please pass in the supported types.
@@ -1525,7 +1448,7 @@ Custom Hooking Members is empty
injectMember {
// Method parameters in parentheses are left blank
members()
afterHook {
after {
// ...
}
}
@@ -1552,7 +1475,7 @@ HookParam Method args index must be >= 0
```kotlin
injectMember {
// ...
afterHook {
after {
// Assume param is empty
args().last()...
// Set an index less than 0
@@ -1582,7 +1505,7 @@ An object that calls an `instance` variable or `instance` method in a `HookParam
```kotlin
injectMember {
// ...
afterHook {
after {
// This variable is called
instance...
// This method is called
@@ -1616,7 +1539,7 @@ The `args` variable is called in `HookParam`, but the parameter array of the cur
```kotlin
injectMember {
// ...
afterHook {
after {
// This variable is called
args...
}
@@ -1646,7 +1569,7 @@ Call the `member` variable in `HookParam` but cannot get the method and construc
```kotlin
injectMember {
// ...
afterHook {
after {
// This variable is called
member...
}
@@ -1676,7 +1599,7 @@ Calling the `method` variable in `HookParam` but not getting the method instance
```kotlin
injectMember {
// ...
afterHook {
after {
// This variable is called
method...
}
@@ -1706,7 +1629,7 @@ A method instance for calling a `constructor` variable in a `HookParam` but not
```kotlin
injectMember {
// ...
afterHook {
after {
// This variable is called
constructor...
}
@@ -1736,7 +1659,7 @@ Invoking the `instance` method in a `HookParam` specifies the wrong type.
```kotlin
injectMember {
// ...
afterHook {
after {
// The type is cast to Activity
// But assumes the current instance's type is not this type
instance<Activity>()...
@@ -1767,7 +1690,7 @@ The `ArgsModifyer.set` method is called in `HookParam` but the method parameter
```kotlin
injectMember {
// ...
afterHook {
after {
// This method is called
args(...).set(...)
}
@@ -1795,7 +1718,7 @@ Calling the `ArgsModifyer.set` method in `HookParam` specifies an array number b
```kotlin
injectMember {
// ...
afterHook {
after {
// The subscript starts from 0
// Assuming the original parameter subscript is 5, but fill in 6 here
args(index = 6).set(...)
@@ -1880,6 +1803,38 @@ For details, please refer to [Status Monitor](../guide/example#status-monitor).
###### exception
::: danger IllegalStateException
Use of searchClass { ... }.hook { ... } is an error, please use like searchClass { ... }.get()?.hook { ... }
:::
**Abnormal**
The Hook instance are created directly using the `searchClass { ... }.hook { ... }` method.
**Solution**
Please use `searchClass { ... }.get()?.hook { ... }` to create a Hook instance.
###### exception
::: danger IllegalStateException
This type \[**TYPE**\] not support to hook, supported are Constructors and Methods
:::
**Abnormal**
Using `Member.hook { ... }` creates member objects that do not support Hooks, such as `Field`.
**Solution**
You can only Hook `Constructor` and `Method`.
###### exception
::: danger IllegalStateException
LayoutInflatedParam View instance got null

View File

@@ -0,0 +1,160 @@
# Migrate to YukiHookAPI 1.2.x
`YukiHookAPI` has undergone a lot of adjustments since version `1.2.0`, you can read on to see what are the notes and new features.
## Default Behavior Changes
Since version `1.2.0`, the `isUsingResourcesHook` function in `@InjectYukiHookWithXposed` is no longer enabled by default, please enable it manually if necessary.
::: warning
Resources Hook will be removed in version **2.0.0** and is now marked **LegacyResourcesHook**.
You can use **@OptIn(LegacyResourcesHook::class)** to eliminate the warning, continue to use version **1.x.x**.
:::
## New API
`YukiHookAPI` introduced the [New Hook Code Style](https://github.com/HighCapable/YukiHookAPI/issues/33) (New API) of `2.0.0` in the `1.2.0` version, it is now in the experimental stage.
You can before the `2.0.0` version is officially released, start migrating and experience the New API.
::: warning
All legacy APIs have been marked **LegacyHookApi**, you can use **@OptIn(LegacyHookApi::class)** to eliminate the warning and continue to use the legacy API.
:::
For example, we want to Hook the `test` method in the `com.example.Test` class.
> Legacy API
```kotlin
findClass("com.example.Test").hook {
injectMember {
method {
name = "test"
}
beforeHook {
// Your code here.
}
afterHook {
// Your code here.
}
}
}
```
> New API
```kotlin
"com.example.Test".toClass()
.method {
name = "test"
}.hook {
before {
// Your code here.
}
after {
// Your code here.
}
}
```
The Hook object of the New API has been migrated from `Class` to `Member`, which will be more intuitive.
## Differential Functions
The following are some of the different functions of connecting to the new version of the API.
### New Multi-Hook Usage
Previously we needed to hook all methods that match conditions like this.
> The following example
```kotlin
injectMembers {
method {
name { it.contains("some") }
}.all()
afterHook {
// Your code here.
}
}
```
Now, you can use the following method instead.
> The following example
```kotlin
method {
name { it.contains("some") }
}.hookAll {
after {
// Your code here.
}
}
```
### New `allMembers(...)` Usage
Previously we needed to hook all methods and constructors like this.
> The following example
```kotlin
injectMembers {
allMembers(MembersType.METHOD)
afterHook {
// Your code here.
}
}
```
```kotlin
injectMembers {
allMembers(MembersType.CONSTRUCTOR)
afterHook {
// Your code here.
}
}
```
Now, you can use the following method instead.
> The following example
```kotlin
method().hookAll {
after {
// Your code here.
}
}
```
```kotlin
constructor().hookAll {
after {
// Your code here.
}
}
```
When the find conditions are not filled in, all members in the current `Class` are obtained by default.
If you want to hook `MembersType.ALL`, there is currently no direct method, but you can concatenate all members and then hook.
> The following example
```kotlin
(method().giveAll() + constructor().giveAll()).hookAll {
after {
// Your code here.
}
}
```
But we do not recommend this approach, too many hook members at one time are uncontrollable and problems may occur.

View File

@@ -6,7 +6,7 @@
> As an Xposed Module, `YukiHookAPI` provides an automatic builder.
You need to integrate the latest version of the `com.highcapable.yukihookapi:ksp-xposed` dependency in your `build.gradle`.
You need to integrate the latest version of the `com.highcapable.yukihookapi:ksp-xposed` dependency in your build script.
## Custom Automatic Builder
@@ -19,6 +19,7 @@ annotation class InjectYukiHookWithXposed(
val sourcePath: String,
val modulePackageName: String,
val entryClassName: String,
val isUsingXposedModuleStatus: Boolean,
val isUsingResourcesHook: Boolean
)
```
@@ -65,6 +66,32 @@ If you want to use the module package name to be automatically generated, you ne
:::
::: danger
In Android Gradle Plugin **8+** versions, you need to manually enable **buildConfig** in the project's **build.gradle** or **build.gradle.kts**.
> Groovy DSL
```groovy
android {
buildFeatures {
buildConfig true
}
}
```
> Kotlin DSL
```kt
android {
buildFeatures {
buildConfig = true
}
}
```
:::
Example namespace `com.example.demo`, any one of the following definitions.
The following definitions are for reference only, usually **as long as your project can generate the `BuildConfig.java` file normally, no additional operations are required**.
@@ -100,6 +127,12 @@ If your module package name is automatically generated by unconventional means,
@InjectYukiHookWithXposed(modulePackageName = "com.example.demo")
```
:::danger
Please do not fill in **BuildConfig.APPLICATION_ID** in **modulePackageName**, this will get an empty string during compilation, depending on the behavior of the Android Gradle Plugin.
:::
As long as you customize the `modulePackageName` parameter, you will get a warning at compile time.
> The following example
@@ -186,11 +219,50 @@ The **entryClassName** you define must not be the same as the class name in **xp
:::
#### isUsingXposedModuleStatus Parameter
`isUsingXposedModuleStatus` determines whether the automatic builder generates relevant code for status functions such as Xposed Module activation, this feature is enabled by default.
After generation, you will be able to use the related functions of `YukiHookAPI.Status` in the Module App's process.
If you do not want to generate related code, you can manually turn off this feature, which will only take effect for the Module App's process.
#### isUsingResourcesHook Parameter
`isUsingResourcesHook` determines whether the automatic builder generates relevant code for the Resources Hook, this feature is enabled by default.
`isUsingResourcesHook` determines whether the automatic builder generates relevant code for the Resources Hook, this feature is not enabled by default.
The generated entry class after enabling it will look like the following.
By default the generated entry class will look like this.
> The following example
```kotlin:no-line-numbers
class _YukiHookXposedInit : IXposedHookZygoteInit, IXposedHookLoadPackage {
override fun initZygote(sparam: IXposedHookZygoteInit.StartupParam?) {
// ...
}
override fun handleLoadPackage(lpparam: XC_LoadPackage.LoadPackageParam?) {
// ...
}
}
```
If your current project need to use Resources Hook, you can set `isUsingResourcesHook = true` to enable automatic generation.
::: warning
This feature will no longer be enabled by default after version **1.2.0**, please enable it manually if you want to use it.
:::
> The following example
```kotlin
@InjectYukiHookWithXposed(isUsingResourcesHook = true)
```
The resulting entry class after enabled will look like the following.
> The following example
@@ -211,34 +283,21 @@ class _YukiHookXposedInit : IXposedHookZygoteInit, IXposedHookLoadPackage, IXpos
}
```
If your current project does not need to use Resources Hook, you can set `isUsingResourcesHook = false` to disable automatic generation.
::: tip
> The following example
Since the Xposed entry class is dynamically generated by **YukiHookAPI**, it will generate the following two files at the same time.
```kotlin
@InjectYukiHookWithXposed(isUsingResourcesHook = false)
```
- **assets/xposed_init**
The resulting entry class after closing will look like the following.
- **resources/META-INF/yukihookapi_init**
If you are using **Git** code control system, you can add these two files to **.gitignore** file.
> The following example
```kotlin:no-line-numbers
class _YukiHookXposedInit : IXposedHookZygoteInit, IXposedHookLoadPackage {
override fun initZygote(sparam: IXposedHookZygoteInit.StartupParam?) {
// ...
}
override fun handleLoadPackage(lpparam: XC_LoadPackage.LoadPackageParam?) {
// ...
}
}
```
:::
### IYukiHookXposedInit Interface
The `IYukiHookXposedInit` interface that your `HookEntryClass` must implements it, which is the entry point for your Module App to start hooking.
The `IYukiHookXposedInit` interface that your Hook entry class must implements it, which is the entry point for your Module App to start hooking.
::: tip

View File

@@ -8,34 +8,46 @@
```:no-line-numbers
Host Environment
└─ YukiMemberHookCreator
└── Class
└── MemberHookCreator
└── Member
├── Before
└── After
MemberHookCreator
└── Member
├── Before
└── After
...
YukiResourcesHookCreator
└── Resources
└── ResourcesHookCreator
└── Drawable
└── Replace
ResourcesHookCreator
└── Layout
└── Inject
...
└─ YukiMemberHookCreator
─ Class
─ MemberHookCreator
─ Member
─ Before
─ After
MemberHookCreator
─ Member
─ Before
─ After
...
YukiResourcesHookCreator
─ Resources
─ ResourcesHookCreator
─ Drawable
─ Replace
ResourcesHookCreator
─ Layout
─ Inject
...
```
> The above structure can be written in the following form in code.
```kotlin
TargetClass.hook {
injectMember {
method {
// New version
TargetClass.method {
// Your code here.
}.hook {
before {
// Your code here.
}
after {
// Your code here.
}
}
// Old version
TargetClass.hook {
injectMember {
method {
// Your code here.
}
beforeHook {
@@ -46,6 +58,7 @@ TargetClass.hook {
}
}
}
// Resources Hook (2.0.0 will be discontinued)
resources().hook {
injectResource {
conditions {
@@ -60,9 +73,9 @@ resources().hook {
> You can find the demo provided by the API below to learn how to use `YukiHookAPI`.
- Host App Demo [click here to view](https://github.com/fankes/YukiHookAPI/tree/master/demo-app)
- Host App Demo [click here to view](https://github.com/HighCapable/YukiHookAPI/tree/master/samples/demo-app)
- Module App Demo [click here to view](https://github.com/fankes/YukiHookAPI/tree/master/demo-module)
- Module App Demo [click here to view](https://github.com/HighCapable/YukiHookAPI/tree/master/samples/demo-module)
Install the Host App and Module App Demo at the same time, and test the hooked function in the Host App by activating the Module App.
@@ -80,20 +93,17 @@ Add code in the body of the `encase` method.
```kotlin
loadApp(name = "com.android.browser") {
ActivityClass.hook {
injectMember {
method {
name = "onCreate"
param(BundleClass)
returnType = UnitType
}
afterHook {
AlertDialog.Builder(instance())
.setTitle("Hooked")
.setMessage("I am hook!")
.setPositiveButton("OK", null)
.show()
}
ActivityClass.method {
name = "onCreate"
param(BundleClass)
returnType = UnitType
}.hook {
after {
AlertDialog.Builder(instance())
.setTitle("Hooked")
.setMessage("I am hook!")
.setPositiveButton("OK", null)
.show()
}
}
}
@@ -103,20 +113,19 @@ At this point, the `onCreate` method will be successfully hooked and this dialog
So, what should I do if I want to continue the Hook `onStart` method?
In the code just now, continue to insert an `injectMember` method body.
We can use Kotlin's `apply` method on `ActivityClass` to create a call space.
> The following example
```kotlin
loadApp(name = "com.android.browser") {
ActivityClass.hook {
injectMember {
method {
name = "onCreate"
param(BundleClass)
returnType = UnitType
}
afterHook {
ActivityClass.apply {
method {
name = "onCreate"
param(BundleClass)
returnType = UnitType
}.hook {
after {
AlertDialog.Builder(instance())
.setTitle("Hooked")
.setMessage("I am hook!")
@@ -124,13 +133,12 @@ loadApp(name = "com.android.browser") {
.show()
}
}
injectMember {
method {
name = "onStart"
emptyParam()
returnType = UnitType
}
afterHook {
method {
name = "onStart"
emptyParam()
returnType = UnitType
}.hook {
after {
// Your code here.
}
}
@@ -138,18 +146,19 @@ loadApp(name = "com.android.browser") {
}
```
For the `Class` that does not exist in the current project, you can use the `stub` method or the `findClass` method to get the class that needs to be hooked.
For the `Class` that does not exist in the current project, you can use the `stub` method or the `String.toClass(...)` method to get the class that needs to be hooked.
For example, I want to get `com.example.demo.TestClass`.
> The following example
```kotlin
findClass(name = "com.example.demo.TestClass").hook {
injectMember {
"com.example.demo.TestClass".toClass()
.method {
// Your code here.
}.hook {
// Your code here.
}
}
```
If `com.example.demo` is the app you want to hook, then the writing method can be simpler.
@@ -157,38 +166,31 @@ If `com.example.demo` is the app you want to hook, then the writing method can b
> The following example
```kotlin
findClass(name = "$packageName.TestClass").hook {
injectMember {
"$packageName.TestClass".toClass()
.method {
// Your code here.
}.hook {
// Your code here.
}
}
```
Some people may have started to say that `findClass` is a bit cumbersome in some scenarios.
Because some people may have the following needs.
If this `Class` is not immediately available, you can use `lazyClass(...)` to define it.
> The following example
```kotlin
const val TestClass = "com.example.demo.TestClass"
Define `TestClass`.
TestClass.hook {
injectMember {
// Your code here.
}
}
```kotlin
val TestClass by lazyClass("com.example.demo.TestClass")
```
That's okay, you can also create a Hook directly using the string class name.
> The following example
Use it when appropriate.
```kotlin
"$packageName.TestClass".hook {
injectMember {
// Your code here.
}
TestClass.method {
// Your code here.
}.hook {
// Your code here.
}
```
@@ -210,16 +212,13 @@ Add code in the body of the `encase` method.
```kotlin
loadZygote {
ActivityClass.hook {
injectMember {
method {
name = "onCreate"
param(BundleClass)
returnType = UnitType
}
afterHook {
// Your code here.
}
ActivityClass.method {
name = "onCreate"
param(BundleClass)
returnType = UnitType
}.hook {
after {
// Your code here.
}
}
}
@@ -243,10 +242,14 @@ Add code in the body of the `encase` method.
```kotlin
loadSystem {
ApplicationInfoClass.hook {
ApplicationInfoClass.method {
// Your code here.
}.hook {
// Your code here.
}
PackageInfoClass.hook {
PackageInfoClass.method {
// Your code here.
}.hook {
// Your code here.
}
}
@@ -260,6 +263,12 @@ loadSystem {
### Hook Resources
::: warning
This feature will be discontinued and removed in version **2.0.0**.
:::
Suppose, we want to replace the content of `app_name` of type `string` in Hook `com.android.browser` with `123`.
Add code in the body of the `encase` method.
@@ -331,15 +340,15 @@ The first way, save the `Result` instance of the current injected object, and ca
```kotlin
// Set a variable to save the current instance
val hookResult = injectMember {
method {
val hookResult =
method {
name = "test"
returnType = UnitType
}.hook {
after {
// ...
}
}
afterHook {
// ...
}
}
// Call the following method when appropriate
hookResult.remove()
```
@@ -349,12 +358,11 @@ The second method, call `removeSelf` in the Hook callback method to remove itsel
> The following example
```kotlin
injectMember {
method {
name = "test"
returnType = UnitType
}
afterHook {
method {
name = "test"
returnType = UnitType
}.hook {
after {
// Just call the following method directly
removeSelf()
}
@@ -378,7 +386,7 @@ You can handle exceptions that occur during the Hook method.
> The following example
```kotlin
injectMember {
hook {
// Your code here.
}.result {
// Handle the exception at the start of the hook
@@ -405,7 +413,7 @@ injectResource {
}
```
You can also handle exceptions that occur when the Hook's `Class` does not exist.
**(Applicable to older versions)** You can also handle exceptions that occur when the Hook's `Class` does not exist.
> The following example
@@ -485,11 +493,10 @@ If you want to throw an exception directly to the Host App in the Hook callback
> The following example
```kotlin
injectMember {
method {
// ...
}
afterHook {
method {
// ...
}.hook {
after {
RuntimeException("Exception Test").throwToApp()
}
}
@@ -500,11 +507,10 @@ You can also throw exceptions directly in the Hook callback method body, and the
> The following example
```kotlin
injectMember {
method {
// ...
}
afterHook {
method {
// ...
}.hook {
after {
throw RuntimeException("Exception Test")
}.onFailureThrowToApp()
}
@@ -514,7 +520,7 @@ The above two methods can receive an exception at the Host App and cause the Hos
::: warning
In order to ensure that the Hook calling domain and the calling domain within the Host App are isolated from each other, exceptions can only be thrown to the Host App in the **beforeHook** and **afterHook** callback method bodies.
In order to ensure that the Hook calling domain and the calling domain within the Host App are isolated from each other, exceptions can only be thrown to the Host App in the **before** and **after** callback method bodies.
:::
@@ -524,42 +530,6 @@ For more functions, please refer to [Throwable.throwToApp](../api/public/com/hig
:::
## Status Monitor
People who use `XposedHelpers` often print `Unhook` after the Hook to determine whether the Hook is successful.
In `YukiHookAPI`, you can easily reimplement this functionality with the following methods.
First we can monitor that the Hook is ready to start.
> The following example
```kotlin
YourClass.hook {
// Your code here.
}.onPrepareHook {
loggerD(msg = "$instanceClass hook start")
}
```
::: danger
**instanceClass** is recommended to be used only in **onPrepareHook**, otherwise the Hook's **Class** does not exist and an uninterceptable exception will be thrown, causing the Hook process to "die".
:::
Then, we can also monitor the success of the method result of the Hook.
> The following example
```kotlin
injectMember {
// Your code here.
}.onHooked { member ->
loggerD(msg = "$member has hooked")
}
```
## Expansion Usage
> You can use the following methods to easily implement various judgments and functions in the Hook process.
@@ -608,7 +578,7 @@ For more functions, please refer to [PackageParam.withProcess](../api/public/com
## Writing Optimization
To make the code more concise, you can omit the name of `YukiHookAPI` and write your `onHook` entry as `lambda`.
To make the code more concise, you can omit the name of `YukiHookAPI` and write your `onHook` entry as **lambda**.
> The following example
@@ -618,13 +588,31 @@ override fun onHook() = encase {
}
```
## Xposed Module own Active State
You can also abbreviate the `hook { ... }` method body when you only need a Hook callback event.
Usually, we choose to write a method that return `false`, and then Hook this method to return `true` to prove that the Hook has taken effect.
> The following example
In `YukiHookAPI`, you don't need to do this at all. `YukiHookAPI` has already encapsulated this operation for you, and you can use it directly.
```kotlin
ActivityClass.method {
// Your code here.
}.hook().after {
// Your code here.
}
```
Now, you can use `YukiHookAPI.Status.isXposedModuleActive` directly in the Module App to determine whether it is active.
## Xposed Module Status
Usually, the developer of the Xposed Module will choose to read the activation information of the current Xposed Module to better show the user the effective status of the current function.
In addition to the basic Hook functions, `YukiHookAPI` also designed a set of Xposed Module status judgment functions for developers, such as activation status and Hook Framework information.
### Determine Self-activation Status
Usually, we will choose to write a method to make it return `false`, and then hook this method to make it return `true` to prove that the Hook has taken effect.
In `YukiHookAPI`, you dont need to do this at all, `YukiHookAPI` has already encapsulated this operation for you, and you can use it directly.
Now, you can directly use `YukiHookAPI.Status.isXposedModuleActive` to determine whether it is activated in the Module App.
> The following example
@@ -634,9 +622,9 @@ if(YukiHookAPI.Status.isXposedModuleActive) {
}
```
Due to some special reasons, Module Apps in TaiChi and Wuji cannot use standard methods to detect the activation state.
Due to some special reasons, the Xposed Modules in TaiChi and Wuji cannot use the standard method to detect the activation state.
At this point, you can use `YukiHookAPI.Status.isTaiChiModuleActive` to determine whether it is activated.
At this point you can use `YukiHookAPI.Status.isTaiChiModuleActive` to determine whether it is activated.
> The following example
@@ -648,7 +636,7 @@ if(YukiHookAPI.Status.isTaiChiModuleActive) {
If you want to use both judgment schemes, `YukiHookAPI` also encapsulates a convenient way for you.
At this point, you can use `YukiHookAPI.Status.isModuleActive` to determine whether you are activated in Xposed or TaiChi and Promise.
At this point, you can use `YukiHookAPI.Status.isModuleActive` to determine whether you are activated in Xposed or TaiChi and Wuji.
> The following example
@@ -666,7 +654,7 @@ For more functions, please refer to [YukiHookAPI.Status](../api/public/com/highc
::: warning
If your Module App's API version is higher than 29 and is running on a system whose target API is 29 or higher, you need to add the following permission statement in **AndroidManifest.xml** to judge the activation status of the Module App in TaiChi and Wuji.
If your Module App's API version is higher than 29 and is running on a system whose target API is 29 or higher, you need to add the following permission statement in **AndroidManifest.xml** to judge the activation status of the module in TaiChi and Wuji.
> The following example
@@ -686,12 +674,44 @@ There is another solution, you can directly declare the **android.permission.QUE
<uses-permission android:name="android.permission.QUERY_ALL_PACKAGES" />
```
If the activation state of TaiChi and Wuji is included in the Module App activation judgment, the **Application** of the Module App must be extends **ModuleApplication** or **ModuleApplication** must be used directly;
If the activation status of TaiChi and Wuji is included in the Module App activation judgment, the **Application** of the Module App must be extends from **ModuleApplication** or directly use **ModuleApplication**.
The API after **1.0.91** has modified the activation logic judgment method, now you can use this API in the Module App and Host App at the same time;
:::
Need to make sure **YukiHookAPI.Configs.isEnableHookModuleStatus** is enabled;
### Get Hook Framework Information
Except for Hook Frameworks that provide standard APIs, Module Apps may not be able to determine whether they are activated in other cases.
In addition to judging your own activation status, you can also get information about the current Hook Framework through the `Executor` in `YukiHookAPI.Status`.
For example, we can use `YukiHookAPI.Status.Executor.name` to get the name of the current Hook Framework.
> The following example
```kotlin
val frameworkName = YukiHookAPI.Status.Executor.name
```
We can also use `YukiHookAPI.Status.Executor.apiLevel` to get the API Level of the current Hook Framework.
> The following example
```kotlin
val frameworkApiLevel = YukiHookAPI.Status.Executor.apiLevel
```
::: tip
For more functions, please refer to [YukiHookAPI.Status.Executor](../api/public/com/highcapable/yukihookapi/YukiHookAPI#executor-object).
:::
::: warning
**YukiHookAPI** after **1.0.91** version modifies the logical judgment method of obtaining the status of the Xposed Module, and now you can use this API in the Module App and Host App at the same time;
Need to make sure **InjectYukiHookWithXposed.isUsingXposedModuleStatus** is enabled;
**YukiHookAPI** only connects to the known acquisition methods.
Except for the Hook Framework that provides standard APIs, in other cases, the Xposed Module may not be able to determine whether it is activated or obtain information about the Hook Framework.
:::

View File

@@ -4,7 +4,7 @@
## Background
This is an efficient Hook API rebuilt based on the Xposed API using `Kotlin`, and creates rich function extensions for the development of Xposed Modules.
This is an efficient Hook API rebuilt based on the Xposed API using Kotlin, and creates rich function extensions for the development of Xposed Modules.
The name is taken from ["ももくり" heroine Yuki Kurihara](https://www.bilibili.com/bangumi/play/ss5016).
@@ -12,17 +12,17 @@ Formerly the Innocent Xposed API used in [Development Learning Project](https://
## Usage
`YukiHookAPI` is built entirely with `Kotlin` `lambda` syntax.
`YukiHookAPI` is built entirely with Kotlin **lambda** syntax.
Abandoning the original less friendly `XposedHelpers`, you can use it to easily create Xposed Modules and easily implement custom Hook API.
## Language Requirement
Please use `Kotlin`, the framework part of the code composition is also compatible with `Java` but the implementation of the basic Hook scene **may not work at all**.
Please use Kotlin, the framework part of the code composition is also compatible with Java but the implementation of the basic Hook scene **may not work at all**.
All demo code in this document will be described using `Kotlin`, if you don't know how to use `Kotlin` then you may not be able to use `YukiHookAPI`.
All demo code in this document will be described using Kotlin, if you don't know how to use Kotlin then you may not be able to use `YukiHookAPI`.
Part of the Java Demo code can be found [here](https://github.com/fankes/YukiHookAPI/tree/master/demo-module/src/main/java/com/highcapable/yukihookapi/demo_module/hook/java), but not recommended.
Part of the Java Demo code can be found [here](https://github.com/HighCapable/YukiHookAPI/tree/master/samples/demo-module/src/main/java/com/highcapable/yukihookapi/demo_module/hook/java), but not recommended.
## Source of Inspiration
@@ -30,7 +30,7 @@ Previously, when we built an Xposed Module, we first needed to create an `xposed
Then, manually fill in your own entry class name into the file and use `XposedHelpers` to implement our Hook logic.
Since `Kotlin` is the main Android development language, this API is really not very elegant to use.
Since Kotlin is the main Android development language, this API is really not very elegant to use.
Is there any **easy to use, light, elegant** solution?
@@ -38,7 +38,7 @@ With this idea, `YukiHookAPI` was born.
Now, we only need to write a small amount of code, and all the time and expense are handed over to automation.
With `Kotlin`'s elegant `lambda` writing and `YukiHookAPI`, you can make your Hook logic more beautiful and clear.
With Kotlin's elegant **lambda** writing and `YukiHookAPI`, you can make your Hook logic more beautiful and clear.
> The following example
@@ -47,56 +47,32 @@ With `Kotlin`'s elegant `lambda` writing and `YukiHookAPI`, you can make your Ho
```kotlin
@InjectYukiHookWithXposed
class HookEntry : IYukiHookXposedInit {
object HookEntry : IYukiHookXposedInit {
override fun onHook() = encase {
loadZygote {
ActivityClass.hook {
injectMember {
method {
name = "onCreate"
param(BundleClass)
}
beforeHook {
// Your code here.
}
afterHook {
// Your code here.
}
ActivityClass.method {
name = "onCreate"
param(BundleClass)
}.hook {
before {
// Your code here.
}
}
resources().hook {
injectResource {
conditions {
name = "sym_def_app_icon"
mipmap()
}
replaceToModuleResource(R.mipmap.ic_launcher)
after {
// Your code here.
}
}
}
loadApp(name = "com.android.browser") {
ActivityClass.hook {
injectMember {
method {
name = "onCreate"
param(BundleClass)
}
beforeHook {
// Your code here.
}
afterHook {
// Your code here.
}
ActivityClass.method {
name = "onCreate"
param(BundleClass)
}.hook {
before {
// Your code here.
}
}
resources().hook {
injectResource {
conditions {
name = "ic_launcher"
mipmap()
}
replaceToModuleResource(R.mipmap.ic_launcher)
after {
// Your code here.
}
}
}
@@ -105,19 +81,15 @@ class HookEntry : IYukiHookXposedInit {
```
:::
::: code-group-item Xposed API
::: code-group-item Rovo89 Xposed API
```kotlin
class HookEntry : IXposedHookZygoteInit, IXposedHookLoadPackage, IXposedHookInitPackageResources {
class HookEntry : IXposedHookZygoteInit, IXposedHookLoadPackage {
private lateinit var moduleResources: XModuleResources
override fun initZygote(sparam: IXposedHookZygoteInit.StartupParam) {
moduleResources = XModuleResources.createInstance(sparam.modulePath, null)
XResources.setSystemWideReplacement(
"android", "mipmap", "sym_def_app_icon",
moduleResources.fwd(R.mipmap.ic_launcher)
)
XposedHelpers.findAndHookMethod(
Activity::class.java.name,
null, "onCreate",
@@ -149,38 +121,12 @@ class HookEntry : IXposedHookZygoteInit, IXposedHookLoadPackage, IXposedHookInit
}
})
}
override fun handleInitPackageResources(resparam: XC_InitPackageResources.InitPackageResourcesParam) {
if (resparam.packageName == "com.android.browser")
resparam.res.setReplacement(
"com.android.browser", "mipmap", "ic_launcher",
moduleResources.fwd(R.mipmap.ic_launcher)
)
}
}
```
:::
::::
Yes, you read that right, just needing these codes can completely replace the Xposed API to achieve the same function.
Yes, you read that right, just needing these codes can completely replace the traditional Xposed API to achieve the same function.
Now, with the help of the efficient and powerful `YukiHookAPI`, you can implement a very simple Xposed Module.
## Suppored Hook Framework
The following are the `Hook Framework` and Xposed framework supported by `YukiHookAPI`.
| Hook Framework | ST | Description |
| --------------------------------------------------------- | --- | ----------------------------------------------------------------------------------------- |
| [LSPosed](https://github.com/LSPosed/LSPosed) | ✅ | Stable use in multiple scenarios |
| [LSPatch](https://github.com/LSPosed/LSPatch) | ⭕ | WIP after this project is improved |
| [EdXposed](https://github.com/ElderDrivers/EdXposed) | ❎ | Maintenance has stopped, no longer recommended |
| [Pine](https://github.com/canyie/pine) | ⭕ | Only available |
| [SandHook](https://github.com/asLody/SandHook) | ⭕ | Only available |
| [Whale](https://github.com/asLody/whale) | ⭕ | Need [xposed-hook-based-on-whale](https://github.com/WindySha/xposed-hook-based-on-whale) |
| [YAHFA](https://github.com/PAGalaxyLab/YAHFA) | ❗ | Need to implement the Xposed API yourself |
| [FastHook](https://github.com/turing-technician/FastHook) | ❗ | Need to implement the Xposed API yourself |
| [Epic](https://github.com/tiann/epic) | ❗ | Need [Dexposed](https://github.com/alibaba/dexposed) by yourself |
| [TaiChi](https://github.com/taichi-framework/TaiChi) | ⭕ | Only available for Xposed Module |
| [Xposed](https://github.com/rovo89/Xposed) | ⭕ | Recommended minimum system version is Android 7.0 |
Now, with the help of the efficient and powerful `YukiHookAPI`, you can implement a very simple Xposed Module.

View File

@@ -66,7 +66,7 @@ The Root-free frameworks mentioned above are [LSPatch](https://github.com/LSPose
### What YukiHookAPI does
Since Xposed appeared until now, apart from `XposedHelpers`, which is well known to developers, there is still no set of syntactic sugar for `Kotlin` and API with complete usage encapsulation.
Since Xposed appeared until now, apart from `XposedHelpers`, which is well known to developers, there is still no set of syntactic sugar for Kotlin and API with complete usage encapsulation.
The birth of this API framework is to hope that in the current era of Xposed, more capable Xposed Module developers can avoid detours and complete the entire development process more easily and simply.

View File

@@ -1,12 +1,16 @@
# Migrate from Xposed API
# Migrate from Other Hook APIs
> If you are familiar with Xposed API, you can refer to the same point below to quickly migrate your API to `YukiHookAPI`.
This document can help you quickly migrate from the Hook APIs you are familiar with to `YukiHookAPI` to become familiar with the related writing methods of `YukiHookAPI`.
## Migrate Hook Entry Point
## Rovo89 Xposed API
> If you are familiar with [Rovo89 Xposed API](https://api.xposed.info/), you can refer to the same point below to quickly migrate your API to `YukiHookAPI`.
### Migrate Hook Entry Point
> Migrated from `XC_LoadPackage.LoadPackageParam` to `PackageParam`.
`YukiHookAPI` implements the `lambda` method body `this` usage for `PackageParam`, and the `PackageParam` object can be obtained globally in the `encase` method body.
`YukiHookAPI` implements the **lambda** method body `this` usage for `PackageParam`, and the `PackageParam` object can be obtained globally in the `encase` method body.
> The API function differences are compared as follows
@@ -25,18 +29,16 @@ override fun onHook() = encase {
appContext
// Hook specified app
loadApp(name = "com.demo.test") {
// Class Hook
findClass("com.demo.test.TestClass").hook {
injectMember {
method {
name = "test"
param(BooleanType)
}
afterHook {
// Member Hook
"com.demo.test.TestClass".toClass()
.method {
name = "test"
param(BooleanType)
}.hook {
after {
// ...
}
}
}
// Resources Hook (fixed usage)
resources().hook {
injectResource {
@@ -52,7 +54,7 @@ override fun onHook() = encase {
```
:::
::: code-group-item Xposed API
::: code-group-item Rovo89 Xposed API
```kotlin
private lateinit var moduleResources: XModuleResources
@@ -67,7 +69,7 @@ override fun handleLoadPackage(lpparam: XC_LoadPackage.LoadPackageParam) {
// Get the ApplicationInfo of the current Hook
lpparam.applicationInfo
// Get the system context object
// There is no ready-made calling method in the native Xposed API, you need to reflect ActivityThread to achieve it
// There is no ready-made calling method in the Rovo89 Xposed API, you need to reflect ActivityThread to achieve it
// Get the host Application lifecycle
AndroidAppHelper.currentApplication()
// Class Hook
@@ -97,13 +99,13 @@ override fun handleInitPackageResources(resparam: XC_InitPackageResources.InitPa
:::
::::
## Migrate Hook Method Body
### Migrate Hook Method Body
> Migrated from `XC_MethodHook.MethodHookParam` to `HookParam`.
### Before/After Hook
#### Before/After Hook
`YukiHookAPI` also implements the `lambda` method body `this` usage for `HookParam`, and the `HookParam` object can be obtained globally in the method bodies such as `beforeHook` and `afterHook`.
`YukiHookAPI` also implements the **lambda** method body `this` usage for `HookParam`, and the `HookParam` object can be obtained globally in the method bodies such as `before` and `after`.
> The API function differences are compared as follows
@@ -111,7 +113,7 @@ override fun handleInitPackageResources(resparam: XC_InitPackageResources.InitPa
::: code-group-item Yuki Hook API
```kotlin
afterHook {
after {
// Get the current Hook instance
instance
// Get the Class instance of the current Hook
@@ -148,7 +150,7 @@ afterHook {
```
:::
::: code-group-item Xposed API
::: code-group-item Rovo89 Xposed API
```kotlin
override fun afterHookedMethod(param: MethodHookParam) {
@@ -188,7 +190,7 @@ override fun afterHookedMethod(param: MethodHookParam) {
:::
::::
### Replace Hook
#### Replace Hook
The `replaceHook` method is special, and the `YukiHookAPI` makes a variety of forms for it to choose from.
@@ -226,7 +228,7 @@ intercept()
```
:::
::: code-group-item Xposed API
::: code-group-item Rovo89 Xposed API
```kotlin
/// A method with no return value void
@@ -258,6 +260,6 @@ override fun replaceHookedMethod(param: MethodHookParam) = null
:::
::::
## Migrate Other Features
## Migrate More Functions Related to Hook API
`YukiHookAPI` is a complete rewrite of the Xposed API, you can refer to [API Document](../api/home) and [Special Features](../api/special-features/reflection) to determine some functional Migration and use.
`YukiHookAPI` is a brand new Hook API, which is fundamentally different from other Hook APIs, you can refer to [API Document](../api/home) and [Special Features](../api/special-features/reflection) to determine some functional Migration and use.

View File

@@ -16,7 +16,9 @@
- Gradle 7.0 and above
- JVM 11 and above (Since API `1.0.80`)
- Java 11 and above (Since API `1.0.80`)
- Java 17 and above (Since API `1.2.0`)
## Automatically Build Project
@@ -30,82 +32,205 @@ If you don't want to use automated build tools, you can still manually configure
### Create Project
Use `Android Studio` or `IntelliJ IDEA` to create a new Android project and select `Kotlin` in the `Language` column to automatically add basic dependencies.
Use `Android Studio` or `IntelliJ IDEA` to create a new Android project and select Kotlin in the `Language` column to automatically add basic dependencies.
### Integration Dependencies
Add dependencies to your project `build.gradle`.
We recommend using Kotlin DSL as the Gradle build script language and [SweetDependency](https://github.com/HighCapable/SweetDependency) to manage dependencies.
#### SweetDependency Method
Add the repositories and dependencies in your project's `SweetDependency` configuration file.
> The following example
```yaml
repositories:
# Must be added when used as an Xposed Module, otherwise optional
rovo89-xposed-api:
url: https://api.xposed.info/
# MavenCentral has a 2-hour cache,
# if the latest version cannot be integrated, please add this
sonatype-oss-releases:
plugins:
# Must be added when used as an Xposed Module, otherwise optional
com.google.devtools.ksp:
version: +
...
libraries:
# Must be added when used as an Xposed Module, otherwise optional
de.robv.android.xposed:
api:
version: 82
repositories:
rovo89-xposed-api
com.highcapable.yukihookapi:
api:
version: +
# Must be added when used as an Xposed Module, otherwise optional
ksp-xposed:
version-ref: <this>::api
...
```
After adding it, run Gradle Sync and all dependencies will be autowired.
Next, deploy plugins in your project `build.gradle.kts`.
> The following example
```kotlin
plugins {
// Must be added when used as an Xposed Module, otherwise optional
autowire(libs.plugins.com.google.devtools.ksp)
// ...
}
```
Then, deploy dependencies in your project `build.gradle.kts`.
> The following example
```kotlin
dependencies {
// Basic dependencies
implementation(com.highcapable.yukihookapi.api)
// Must be added when used as an Xposed Module, otherwise optional
compileOnly(de.robv.android.xposed.api)
// Must be added when used as an Xposed Module, otherwise optional
ksp(com.highcapable.yukihookapi.ksp.xposed)
}
```
#### Traditional Method (Not Recommended)
Add repositories in your project `build.gradle.kts` or `build.gradle`.
> Kotlin DSL
```kotlin
repositories {
google()
mavenCentral()
// Must be added when used as an Xposed Module, otherwise optional
maven { url("https://api.xposed.info/") }
// MavenCentral has a 2-hour cache, if the latest version cannot be integrated, please add this URL
maven { url("https://s01.oss.sonatype.org/content/repositories/releases/") }
}
```
> Groovy DSL
```groovy
repositories {
google()
mavenCentral()
// ❗If your Plugin version is too low, be sure to add it as an Xposed Module, other cases are optional
maven { url "https://dl.bintray.com/kotlin/kotlin-eap" }
// ❗Be sure to add it as an Xposed Module, optional in other cases
maven { url "https://api.xposed.info/" }
// MavenCentral has a 2-hour cache, if you cannot integrate the latest version, please add this address
maven { url "https://s01.oss.sonatype.org/content/repositories/releases" }
// Must be added when used as an Xposed Module, otherwise optional
maven { url 'https://api.xposed.info/' }
// MavenCentral has a 2-hour cache, if the latest version cannot be integrated, please add this URL
maven { url 'https://s01.oss.sonatype.org/content/repositories/releases/' }
}
```
Add `plugin` to your app `build.gradle`.
Add plugins in your project `build.gradle.kts` or `build.gradle`.
> The following example
> Kotlin DSL
```kotlin
plugins {
// Must be added when used as an Xposed Module, otherwise optional
id("com.google.devtools.ksp") version "<ksp-version>"
}
```
> Groovy DSL
```groovy
plugins {
// ❗Be sure to add it as an Xposed Module, optional in other cases
// Must be added when used as an Xposed Module, otherwise optional
id 'com.google.devtools.ksp' version '<ksp-version>'
}
```
Add dependencies to your app `build.gradle`.
Add dependencies in your project `build.gradle.kts` or `build.gradle`.
> The following example
> Kotlin DSL
```kotlin
dependencies {
// Basic dependency
implementation("com.highcapable.yukihookapi:api:<yuki-version>")
// Must be added when used as an Xposed Module, otherwise optional
compileOnly("de.robv.android.xposed:api:82")
// Must be added when used as an Xposed Module, otherwise optional
ksp("com.highcapable.yukihookapi:ksp-xposed:<yuki-version>")
}
```
> Groovy DSL
```groovy
dependencies {
// base dependencies
// Basic dependency
implementation 'com.highcapable.yukihookapi:api:<yuki-version>'
// ❗Be sure to add it as an Xposed Module, optional in other cases
// Must be added when used as an Xposed Module, otherwise optional
compileOnly 'de.robv.android.xposed:api:82'
// ❗Be sure to add it as an Xposed Module, optional in other cases
// Must be added when used as an Xposed Module, otherwise optional
ksp 'com.highcapable.yukihookapi:ksp-xposed:<yuki-version>'
}
```
Please modify **&lt;ksp-version&gt;** to the latest version from [here](https://github.com/google/ksp/releases) **(Please choose your current corresponding Kotlin version)**.
Please modify **&lt;ksp-version&gt;** to the latest version found [here](https://github.com/google/ksp/releases) **(please note to select your current corresponding Kotlin version)**.
Please modify **&lt;yuki-version&gt;** to the latest version [here](../about/changelog).
Please change **&lt;yuki-version&gt;** to the latest version [here](../about/changelog).
::: danger
:::danger
The **api** of **YukiHookAPI** and the versions that **ksp-xposed** depend on must correspond one by one, otherwise a version mismatch error will occur.
The **api** and **ksp-xposed** dependency versions of **YukiHookAPI** must correspond one-to-one, otherwise a version mismatch error will occur.
We recommend using [SweetDependency](https://github.com/HighCapable/SweetDependency) to autowire dependencies for you.
:::
Modify the JVM version of `Kotlin` to 11 and above in your app `build.gradle`.
#### Configure Java Version
> The following example
Modify the Java version of Kotlin in your project `build.gradle.kts` or `build.gradle` to 17 or above.
> Kotlin DSL
```kt
android {
compileOptions {
sourceCompatibility = JavaVersion.VERSION_17
targetCompatibility = JavaVersion.VERSION_17
}
kotlinOptions {
jvmTarget = "17"
}
}
```
> Groovy DSL
```groovy
android {
compileOptions {
sourceCompatibility JavaVersion.VERSION_11
targetCompatibility JavaVersion.VERSION_11
sourceCompatibility JavaVersion.VERSION_17
targetCompatibility JavaVersion.VERSION_17
}
kotlinOptions {
jvmTarget = '11'
jvmTarget = '17'
}
}
```
::: warning
Since API **1.0.80** version, the default JVM version is 11, and 1.8 and below are no longer supported.
Since API **1.0.80**, the Java version used by Kotlin defaults to 11, and versions 1.8 and below are no longer supported.
Since API **1.2.0**, the Java version used by Kotlin defaults to 17, and versions 11 and below are no longer supported.
:::
@@ -121,7 +246,7 @@ Add the base code to your `AndroidManifest.xml`.
android:name="xposedmodule"
android:value="true" />
<!-- Set your module description -->
<!-- Set your Xposed Module description -->
<meta-data
android:name="xposeddescription"
android:value="Fill in your Xposed Module description" />
@@ -178,7 +303,7 @@ Then, you can start writing Hook code.
For configuration details related to use as an Xposed Module, you can [click here](../config/xposed-using) to continue reading.
If you are currently using Xposed API, you can refer to [Migrate from Xposed API](../guide/move-to-new-api).
If you are currently using Hook APIs such as Rovo89 Xposed API, you can refer to [Migrate from Other Hook APIs](../guide/move-to-new-api).
### Use as Hook API
@@ -190,7 +315,7 @@ Create your custom `Application`.
Regardless of the **Hook Framework** you use, you need to add its docking Xposed dependency support.
If the target **Hook Framework** does not integrate Xposed API, you need to implement and connect **XposedBridge** by yourself.
If the target **Hook Framework** does not integrate Rovo89 Xposed API, you need to implement and connect **XposedBridge** by yourself.
:::
@@ -218,6 +343,6 @@ For configuration details related to use as a Hook API, you can [click here](../
::: warning
**YukiHookModuleStatus**, **YukiHookModulePrefs**, **YukiHookDataChannel** and Resources Hook functionality will not work when using a custom Hook Framework instead of the full Xposed Module.
**YukiHookPrefsBridge**, **YukiHookDataChannel** and Resources Hook functionality will not work when using a custom Hook Framework instead of the full Xposed Module.
:::

View File

@@ -0,0 +1,52 @@
# Supportive
The following are the related functions, Xposed Frameworks, Hook Frameworks and Hook APIs supported by `YukiHookAPI`.
> Basic Functions
| Name | ST | Description |
| -------------------------- | --- | ------------------------------------------------------------------------------------------------------------------ |
| Xposed Module Auto Builder | ✅ | Will use [New Xposed Module Config Plan](https://github.com/HighCapable/YukiHookAPI/issues/49) on `YukiHookAPI` `2.0.0` |
| ART Dynamic Method Hook | ✅ | Stable use in multiple scenarios |
| Xposed Resources Hook | ❗ | Supported, but will be deprecated on `YukiHookAPI` `2.0.0` |
> Extended Functions
| Name | ST | Description |
| -------------------------------------------------------------------------------------------------- | --- | ------------------------------------------------------------------------------------------------------ |
| [Reflection Extensions](../api/special-features/reflection) | ⭕ | Will be merge into [YukiReflection](https://github.com/HighCapable/YukiReflection) on `YukiHookAPI` `2.0.0` |
| [Xposed Module Data Storage](../api/special-features/xposed-storage) | ✅ | Normal use |
| [Xposed Module and Host Channel](../api/special-features/xposed-channel) | ✅ | Normal use |
| [Host Lifecycle Extension](../api/special-features/host-lifecycle) | ✅ | Normal use |
| [Inject Module Apps Resources](../api/special-features/host-inject#inject-module-apps-resources) | ✅ | Normal use |
| [Register Module Apps Activity](../api/special-features/host-inject#register-module-apps-activity) | ✅ | Normal use |
> Xposed Frameworks
| Name | ST | Description |
| ---------------------------------------------------- | --- | --------------------------------------------------------------------------- |
| [LSPosed](https://github.com/LSPosed/LSPosed) | ✅ | Stable use in multiple scenarios |
| [LSPatch](https://github.com/LSPosed/LSPatch) | ⭕ | Support, API support will be gradually added after the project is completed |
| [EdXposed](https://github.com/ElderDrivers/EdXposed) | ❎ | Maintenance has stopped and is no longer recommended |
| [Dreamland](https://github.com/canyie/Dreamland) | ⭕ | Theoretical support (not tested by developer) |
| [TaiChi](https://github.com/taichi-framework/TaiChi) | ⭕ | Hook functions normally (some functions have restrictions) |
| [Xposed](https://github.com/rovo89/Xposed) | ❎ | Maintenance has stopped and is no longer recommended |
> Hook Frameworks
| Name | ST | Description |
| --------------------------------------------------------- | --- | -------------------------------------------------------------------------------------------- |
| [LSPlant](https://github.com/LSPosed/LSPlant) | ⭕ | Please visit [AliuHook](https://github.com/Aliucord/hook) |
| [Pine](https://github.com/canyie/pine) | ⭕ | Theoretical support (not tested by developer) |
| [SandHook](https://github.com/asLody/SandHook) | ❎ | The latests Android are not supported, you need to integrated the Rovo89 Xposed API yourself |
| [Whale](https://github.com/asLody/whale) | ❎ | The latests Android are not supported, you need to integrated the Rovo89 Xposed API yourself |
| [YAHFA](https://github.com/PAGalaxyLab/YAHFA) | ❎ | The latests Android are not supported, you need to integrated the Rovo89 Xposed API yourself |
| [FastHook](https://github.com/turing-technician/FastHook) | ❎ | Maintenance has stopped and is no longer recommended |
| [Epic](https://github.com/tiann/epic) | ❎ | Maintenance has stopped and is no longer recommended |
> Hook APIs
| Name | ST | Description |
| ------------------------------------------------- | --- | ------------------------------------------ |
| [Rovo89 Xposed API](https://api.xposed.info/) | ✅ | Stable use in multiple scenarios |
| [Modern Xposed API](https://github.com/libxposed) | ❎ | Will be supported on `YukiHookAPI` `2.0.0` |

View File

@@ -11,45 +11,33 @@ actions:
type: secondary
features:
- title: Xposed Module Develop
details: The automatic builder can help you quickly create an Xposed Module, automatic configure the entry class and xposed_init file.
details: The automatic builder can help you quickly create an Xposed Module, automatic configure the entry class and xposed_init files.
- title: Light and Elegant
details: A powerful, elegant, beautiful API built with Kotlin lambda can help you quickly implement members search and methods hooks.
details: A powerful, elegant, beautiful API built with Kotlin lambda can help you quickly implement method Hook and more convenient functions.
- title: Debugging Efficient
details: A rich debug log function, detailing the name of each hooked method, time-consuming to find the class can quickly debug and find errors.
- title: Easy to transplant
details: Native support for Xposed API usage, in any case, the supported Hook Framework with Xposed API can be quickly spliced with it.
- title: Easy to Transplant
details: Natively supports multiple Xposed API usages and natively connects to multiple Xposed APIs, Hook Frameworks within the supported range can be quickly integrated.
- title: Obfuscate Support
details: The built Xposed Module simply supports R8, obfuscate will not destroy the hook entry point, and no other configuration is required under R8.
- title: Quickly Started
details: Simple and easy to use it now! Do not need complex configuration and full development experience, Integrate dependencies and enjoy yourself.
footer: MIT License | Copyright (C) 2019-2023 HighCapable
footer: Apache-2.0 License | Copyright (C) 2019-2023 HighCapable
---
### All Hook process in one step, everything is simplified
```kotlin
loadApp(name = "com.android.browser") {
ActivityClass.hook {
injectMember {
method {
name = "onCreate"
param(BundleClass)
}
beforeHook {
// Your code here.
}
afterHook {
// Your code here.
}
ActivityClass.method {
name = "onCreate"
param(BundleClass)
}.hook {
before {
// Your code here.
}
}
resources().hook {
injectResource {
conditions {
name = "ic_launcher"
mipmap()
}
replaceToModuleResource(R.mipmap.ic_launcher)
after {
// Your code here.
}
}
}

View File

@@ -12,9 +12,9 @@ This project is open source and free, and will be maintained continuously accord
The original version may have imperfections or bugs. We welcome to your feedback.
Project Address [YukiHookAPI-ProjectBuilder](https://github.com/fankes/YukiHookAPI-ProjectBuilder)。
Project Address [YukiHookAPI-ProjectBuilder](https://github.com/HighCapable/YukiHookAPI-ProjectBuilder)。
If you want to download directly, you can [click here](https://github.com/fankes/YukiHookAPI-ProjectBuilder/releases) to go to the Release address.
If you want to download directly, you can [click here](https://github.com/HighCapable/YukiHookAPI-ProjectBuilder/releases) to go to the Release address.
## Usage

View File

@@ -13,5 +13,5 @@ actions:
- text: 简体中文
link: /zh-cn/
type: secondary
footer: MIT License | Copyright (C) 2019-2023 HighCapable
footer: Apache-2.0 License | Copyright (C) 2019-2023 HighCapable
---

View File

@@ -4,30 +4,24 @@
## License
[The MIT License (MIT)](https://github.com/fankes/YukiHookAPI/blob/master/LICENSE)
[Apache-2.0](https://github.com/HighCapable/YukiHookAPI/blob/master/LICENSE)
```:no-line-numbers
MIT License
Apache License Version 2.0
Copyright (C) 2019-2023 HighCapable
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
https://www.apache.org/licenses/LICENSE-2.0
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
```
版权所有 © 2019-2023 HighCapable

View File

@@ -8,7 +8,99 @@
:::
### 1.1.5 | 2023.01.13 &ensp;<Badge type="tip" text="最新" vertical="middle" />
### 1.2.0 | 2023.10.07 &ensp;<Badge type="tip" text="最新" vertical="middle" />
- 许可协议由 `MIT` 变更为 `Apache-2.0`,在此之后的版本将由此许可协议进行分发,您在使用此版本后应变更相关许可协议
- 这是一次重大更新,详情请参考 [迁移到 YukiHookAPI 1.2.x](https://highcapable.github.io/YukiHookAPI/zh-cn/config/move-to-api-1-2-x)
- 适配 Android 14感谢 [BlueCat300](https://github.com/BlueCat300) 的 [PR](https://github.com/HighCapable/YukiHookAPI/pull/44)
- 修复 `findAllInterfaces` 相关问题,感谢 [buffcow](https://github.com/buffcow) 的 [PR](https://github.com/HighCapable/YukiHookAPI/pull/38)
- 修复 Hook 过程中的延迟回调问题,感谢 [cesaryuan](https://github.com/cesaryuan) 的 [Issue](https://github.com/HighCapable/YukiHookAPI/issues/47)
- 新增 Resources Hook 相关功能支持,详情请参考这个 [Issue](https://github.com/HighCapable/YukiHookAPI/issues/36)
- 新增 `YukiHookAPI.TAG`
- 作废了 ~~`YukiHookAPI.API_VERSION_NAME`~~、~~`YukiHookAPI.API_VERSION_CODE`~~,统一合并到 `YukiHookAPI.VERSION`
- 作废了 `YukiMemberHookCreator` 中的 `useDangerousOperation` 方法
- 作废了 `YukiMemberHookCreator` 中的 `instanceClass` 功能,不再推荐使用
- 修改 `HookParam` 中的 `instanceClass` 为空安全返回值类型
- 分离全部使用 `injectMember` 创建的 Hook 对象到 `LegacyCreator`
- 修改 `PackageParam` 中的 `appClassLoader` 为空安全返回值类型
- 重构全部 `logger...` 方法到新用法 `YLog`
- 移除了打印日志功能后方的 `-->` 样式
- 修复并改进在使用 `namespace` 后通过 KSP 无法获取模块包名的问题
- 是否启用模块激活状态等功能现已移动到 `InjectYukiHookWithXposed` 注解中
- 分离 [FreeReflection](https://github.com/tiann/FreeReflection) 不再自动生成,将作为依赖自动导入
- 新增重复 Hook 同一个方法时将自动打印警告日志
- 作废了 `PackageParam` 中的 `findClass(...)` 方法,请迁移到 `"...".toClass()` 方法
- 作废了 `PackageParam` 中的 `String.hook { ... }` 方法,推荐使用新方式进行 Hook
- `AppLifecycle` 现在可以在不同 Hooker 中重复创建
- 作废了旧版 Hook 优先级写法,统一迁移到 `YukiHookPriority`
- 移除了 Hook 过程中的 `tag` 功能
- 重构方法查找中的 `remendy` 功能,现在可以对其进行分步打印异常
- 多重方法查找结果类型由 `HashSet` 改为 `MutableList`
- 新增使用 `method()``constructor()``field()` 可直接获取到类中的所有对象功能
- `constructor()` 的行为不再是 `constructor { emptyParam() }`
- 新增 `lazyClass``lazyClassOrNull` 方法,可延迟装载 `Class`
### 1.1.11 | 2023.04.25 &ensp;<Badge type="warning" text="过旧" vertical="middle" />
- 修复从 `1.1.5` 版本开始的一个严重问题,`Member` 缓存未生效且持续存储最终引发 APP 内存溢出 (OOM),感谢 [Art-Chen](https://github.com/Art-Chen)
- 移除 `Member` 的直接缓存功能并作废 ~~`YukiHookAPI.Configs.isEnableMemberCache`~~,保留 `Class` 的缓存功能
- 对接查找功能到 `Sequence`,优化 `Member` 的查找速度与性能
- 移除 `YukiHookPrefsBridge` 的直接键值缓存功能并移除 `LruCache` 相关功能
- 作废了 ~~`YukiHookAPI.Configs.isEnablePrefsBridgeCache`~~
- 作废了 `YukiHookPrefsBridge` 中的 ~~`direct`~~、~~`clearCache`~~ 方法
### 1.1.10 | 2023.04.21 &ensp;<Badge type="warning" text="过旧" vertical="middle" />
- `Activity` 代理功能新增每个被代理的 `Activity` 指定单独的代理 `Activity` 功能
- 修复 `YukiHookPrefsBridge` 中的 `contains``all` 方法未判断 `native` 功能的问题
- 整合 `YukiHookPrefsBridge` 中的缓存功能到 `PreferencesCacheManager` 并使用 `LruCache` 作为键值对前置缓存
- 修改 `YukiHookPrefsBridge` 键值对缓存功能在所有环境中生效 (模块、宿主)
- 修改部分用于缓存的 `HashMap``ArrayMap` 以减少内存消耗
- 修复一些其它可能出现的问题
### 1.1.9 | 2023.04.17 &ensp;<Badge type="warning" text="过旧" vertical="middle" />
- 将依赖库的类型由 **Java Library** (jar) 修改为 **Android Library** (aar)
- 移除通过 Hook 或反射 API 内部方法、参数的检查功能
- 修复 `YukiHookDataChannel` 自动分段发送数据功能不能正常生效 (依然会抛出异常) 的问题
- 新增可以手动根据目标设备的限制修改 `YukiHookDataChannel` 允许一次发送的最大数据字节大小
- 移除 `YukiHookDataChannel` 只能在模块 `Activity` 中使用的限制,现在你可以在任何地方使用它
- 修改并规范 `YukiHookDataChannel` 使用的广播 Action 名称
- 修复 `YukiHookDataChannel` 在不同模块同一宿主的情况下出现 `BadParcelableException` 异常的问题
- 新增 `ExecutorType`,可以通过 `YukiHookAPI.Status.Executor.type` 来获取已知 Hook Framework 的类型
- ~~`YukiHookModulePrefs`~~ 更名为 `YukiHookPrefsBridge`
- 修改 `YukiHookPrefsBridge` 为非单例实现,作为单例可能发生数据混淆的问题
- 作废了 ~~`Context.modulePrefs(...)`~~ 方法,请迁移到 `Context.prefs(...)`
- `YukiHookPrefsBridge` 新增 `native` 方法,支持直接作为原生存储在模块和宿主中存储私有数据
- 整合 `YukiHookPrefsBridge` 中的存储方法到 `YukiHookPrefsBridge.Editor`,请使用 `edit` 方法来存储数据
- `YukiHookPrefsBridge` 新增 `contains` 方法
- 缓存 `YukiHookPrefsBridge` 中动态创建的代理对象,尝试修复可能会导致宿主、模块出现 OOM 的问题
- 修改 `Activity` 代理功能的代理类为动态生成,防止不同模块注入宿主后造成冲突
- 修复一些其它可能出现的问题
### 1.1.8 | 2023.02.01 &ensp;<Badge type="warning" text="过旧" vertical="middle" />
- 修复底层 Hook 方法在回调时修改 `result` 等参数时时不能同步更新修改后的状态问题,感谢 [Yongzheng Lai](https://github.com/elvizlai) 的 [Issue](https://github.com/HighCapable/YukiHookAPI/issues/23)
- 移动 `YukiHookAPI` 自动生成的入口类名称文件 `assets/yukihookapi_init``resources/META-INF/yukihookapi_init`
- 允许在仅打印异常堆栈时 `msg` 参数为空并可以不设置 `msg` 参数,留空 `msg` 参数的日志除非异常堆栈不为空否则将不会被记录
- 修复 Hook 回调方法体内发生的异常打印的日志无具体方法信息的 BUG
- `HookParam` 新增 `instanceOrNull` 变量与方法,可以在不确定 Hook 实例是否为空的前提下使用以防止 Hook 实例为空抛出异常
- 解耦合所有 `Member` 查找功能中的 Hooker 到 `MemberBaseFinder.MemberHookerManager`
- 修改了 `YukiMemberHookCreator` 中的 `by` 条件用法,现在可以重复使用 `by` 方法设置多个条件
- 移除了 Android `type` 中的错误 `Class` 对象声明
- `PackageParam.AppLifecycle` 中的 `registerReceiver` 方法新增直接使用 `IntentFilter` 创建系统广播监听的功能
- 修复在 `PackageParam.AppLifecycle` 中可能存在多次注册生命周期的问题
- Revert: 1.1.7 版本由于有一个严重问题已经撤回,请直接更新到此版本即可 (更新日志同 1.1.7 版本)
### 1.1.6 | 2023.01.21 &ensp;<Badge type="warning" text="过旧" vertical="middle" />
- 修复 Xposed 模块装载时可能存在同一个进程多个包名的情况导致 `PackageParam` 保持单例后 `ClassLoader` 不符的严重问题
- 新增同一个进程多个包名的情况下未区分包名时,停止装载单例化的子 Hooker 并打印警告信息
- 修复 `HookParam.callOriginal``HookParam.invokeOriginal` 等方法调用原始方法时参数个数不正确的问题
- 修改 `MethodFinder``ConstructorFinder``ReflectionFactory` 中反射调用的方法参数名 `param``args`
- 新增 Xposed 模块自动处理程序中判断入口类构造方法参数功能,入口类需要保证其不存在任何构造方法参数
### 1.1.5 | 2023.01.13 &ensp;<Badge type="warning" text="过旧" vertical="middle" />
- 规范并优化整体代码风格
- 对部分内部调用的 API 进行了私有化处理
@@ -28,7 +120,7 @@
- 修复一个 Hook 过程中方法返回值的对象是目标的继承类和接口时被识别为返回值不符的严重错误
- 修复在当前 Hook 的实例对象是静态的情况下调用 `HookParam.callOriginal``HookParam.invokeOriginal` 出现对象为空问题
- 优化对太极激活方法相关判断功能以及同步更新文档相关说明
- 作废了 ~~`YukiHookAPI.Status.executorName`~~、~~`YukiHookAPI.Status.executorVersion`~~,请移到 `YukiHookAPI.Status.Executor`
- 作废了 ~~`YukiHookAPI.Status.executorName`~~、~~`YukiHookAPI.Status.executorVersion`~~,请移到 `YukiHookAPI.Status.Executor`
- 适配了一些第三方 Hook Framework 的 `YukiHookAPI.Status.Executor.name` 名称显示功能
- 新增 `Class.extends``Class.implements` 等方法,可更加方便地判断当前 `Class` 的继承与接口关系
- 新增 `Class.toClass``Class.toClassOrNull` 等相关方法的同名泛型方法,可使用泛型来约束已知 `Class` 的实例对象类型
@@ -105,7 +197,7 @@
- 新增 `generic` 功能,可对泛型进行反射和调用,你可以在 `Class``CurrentClass` 中使用它
- 作废 `buildOfAny` 方法,现在请直接使用 `buildOf` 方法 (不带泛型) 来使用构造方法创建新对象并得到结果 `Any`
- 修复 `hasExtends` 使用过程发生空指针异常的问题
- `CurrentClass` 新增非 `lambda` 方式的调用方法
- `CurrentClass` 新增非 **lambda** 方式的调用方法
- `CurrentClass` 新增 `name``simpleName` 功能
- 完全重写 `ReflectionTool` 的核心方法,将不同的查找条件进行了整理分类
- 修复 `ReflectionTool` 中可能的直接调用 `declared` 获取的 `Member` 抛出异常的问题
@@ -121,7 +213,7 @@
- 新增反射查找中的多重查找功能,可使用相对查找条件同时获取多个查找结果,感谢 **AA** 以及 [Kitsune](https://github.com/KyuubiRan) 的建议
- 修复 `appClassLoader` 获取到的对象在某些系统中的系统应用中不正确的问题,感谢 [Luckyzyx](https://github.com/luckyzyx) 的反馈
- 修改了 `XposedBridge.invokeOriginalMethod` 的调用方式并在 `MethodFinder.Result.Instance` 中增加 `original` 功能
- 修复 `YukiHookModulePrefs``getStringSet` 方法取值错误的问题并优化代码风格,感谢 [Teddy_Zhu](https://github.com/Teddy-Zhu) 的 [PR](https://github.com/fankes/YukiHookAPI/pull/19)
- 修复 `YukiHookModulePrefs``getStringSet` 方法取值错误的问题并优化代码风格,感谢 [Teddy_Zhu](https://github.com/Teddy-Zhu) 的 [PR](https://github.com/HighCapable/YukiHookAPI/pull/19)
- 修改 `YukiHookModulePrefs`,拦截 `XSharePreference` 可能不存在的异常
- 修复 `YukiHookDataChannel` 在某些第三方 ROM 系统框架中无法注册成功的问题
- 安全化 `YukiHookDataChannel`,现在它只能在来自指定包名的模块与宿主之间通信
@@ -133,7 +225,7 @@
- 新增模块资源注入与 `Activity` 代理功能,你可以调用 `injectModuleAppResources``registerModuleAppActivities` 来使用
- 新增 `ModuleContextThemeWrapper` 功能,你可以调用 `applyModuleTheme` 在任意 `Activity` 中创建模块的 `Context`
- 新增 `ClassLoader.onLoadClass` 功能,可用于监听 `ClassLoader``loadClass` 方法被调用的事件
- 作废了 `classOf``clazz` 扩展方法,新增 `toClass` 以及 `toClassOrNull` 用法,请现在移到新的方法
- 作废了 `classOf``clazz` 扩展方法,新增 `toClass` 以及 `toClassOrNull` 用法,请现在移到新的方法
- `VariousClass` 新增 `getOrNull` 方法,可在匹配不到 `Class` 的时候不抛出异常而是返回 `null`
- `PackageParam.hook` 中移除了 `isUseAppClassLoader` 参数,修改为 `isForceUseAbsolute` 并自动匹配目标 `Class`
- `PackageParam` 新增 `systemContext` 功能,你可以在任意时间调用此功能获取一个持久化的 `Context`
@@ -144,7 +236,7 @@
- Hook 过程中新增解除 Hook 功能,可使用 `remove``removeSelf` 方法解除 Hook
- 修复在 ReplaceHook 失败的时候导致宿主抛出异常的问题,现修改为调用原始方法保证宿主功能正常运行
- 新增 Hook 过程中对方法返回值的检查功能,在返回值不匹配的情况下会根据情景自动抛出异常或打印错误
- Resources Hook 中新增 `array` 类型,感谢 [GSWXXN](https://github.com/GSWXXN) 的 [PR](https://github.com/fankes/YukiHookAPI/pull/12)
- Resources Hook 中新增 `array` 类型,感谢 [GSWXXN](https://github.com/GSWXXN) 的 [PR](https://github.com/HighCapable/YukiHookAPI/pull/12)
- 移动 `me.weishu.reflection``thirdparty` 防止同时引入的同名依赖冲突
- 移除 Hook 方法体为空时抛出的异常,修改为打印警告日志
- 修改 `AppLifecycle` 的异常处理逻辑,当其发生异常时直接抛给宿主
@@ -234,7 +326,7 @@
- ~~`YukiHookXposedInitProxy`~~ 更名为 `IYukiHookXposedInit`,原接口名称已作废,将在后续版本中直接被删除
- 新增 `initZygote` 与 Resources Hook 功能,支持 Hook Layout
- 新增 `onXposedEvent` 方法,可监听原生 Xposed API 的全部事件
- 对 Hook 功能的 `lambda` 进行 `inline` 处理,避免生成过碎的匿名类,提升编译后的运行性能
- 对 Hook 功能的 **lambda** 进行 `inline` 处理,避免生成过碎的匿名类,提升编译后的运行性能
- 修复 `PrefsData` 编译后的方法体复制过大的问题
- 增加 `XSharePreference` 可读性测试,失败后会自动打印警告日志
- `PackageParam` 新增 `appResources``moduleAppResources``moduleAppFilePath` 功能
@@ -262,7 +354,7 @@
- 修复 `YukiHookModulePrefs``New XSharePreference` 模式下工作的部分问题
- 新增 `ModulePreferenceFragment`,现在,你可以完全替换掉 `PreferenceFragmentCompat` 并开始使用新的功能
- 适配 `PreferenceFragmentCompat` 的 Sp 数据存储解决方案,感谢 [mahoshojoHCG](https://github.com/mahoshojoHCG) 的反馈
- 更新自动处理程序以及 `Kotlin` 依赖到最新版本
- 更新自动处理程序以及 Kotlin 依赖到最新版本
- 修正部分文档和代码注释中的错误
### 1.0.77 | 2022.04.15 &ensp;<Badge type="danger" text="过期" vertical="middle" />
@@ -353,7 +445,7 @@
- 增加 `MethodFinder``FieldFinder` 新的返回值调用方法
- 修复可能存在的问题,并修复太极使用过程中可能存在的问题
- 修复自动生成 Xposed 入口类可能发生的问题
- 增加了 `type` 中的 `android` 类型以及 `java` 类型
- 增加了 `type` 中的 `android` 类型以及 Java 类型
### 1.0.6 | 2022.03.20 &ensp;<Badge type="danger" text="过期" vertical="middle" />
@@ -370,7 +462,7 @@
- 修正一处注释错误
- 临时修复一个 BUG
- 增加了 `type` 中的大量 `android` 类型以及少量 `java` 类型
- 增加了 `type` 中的大量 `android` 类型以及少量 Java 类型
- 修复新版与旧版 Kotlin APIs 的兼容性问题
### 1.0.5 | 2022.03.18 &ensp;<Badge type="danger" text="过期" vertical="middle" />
@@ -406,7 +498,7 @@
- `RemedyPlan` 增加 `onFind` 功能
- 整合并修改了部分反射 API 代码
- 增加了 `type` 中的 `java` 类型
- 增加了 `type` 中的 Java 类型
- 修复忽略错误在控制台仍然输出的问题
### 1.0 | 2022.02.14 &ensp;<Badge type="danger" text="过期" vertical="middle" />

View File

@@ -2,10 +2,10 @@
> 如在使用中有任何问题,或有任何建设性的建议,都可以联系我们。
加入我们 [点击加入 Telegram 群组](https://t.me/YukiHookAPI)
加入我们 [点击加入 Telegram 群组](https://t.me/YukiHookAPI)、[点击加入 Telegram 群组 (开发者)](https://t.me/HighCapable_Dev)。
**酷安** 找到我 [@星夜不荟](http://www.coolapk.com/u/876977)
**酷安** 找到我 [@星夜不荟](http://www.coolapk.com/u/876977)
## 助力维护
感谢您选择并使用 `YukiHookAPI`,如有代码相关的建议和请求,可在 Github 提交 Pull Request。
感谢您选择并使用 `YukiHookAPI`,如有代码相关的建议和请求,可在 GitHub 提交 Pull Request。

View File

@@ -6,7 +6,7 @@
> 这里收录了 `YukiHookAPI` 尚未解决的问题。
### YukiHookModulePrefs
### YukiHookPrefsBridge
目前仅限完美支持 LSPosed其它 Xposed 框架需要降级模块 API。
@@ -16,12 +16,26 @@
后期 Android 系统的权限将越来越严格,`selinux` 就是目前面临的一个大问题,有待讨论和研究。
::: tip 2023.10.06 更新
LSPosed 现已实验性推出了 [Modern Xposed API](https://github.com/libxposed),它采用 Service 的方式与模块通信,这将能够解决模块数据存储的问题。
为了保证大部分模块的兼容性,后期 **YukiHookAPI** 计划使用自定义的 ContentProvider 实现模块与宿主的数据互通,敬请期待。
:::
## 未来的计划
> 这里收录了 `YukiHookAPI` 可能会在后期添加的功能。
### 支持独立使用的 Lite 版本
如果你喜欢 `YukiHookAPI` 的反射 API但你的项目可能并不需要相关 Hook 功能。
那么这里有一个好消息要告诉你:
`YukiHookAPI` 的核心反射 API 已被解耦合为 [YukiReflection](https://github.com/HighCapable/YukiReflection) 项目,它现在能在任何 Android 项目中使用。
::: tip 待讨论
目前 API 只支持通过自动处理程序绑定到 **xposed_init**,若您不喜欢自动处理程序,一定要自己实现模块装载入口,未来会按照需求人数推出仅有 API 功能的 Lite 版本,你可向我们提出 **issues**
@@ -30,8 +44,12 @@
API 已经提供了 Xposed 原生 API 监听接口,你可以 [在这里](../config/xposed-using#原生-xposed-api-事件) 找到或查看 Demo 的实现方法。
### 支持更多 Hook Framework
### 里程碑计划
作为 API 来讲,目前仅仅对接 `XposedBridge` 作为兼容层,还是有一定的局限性
下方这些计划已在 GitHub 的 `issues` 中发布,你可以查看每个项目的进度
大部分 `inline hook` 没有 `Java` 兼容层,后期可能会考虑 `native hook``Java` 兼容层适配
所有功能预计在 `2.0.0` 版本完成,敬请期待
- [New Xposed Module Config Plan](https://github.com/HighCapable/YukiHookAPI/issues/49)
- [New Hook Entry Class](https://github.com/HighCapable/YukiHookAPI/issues/48)
- [New Hook Code Style](https://github.com/HighCapable/YukiHookAPI/issues/33)

View File

@@ -16,33 +16,53 @@ object YukiHookAPI
> 这是 `YukiHookAPI` 的 API 调用总类Hook 相关功能的开始、Hook 相关功能的配置都在这里。
## API_VERSION_NAME <span class="symbol">- field</span>
## TAG <span class="symbol">- field</span>
```kotlin:no-line-numbers
const val API_VERSION_NAME: String
const val TAG: String
```
**变更记录**
`v1.0.4` `新增`
`v1.2.0` `新增`
**功能描述**
> 获取当前 `YukiHookAPI` 的名称 (标签)。
## VERSION <span class="symbol">- field</span>
```kotlin:no-line-numbers
const val VERSION: String
```
**变更记录**
`v1.2.0` `新增`
**功能描述**
> 获取当前 `YukiHookAPI` 的版本。
## API_VERSION_CODE <span class="symbol">- field</span>
```kotlin:no-line-numbers
const val API_VERSION_CODE: Int
```
<h2 class="deprecated">API_VERSION_NAME - field</h2>
**变更记录**
`v1.0.4` `新增`
**功能描述**
`v1.2.0` `作废`
> 获取当前 `YukiHookAPI` 的版本号。
不再区分版本名称和版本号,请迁移到 `VERSION`
<h2 class="deprecated">API_VERSION_CODE - field</h2>
**变更记录**
`v1.0.4` `新增`
`v1.2.0` `作废`
不再区分版本名称和版本号,请迁移到 `VERSION`
<h2 class="deprecated">executorName - field</h2>
@@ -52,7 +72,7 @@ const val API_VERSION_CODE: Int
`v1.0.91` `移除`
移到 `Status.Executor.name`
移到 `Status.Executor.name`
<h2 class="deprecated">executorVersion - field</h2>
@@ -62,7 +82,7 @@ const val API_VERSION_CODE: Int
`v1.0.91` `移除`
移到 `Status.Executor.apiLevel`、`Status.Executor.versionName`、`Status.Executor.versionCode`
移到 `Status.Executor.apiLevel`、`Status.Executor.versionName`、`Status.Executor.versionCode`
## Status <span class="symbol">- object</span>
@@ -114,7 +134,7 @@ val isXposedEnvironment: Boolean
`v1.1.5` `作废`
移到 `Executor.name`
移到 `Executor.name`
<h3 class="deprecated">executorVersion - field</h3>
@@ -124,7 +144,7 @@ val isXposedEnvironment: Boolean
`v1.1.5` `作废`
移到 `Executor.apiLevel`、`Executor.versionName`、`Executor.versionCode`
移到 `Executor.apiLevel`、`Executor.versionName`、`Executor.versionCode`
### isModuleActive <span class="symbol">- field</span>
@@ -144,7 +164,7 @@ val isModuleActive: Boolean
在模块环境中你需要将 **Application** 继承于 **ModuleApplication**。
在模块环境中需要启用 **Configs.isEnableHookModuleStatus**。
在模块环境中需要启用 **InjectYukiHookWithXposed.isUsingXposedModuleStatus**。
在 (Xposed) 宿主环境中仅返回非 **isTaiChiModuleActive** 的激活状态。
@@ -166,7 +186,7 @@ val isXposedModuleActive: Boolean
::: warning
在模块环境中需要启用 **Configs.isEnableHookModuleStatus**。
在模块环境中需要启用 **InjectYukiHookWithXposed.isUsingXposedModuleStatus**。
在 (Xposed) 宿主环境中始终返回 true。
@@ -206,11 +226,11 @@ val isSupportResourcesHook: Boolean
**功能描述**
> 判断当前 Hook Framework 是否支持资源钩子(Resources Hook)。
> 判断当前 Hook Framework 是否支持资源钩子 (Resources Hook)。
::: warning
在模块环境中需要启用 **Configs.isEnableHookModuleStatus**。
在模块环境中需要启用 **InjectYukiHookWithXposed.isUsingXposedModuleStatus**。
在 (Xposed) 宿主环境中可能会延迟等待事件回调后才会返回 true。
@@ -248,7 +268,27 @@ val name: String
::: warning
在模块环境中需要启用 **Configs.isEnableHookModuleStatus**。
在模块环境中需要启用 **InjectYukiHookWithXposed.isUsingXposedModuleStatus**。
:::
#### type <span class="symbol">- field</span>
```kotlin:no-line-numbers
val type: ExecutorType
```
**变更记录**
`v1.1.9` `新增`
**功能描述**
> 获取当前 Hook Framework 类型。
::: warning
在模块环境中需要启用 **InjectYukiHookWithXposed.isUsingXposedModuleStatus**。
:::
@@ -268,7 +308,7 @@ val apiLevel: Int
::: warning
在模块环境中需要启用 **Configs.isEnableHookModuleStatus**。
在模块环境中需要启用 **InjectYukiHookWithXposed.isUsingXposedModuleStatus**。
:::
@@ -288,7 +328,7 @@ val versionName: String
::: warning
在模块环境中需要启用 **Configs.isEnableHookModuleStatus**。
在模块环境中需要启用 **InjectYukiHookWithXposed.isUsingXposedModuleStatus**。
:::
@@ -308,7 +348,7 @@ val versionCode: Int
::: warning
在模块环境中需要启用 **Configs.isEnableHookModuleStatus**。
在模块环境中需要启用 **InjectYukiHookWithXposed.isUsingXposedModuleStatus**。
:::
@@ -329,7 +369,7 @@ object Configs
### debugLog <span class="symbol">- method</span>
```kotlin:no-line-numbers
inline fun debugLog(initiate: YukiHookLogger.Configs.() -> Unit)
inline fun debugLog(initiate: YLog.Configs.() -> Unit)
```
**变更记录**
@@ -338,7 +378,7 @@ inline fun debugLog(initiate: YukiHookLogger.Configs.() -> Unit)
**功能描述**
> 配置 `YukiHookLogger.Configs` 相关参数。
> 配置 `YLog.Configs` 相关参数。
<h3 class="deprecated">debugTag - field</h3>
@@ -348,7 +388,7 @@ inline fun debugLog(initiate: YukiHookLogger.Configs.() -> Unit)
`v1.1.0` `作废`
移到 `YukiHookLogger.Configs.tag`
移到 `YLog.Configs.tag`
### isDebug <span class="symbol">- field</span>
@@ -362,9 +402,9 @@ var isDebug: Boolean
**功能描述**
> 是否启用 DEBUG 模式。
> 是否启用 Debug 模式。
默认为开启状态,开启后模块将会向 `Logcat` 和 `XposedBridge.log` 打印详细的 Hook 日志,关闭后仅会打印 `E` 级别的日志。
默认不启用,启用后模块将会向 `Logcat` 和 (Xposed) 宿主环境中的日志功能打印详细的 Hook 日志,关闭后仅会打印 `E` 级别的日志。
<h3 class="deprecated">isAllowPrintingLogs - field</h3>
@@ -374,25 +414,27 @@ var isDebug: Boolean
`v1.1.0` `作废`
移到 `YukiHookLogger.Configs.isEnable`
移到 `YLog.Configs.isEnable`
### isEnableModulePrefsCache <span class="symbol">- field</span>
```kotlin:no-line-numbers
var isEnableModulePrefsCache: Boolean
```
<h3 class="deprecated">isEnableModulePrefsCache - field</h3>
**变更记录**
`v1.0.5` `新增`
**功能描述**
`v1.1.9` `作废`
> 是否启用 `YukiHookModulePrefs` 的键值缓存功能。
请迁移到 `isEnablePrefsBridgeCache`
为防止内存复用过高问题,此功能默认启用。
<h3 class="deprecated">isEnablePrefsBridgeCache - field</h3>
你可以手动在 `YukiHookModulePrefs` 中自由开启和关闭缓存功能以及清除缓存。
**变更记录**
`v1.1.9` `新增`
`v1.1.11` `作废`
键值的直接缓存功能已被移除,因为其存在内存溢出 (OOM) 问题
### isEnableModuleAppResourcesCache <span class="symbol">- field</span>
@@ -418,27 +460,15 @@ var isEnableModuleAppResourcesCache: Boolean
:::
### isEnableHookModuleStatus <span class="symbol">- field</span>
```kotlin:no-line-numbers
var isEnableHookModuleStatus: Boolean
```
<h3 class="deprecated">isEnableHookModuleStatus - field</h3>
**变更记录**
`v1.0.88` `新增`
**功能描述**
`v1.2.0` `作废`
> 是否启用 Hook Xposed 模块激活等状态功能.
为原生支持 Xposed 模块激活状态检测,此功能默认启用。
::: warning
关闭后你将不能再在模块环境中使用 **YukiHookAPI.Status** 中的激活状态判断功能。
:::
请手动迁移到 `InjectYukiHookWithXposed.isUsingXposedModuleStatus`
### isEnableHookSharedPreferences <span class="symbol">- field</span>
@@ -460,7 +490,7 @@ var isEnableHookSharedPreferences: Boolean
这是一个可选的实验性功能,此功能默认不启用。
仅用于修复某些系统可能会出现在启用了 **New XSharedPreferences** 后依然出现文件权限错误问题,若你能正常使用 **YukiHookModulePrefs** 就不建议启用此功能。
仅用于修复某些系统可能会出现在启用了 **New XSharedPreferences** 后依然出现文件权限错误问题,若你能正常使用 **YYukiHookPrefsBridge** 就不建议启用此功能。
:::
@@ -482,33 +512,15 @@ var isEnableDataChannel: Boolean
此功能默认启用,关闭后将不会在功能初始化的时候装载 `YukiHookDataChannel`。
### isEnableMemberCache <span class="symbol">- field</span>
```kotlin:no-line-numbers
var isEnableMemberCache: Boolean
```
<h3 class="deprecated">isEnableMemberCache - field</h3>
**变更记录**
`v1.0.68` `新增`
`v1.0.80` `修改`
`v1.1.11` `作废`
将方法体进行 inline
**功能描述**
> 是否启用 `Member` 缓存功能。
为防止 `Member` 复用过高造成的系统 GC 问题,此功能默认启用。
启用后会缓存已经找到的 `Method`、`Constructor`、`Field`。
缓存的 `Member` 都将处于 `MemberCacheStore` 的全局静态实例中。
推荐使用 `MethodFinder`、`ConstructorFinder`、`FieldFinder` 来获取 `Member`。
除非缓存的 `Member` 发生了混淆的问题,例如使用 R8 混淆后的 APP 的目标 `Member`,否则建议启用。
`Member` 的直接缓存功能已被移除,因为其存在内存溢出 (OOM) 问题
## configs <span class="symbol">- method</span>
@@ -520,20 +532,24 @@ inline fun configs(initiate: Configs.() -> Unit)
`v1.0` `添加`
`v1.0.80` `修改`
将方法体进行 inline
**功能描述**
> 对 `Configs` 类实现了一个 `lambda` 方法体。
> 对 `Configs` 类实现了一个 **lambda** 方法体。
你可以轻松调用它进行配置。
你可以轻松调用它进行配置。
**功能示例**
你可以在 `HookEntryClass` 的 `onInit` 方法中调用 `configs` 方法和 `debugLog` 方法完成对 API 的功能配置,实时生效。
你可以在 Hook 入口类的 `onInit` 方法中调用 `configs` 方法和 `debugLog` 方法完成对 API 的功能配置,实时生效。
> 示例如下
```kotlin
class HookEntryClass : IYukiHookXposedInit {
object HookEntry : IYukiHookXposedInit {
override fun onInit() {
YukiHookAPI.configs {
@@ -544,12 +560,10 @@ class HookEntryClass : IYukiHookXposedInit {
elements(TAG, PRIORITY, PACKAGE_NAME, USER_ID)
}
isDebug = BuildConfig.DEBUG
isEnableModulePrefsCache = true
isEnableModuleAppResourcesCache = true
isEnableHookModuleStatus = true
isEnableHookSharedPreferences = false
isEnableDataChannel = true
isEnableMemberCache = true
}
}
@@ -564,7 +578,7 @@ class HookEntryClass : IYukiHookXposedInit {
> 示例如下
```kotlin
class HookEntryClass : IYukiHookXposedInit {
object HookEntry : IYukiHookXposedInit {
override fun onInit() = configs {
debugLog {
@@ -574,12 +588,10 @@ class HookEntryClass : IYukiHookXposedInit {
elements(TAG, PRIORITY, PACKAGE_NAME, USER_ID)
}
isDebug = BuildConfig.DEBUG
isEnableModulePrefsCache = true
isEnableModuleAppResourcesCache = true
isEnableHookModuleStatus = true
isEnableHookSharedPreferences = false
isEnableDataChannel = true
isEnableMemberCache = true
}
override fun onHook() {
@@ -593,25 +605,23 @@ class HookEntryClass : IYukiHookXposedInit {
> 示例如下
```kotlin
class HookEntryClass : IYukiHookXposedInit {
object HookEntry : IYukiHookXposedInit {
override fun onInit() {
YukiHookLogger.Configs.tag = "YukiHookAPI"
YukiHookLogger.Configs.isEnable = true
YukiHookLogger.Configs.isRecord = false
YukiHookLogger.Configs.elements(
YukiHookLogger.Configs.TAG,
YukiHookLogger.Configs.PRIORITY,
YukiHookLogger.Configs.PACKAGE_NAME,
YukiHookLogger.Configs.USER_ID
YLog.Configs.tag = "YukiHookAPI"
YLog.Configs.isEnable = true
YLog.Configs.isRecord = false
YLog.Configs.elements(
YLog.Configs.TAG,
YLog.Configs.PRIORITY,
YLog.Configs.PACKAGE_NAME,
YLog.Configs.USER_ID
)
YukiHookAPI.Configs.isDebug = BuildConfig.DEBUG
YukiHookAPI.Configs.isEnableModulePrefsCache = true
YukiHookAPI.Configs.isEnableModuleAppResourcesCache = true
YukiHookAPI.Configs.isEnableHookModuleStatus = true
YukiHookAPI.InjectYukiHookWithXposed.isUsingXposedModuleStatus = true
YukiHookAPI.Configs.isEnableHookSharedPreferences = false
YukiHookAPI.Configs.isEnableDataChannel = true
YukiHookAPI.Configs.isEnableMemberCache = true
}
override fun onHook() {

View File

@@ -9,6 +9,7 @@ annotation class InjectYukiHookWithXposed(
val sourcePath: String,
val modulePackageName: String,
val entryClassName: String,
val isUsingXposedModuleStatus: Boolean,
val isUsingResourcesHook: Boolean
)
```
@@ -25,6 +26,10 @@ annotation class InjectYukiHookWithXposed(
新增 `isUsingResourcesHook` 参数
`v1.2.0` `修改`
新增 `isUsingXposedModuleStatus` 参数
**功能描述**
> 标识 `YukiHookAPI` 注入 Xposed 入口的类注解。

View File

@@ -5,7 +5,7 @@ pageClass: code-page
# CurrentClass <span class="symbol">- class</span>
```kotlin:no-line-numbers
class CurrentClass internal constructor(internal val classSet: Class<*>, internal val instance: Any)
class CurrentClass internal constructor(private val classSet: Class<*>, internal val instance: Any)
```
**变更记录**
@@ -125,7 +125,7 @@ inline fun method(initiate: MethodConditions): MethodFinder.Result.Instance
## SuperClass <span class="symbol">- class</span>
```kotlin:no-line-numbers
inner class SuperClass internal constructor(internal val superClassSet: Class<*>)
inner class SuperClass internal constructor(private val superClassSet: Class<*>)
```
**变更记录**

View File

@@ -19,11 +19,11 @@ class GenericClass internal constructor(private val type: ParameterizedType)
## argument <span class="symbol">- method</span>
```kotlin:no-line-numbers
fun argument(index: Int): Class<*>
fun argument(index: Int): Class<*>?
```
```kotlin:no-line-numbers
inline fun <reified T> argument(index: Int): Class<T>
inline fun <reified T> argument(index: Int): Class<T>?
```
**变更记录**
@@ -34,6 +34,16 @@ inline fun <reified T> argument(index: Int): Class<T>
新增泛型返回值 `Class<T>` 方法
`v1.2.0` `修改`
方法的返回值可为 `null`
**功能描述**
> 获得泛型参数数组下标的 `Class` 实例。
> 获得泛型参数数组下标的 `Class` 实例。
::: warning
在运行时局部变量的泛型会被擦除,获取不到时将会返回 **null**
:::

View File

@@ -5,7 +5,7 @@ pageClass: code-page
# YukiMemberHookCreator <span class="symbol">- class</span>
```kotlin:no-line-numbers
class YukiMemberHookCreator internal constructor(internal val packageParam: PackageParam, internal val hookClass: HookClass)
class YukiMemberHookCreator internal constructor(private val packageParam: PackageParam, private val hookClass: HookClass)
```
**变更记录**
@@ -28,53 +28,37 @@ class YukiMemberHookCreator internal constructor(internal val packageParam: Pack
> `YukiHookAPI` 的 `Member` 核心 Hook 实现类。
## PRIORITY_DEFAULT <span class="symbol">- field</span>
```kotlin:no-line-numbers
val PRIORITY_DEFAULT: Int
```
<h2 class="deprecated">PRIORITY_DEFAULT - field</h2>
**变更记录**
`v1.0.80` `新增`
**功能描述**
`v1.2.0` `作废`
> 默认 Hook 回调优先级。
请迁移到 `YukiHookPriority`
## PRIORITY_LOWEST <span class="symbol">- field</span>
```kotlin:no-line-numbers
val PRIORITY_LOWEST: Int
```
<h2 class="deprecated">PRIORITY_LOWEST - field</h2>
**变更记录**
`v1.0.80` `新增`
**功能描述**
`v1.2.0` `作废`
> 延迟回调 Hook 方法结果。
请迁移到 `YukiHookPriority`
## PRIORITY_HIGHEST <span class="symbol">- field</span>
```kotlin:no-line-numbers
val PRIORITY_HIGHEST: Int
```
<h2 class="deprecated">PRIORITY_HIGHEST - field</h2>
**变更记录**
`v1.0.80` `新增`
**功能描述**
`v1.2.0` `作废`
> 更快回调 Hook 方法结果。
请迁移到 `YukiHookPriority`
## instanceClass <span class="symbol">- field</span>
```kotlin:no-line-numbers
val instanceClass: Class<*>
```
<h2 class="deprecated">instanceClass - field</h2>
**变更记录**
@@ -84,21 +68,11 @@ val instanceClass: Class<*>
~~`thisClass`~~ 更名为 `instanceClass`
**功能描述**
`v1.2.0` `作废`
> 得到当前被 Hook 的 `Class`。
不再推荐使用
::: danger
不推荐直接使用,万一得不到 **Class** 对象则会无法处理异常导致崩溃。
:::
## injectMember <span class="symbol">- method</span>
```kotlin:no-line-numbers
inline fun injectMember(priority: Int, tag: String, initiate: MemberHookCreator.() -> Unit): MemberHookCreator.Result
```
<h2 class="deprecated">injectMember - method</h2>
**变更记录**
@@ -110,72 +84,38 @@ inline fun injectMember(priority: Int, tag: String, initiate: MemberHookCreator.
增加 `priority` Hook 优先级
`v1.2.0` `作废`
请迁移到另一个 `injectMember`
## injectMember <span class="symbol">- method</span>
```kotlin:no-line-numbers
inline fun injectMember(priority: YukiHookPriority, initiate: MemberHookCreator.LegacyCreator.() -> Unit): MemberHookCreator.Result
```
**变更记录**
`v1.2.0` `新增`
**功能描述**
> 注入要 Hook 的 `Method`、`Constructor`。
**功能示例**
你可以注入任意 `Method` 与 `Constructor`,使用 `injectMember` 即可创建一个 `Hook` 对象。
> 示例如下
```kotlin
injectMember {
// Your code here.
}
```
你还可以自定义 `tag`,方便你在调试的时候能够区分你的 `Hook` 对象。
> 示例如下
```kotlin
injectMember(tag = "KuriharaYuki") {
// Your code here.
}
```
你还可以自定义 `priority`,以控制当前 Hook 对象并列执行的优先级速度。
> 示例如下
```kotlin
injectMember(priority = PRIORITY_HIGHEST) {
// Your code here.
}
```
## useDangerousOperation <span class="symbol">- method</span>
```kotlin:no-line-numbers
fun useDangerousOperation(option: String)
```
<h2 class="deprecated">useDangerousOperation - method</h2>
**变更记录**
`v1.1.0` `新增`
**功能描述**
`v1.2.0` `作废`
> 允许 Hook 过程中的所有危险行为。
请在 `option` 中键入 `Yes do as I say!` 代表你同意允许所有危险行为。
你还需要在整个调用域中声明注解 `CauseProblemsApi` 以消除警告。
若你只需要 Hook `ClassLoader` 的 `loadClass` 方法,请参考 [ClassLoader.onLoadClass](../factory/ReflectionFactory#classloader-onloadclass-ext-method)。
::: danger
若你不知道允许此功能会带来何种后果,请勿使用。
:::
此功能已被弃用
## MemberHookCreator <span class="symbol">- class</span>
```kotlin:no-line-numbers
inner class MemberHookCreator internal constructor(private val priority: Int, internal val tag: String)
inner class MemberHookCreator internal constructor(private val priority: YukiHookPriority, private val hookMode: HookMode)
```
**变更记录**
@@ -196,343 +136,41 @@ inner class MemberHookCreator internal constructor(private val priority: Int, in
修正拼写错误的 **Creater** 命名到 **Creator**
`v1.2.0` `修改`
移除 `tag`
`priority` 类型由 `Int` 变更为 `YukiHookPriority`
增加 `hookMode` Hook 模式
**功能描述**
> Hook 核心功能实现类,查找和处理需要 Hook 的 `Method`、`Constructor`。
<h3 class="deprecated">member - field</h3>
**变更记录**
`v1.0` `添加`
`v1.1.0` `移除`
请转移到 `members`
### members <span class="symbol">- method</span>
### before <span class="symbol">- method</span>
```kotlin:no-line-numbers
fun members(vararg member: Member?)
fun before(initiate: HookParam.() -> Unit): HookCallback
```
**变更记录**
`v1.1.0` `新增`
**功能描述**
> 手动指定要 Hook 的 `Method`、`Constructor`。
::: warning
不建议使用此方法设置目标需要 Hook 的 **Member** 对象,你可以使用 **method** 或 **constructor** 方法。
:::
**功能示例**
你可以调用 `instanceClass` 来手动查找要 Hook 的 `Method`、`Constructor`。
> 示例如下
```kotlin
injectMember {
members(instanceClass.getDeclaredMethod("test", StringClass))
beforeHook {}
afterHook {}
}
```
同样地,你也可以传入一组 `Member` 同时进行 Hook。
> 示例如下
```kotlin
injectMember {
members(
instanceClass.getDeclaredMethod("test1", StringClass),
instanceClass.getDeclaredMethod("test2", StringClass),
instanceClass.getDeclaredMethod("test3", StringClass)
)
beforeHook {}
afterHook {}
}
```
<h3 class="deprecated">allMethods - method</h3>
**变更记录**
`v1.0` `添加`
`v1.1.0` `作废`
请使用 `method { name = /** name */ }.all()` 来取代它
<h3 class="deprecated">allConstructors - method</h3>
**变更记录**
`v1.0` `添加`
`v1.1.0` `作废`
请使用 `allMembers(MembersType.CONSTRUCTOR)` 来取代它
### allMembers <span class="symbol">- method</span>
```kotlin:no-line-numbers
fun allMembers(type: MembersType)
```
**变更记录**
`v1.1.0` `新增`
**功能描述**
> 查找并 Hook `hookClass` 中的全部 `Method`、`Constructor`。
::: warning
无法准确处理每个 **Member** 的返回值和 **param**,建议使用 **method** or **constructor** 对每个 **Member** 单独 Hook。
:::
### method <span class="symbol">- method</span>
```kotlin:no-line-numbers
inline fun method(initiate: MethodConditions): MethodFinder.Result
```
**变更记录**
`v1.0` `添加`
`v1.0.80` `修改`
将方法体进行 inline
**功能描述**
> 查找当前 `Class` 需要 Hook 的 `Method` 。
**功能示例**
你可参考 [MethodFinder](finder/members/MethodFinder) 查看详细用法。
> 示例如下
```kotlin
injectMember {
method {
name = "test"
param(StringClass)
returnType = UnitType
}
beforeHook {}
afterHook {}
}
```
若想 Hook 当前查找 `method { ... }` 条件的全部结果,你只需要在最后加入 `all` 即可。
> 示例如下
```kotlin
injectMember {
method {
name = "test"
paramCount(1..5)
}.all()
beforeHook {}
afterHook {}
}
```
此时 `beforeHook` 与 `afterHook` 会在每个查找到的结果中多次回调 Hook 方法体。
::: warning
若没有 **all**,默认只会 Hook 当前条件查找到的数组下标结果第一位。
:::
### constructor <span class="symbol">- method</span>
```kotlin:no-line-numbers
inline fun constructor(initiate: ConstructorConditions): ConstructorFinder.Result
```
**变更记录**
`v1.0` `添加`
`v1.0.80` `修改`
将方法体进行 inline
**功能描述**
> 查找当前 `Class` 需要 Hook 的 `Constructor`。
**功能示例**
你可参考 [ConstructorFinder](finder/members/ConstructorFinder) 查看详细用法。
> 示例如下
```kotlin
injectMember {
constructor { param(StringClass) }
beforeHook {}
afterHook {}
}
```
若想 Hook 当前查找 `constructor { ... }` 条件的全部结果,你只需要在最后加入 `all` 即可。
> 示例如下
```kotlin
injectMember {
constructor { paramCount(1..5) }.all()
beforeHook {}
afterHook {}
}
```
此时 `beforeHook` 与 `afterHook` 会在每个查找到的结果中多次回调 Hook 方法体。
::: warning
若没有 **all**,默认只会 Hook 当前条件查找到的数组下标结果第一位。
:::
### HookParam.field <span class="symbol">- i-ext-method</span>
```kotlin:no-line-numbers
inline fun HookParam.field(initiate: FieldConditions): FieldFinder.Result
```
**变更记录**
`v1.0` `添加`
`v1.0.80` `修改`
将方法体进行 inline
**功能描述**
> 使用当前 `hookClass` 查找并得到 `Field`。
**功能示例**
你可参考 [FieldFinder](finder/members/FieldFinder) 查看详细用法。
> 示例如下
```kotlin
injectMember {
method {
name = "test"
param(StringClass)
returnType = UnitType
}
afterHook {
// 这里不需要再调用 instanceClass.field 进行查找
field {
name = "isSweet"
type = BooleanType
}.get(instance).setTrue()
}
}
```
### HookParam.method <span class="symbol">- i-ext-method</span>
```kotlin:no-line-numbers
inline fun HookParam.method(initiate: MethodConditions): MethodFinder.Result
```
**变更记录**
`v1.0.2` `添加`
`v1.0.80` `修改`
将方法体进行 inline
**功能描述**
> 使用当前 `hookClass` 查找并得到 `Method` 。
### HookParam.constructor <span class="symbol">- i-ext-method</span>
```kotlin:no-line-numbers
inline fun HookParam.constructor(initiate: ConstructorConditions): ConstructorFinder.Result
```
**变更记录**
`v1.0.2` `添加`
`v1.0.80` `修改`
将方法体进行 inline
**功能描述**
> 使用当前 `hookClass` 查找并得到 `Constructor`。
### HookParam.injectMember <span class="symbol">- i-ext-method</span>
```kotlin:no-line-numbers
inline fun HookParam.injectMember(priority: Int, tag: String, initiate: MemberHookCreator.() -> Unit): MemberHookCreator.Result
```
**变更记录**
`v1.0.88` `新增`
**功能描述**
> 注入要 Hook 的 `Method`、`Constructor` (嵌套 Hook)。
### beforeHook <span class="symbol">- method</span>
```kotlin:no-line-numbers
fun beforeHook(initiate: HookParam.() -> Unit): HookCallback
```
**变更记录**
`v1.0` `添加`
`v1.1.0` `修改`
新增 `HookCallback` 返回类型
`v1.2.0` `新增`
**功能描述**
> 在 `Member` 执行完成前 Hook。
### afterHook <span class="symbol">- method</span>
### after <span class="symbol">- method</span>
```kotlin:no-line-numbers
fun afterHook(initiate: HookParam.() -> Unit): HookCallback
fun after(initiate: HookParam.() -> Unit): HookCallback
```
**变更记录**
`v1.0` `添加`
`v1.1.0` `修改`
新增 `HookCallback` 返回类型
`v1.2.0` `新增`
**功能描述**
@@ -662,6 +300,26 @@ fun removeSelf(result: (Boolean) -> Unit)
:::
### LegacyCreator <span class="symbol">- class</span>
```kotlin:no-line-numbers
inner class LegacyCreator internal constructor()
```
**变更记录**
`v1.2.0` `新增`
**功能描述**
> 使用 `injectMember` 创建的 Hook 核心功能实现类 (旧版本)。
::: warning
大部分旧版 API 已被迁移至此处,将不再特殊说明其中包含的旧版 API。
:::
### HookCallback <span class="symbol">- class</span>
```kotlin:no-line-numbers
@@ -726,24 +384,6 @@ inline fun result(initiate: Result.() -> Unit): Result
> 创建监听失败事件方法体。
**功能示例**
你可以使用此方法为 `Result` 类创建 `lambda` 方法体。
> 示例如下
```kotlin
injectMember {
// Your code here.
}.result {
onHooked {}
onAlreadyHooked {}
ignoredConductFailure()
onHookingFailure {}
// ...
}
```
#### by <span class="symbol">- method</span>
```kotlin:no-line-numbers

View File

@@ -283,6 +283,52 @@ injectResource {
}
```
### replaceTo <span class="symbol">- method</span>
```kotlin:no-line-numbers
fun replaceTo(result: (original: Any) -> Any?)
```
**变更记录**
`v1.2.0` `新增`
**功能描述**
> 替换指定 Resources 为指定的值。
::: warning
此方法只支持部分类型,例如 **String**、**Boolean**。
此方法不支持在 **HookEntryType.ZYGOTE** 时使用。
:::
### replaceToModuleResource <span class="symbol">- method</span>
```kotlin:no-line-numbers
fun replaceToModuleResource(result: (original: Any) -> Int)
```
**变更记录**
`v1.2.0` `新增`
**功能描述**
> 替换为当前 Xposed 模块的 Resources。
你可以直接使用模块的 `R.string.xxx`、`R.mipmap.xxx`、`R.drawable.xxx` 替换 Hook APP 的 Resources。
::: warning
此方法只支持部分类型,例如 **String**、**Boolean**。
此方法不支持在 **HookEntryType.ZYGOTE** 时使用。
:::
### injectAsLayout <span class="symbol">- method</span>
```kotlin:no-line-numbers

View File

@@ -0,0 +1,107 @@
---
pageClass: code-page
---
# ExecutorType <span class="symbol">- class</span>
```kotlin:no-line-numbers
enum class ExecutorType
```
**变更记录**
`v1.1.9` `新增`
**功能描述**
> Hook Framework 类型定义。
定义了目前已知使用频率较高的 Hook Framework。
后期根据 Hook Framework 特征和使用情况将会继续添加新的类型。
无法识别的 Hook Framework 将被定义为 `UNKNOWN`。
## UNKNOWN <span class="symbol">- enum</span>
```kotlin:no-line-numbers
UNKNOWN
```
**变更记录**
`v1.1.9` `新增`
**功能描述**
> 未知类型。
## XPOSED <span class="symbol">- enum</span>
```kotlin:no-line-numbers
XPOSED
```
**变更记录**
`v1.1.9` `新增`
**功能描述**
> 原版、第三方 Xposed。
## LSPOSED_LSPATCH <span class="symbol">- enum</span>
```kotlin:no-line-numbers
LSPOSED_LSPATCH
```
**变更记录**
`v1.1.9` `新增`
**功能描述**
> LSPosed、LSPatch。
## ED_XPOSED <span class="symbol">- enum</span>
```kotlin:no-line-numbers
ED_XPOSED
```
**变更记录**
`v1.1.9` `新增`
**功能描述**
> EdXposed。
## TAICHI_XPOSED <span class="symbol">- enum</span>
```kotlin:no-line-numbers
TAICHI_XPOSED
```
**变更记录**
`v1.1.9` `新增`
**功能描述**
> TaiChi (太极)。
## BUG_XPOSED <span class="symbol">- enum</span>
```kotlin:no-line-numbers
BUG_XPOSED
```
**变更记录**
`v1.1.9` `新增`
**功能描述**
> BugXposed (应用转生)。

View File

@@ -0,0 +1,63 @@
---
pageClass: code-page
---
# YukiHookPriority <span class="symbol">- class</span>
```kotlin:no-line-numbers
enum class YukiHookPriority
```
**变更记录**
`v1.1.5` `新增`
`v1.2.0` `修改`
移除 `internal` 对外公开
**功能描述**
> Hook 回调优先级配置类。
## DEFAULT <span class="symbol">- enum</span>
```kotlin:no-line-numbers
DEFAULT
```
**变更记录**
`v1.1.5` `新增`
**功能描述**
> 默认 Hook 回调优先级。
## LOWEST <span class="symbol">- enum</span>
```kotlin:no-line-numbers
LOWEST
```
**变更记录**
`v1.1.5` `新增`
**功能描述**
> 延迟回调 Hook 方法结果。
## HIGHEST <span class="symbol">- enum</span>
```kotlin:no-line-numbers
HIGHEST
```
**变更记录**
`v1.1.5` `新增`
**功能描述**
> 更快回调 Hook 方法结果。

Some files were not shown because too many files have changed in this diff Show More