|
60 | 60 |
|
61 | 61 | # 💉 Introduction to ReVanced Patcher |
62 | 62 |
|
63 | | -To create patches for Android apps, it is recommended to know the basic concept of ReVanced Patcher. |
| 63 | +ReVanced Patcher is made out of three structural components. |
64 | 64 |
|
65 | 65 | ## 📙 How it works |
66 | 66 |
|
67 | | -ReVanced Patcher is a library that allows modifying Android apps by applying patches. |
| 67 | +ReVanced Patcher is a library that makes modifying Android apps easy and modular by applying patches. |
68 | 68 | It is built on top of [Smali](https://github.com/google/smali) for bytecode manipulation and [Androlib (Apktool)](https://github.com/iBotPeaches/Apktool) |
69 | 69 | for resource decoding and encoding. |
70 | 70 |
|
71 | | -ReVanced Patcher receives a list of patches and applies them to a given APK file. |
72 | | -It then returns the modified components of the APK file, such as modified dex files and resources, |
73 | | -that can be repackaged into a new APK file. |
| 71 | +First, you load a set of patches to filter as desired based on their attributes: |
74 | 72 |
|
75 | | -ReVanced Patcher has a simple API that allows you to load patches from RVP (JAR or DEX container) files |
76 | | -and apply them to an APK file. Later on, you will learn how to create patches. |
| 73 | +```kt |
| 74 | +val patches = loadPatches(File("revanced-patches.rvp")) |
| 75 | +``` |
| 76 | + |
| 77 | +Afterward, you create a patcher instance for a specific APK file. |
| 78 | +In the `getPatches` lambda, you receive the packageName and versionName of the APK file being patched. |
| 79 | +This is useful to decide which patches to return to the patcher based on the target application: |
77 | 80 |
|
78 | 81 | ```kt |
79 | | -val patches = loadPatchesFromJar(setOf(File("revanced-patches.rvp"))) |
80 | | - |
81 | | -val patcherResult = Patcher(PatcherConfig(apkFile = File("some.apk"))).use { patcher -> |
82 | | - // Here you can access metadata about the APK file through patcher.context.packageMetadata |
83 | | - // such as package name, version code, version name, etc. |
84 | | - |
85 | | - // Add patches. |
86 | | - patcher += patches |
87 | | - |
88 | | - // Execute the patches. |
89 | | - runBlocking { |
90 | | - patcher().collect { patchResult -> |
91 | | - if (patchResult.exception != null) |
92 | | - logger.info { "\"${patchResult.patch}\" failed:\n${patchResult.exception}" } |
93 | | - else |
94 | | - logger.info { "\"${patchResult.patch}\" succeeded" } |
95 | | - } |
96 | | - } |
| 82 | +val patch = patcher(apkFile = File("app.apk")) { packageName, versionName -> |
| 83 | + patches // Optionally filter this set - for example based on packageName and versionName. |
| 84 | +} |
| 85 | +``` |
| 86 | + |
| 87 | +The `patcher` function returns a `patch` lambda that you can later execute to apply the patches to the APK file. |
| 88 | +On execution, `PatchResult` objects for each patch are emitted in the provided lambda. |
| 89 | +You can use this to log the success or failure of each patch: |
97 | 90 |
|
98 | | - // Compile and save the patched APK file components. |
99 | | - patcher.get() |
| 91 | +```kt |
| 92 | +val patchesResult = patch { patchResult -> |
| 93 | + val exception = patchResult.exception |
| 94 | + ?: return@patch logger.info("\"${patchResult.patch}\" succeeded") |
| 95 | + |
| 96 | + StringWriter().use { writer -> |
| 97 | + exception.printStackTrace(PrintWriter(writer)) |
| 98 | + |
| 99 | + logger.severe("\"${patchResult.patch}\" failed:\n$writer") |
| 100 | + } |
100 | 101 | } |
| 102 | +``` |
| 103 | + |
| 104 | +At last, the `patchesResult` returned by the `patch` lambda contains the modified components of the APK file. |
101 | 105 |
|
102 | | -// The result of the patcher contains the modified components of the APK file that can be repackaged into a new APK file. |
103 | | -val dexFiles = patcherResult.dexFiles |
104 | | -val resources = patcherResult.resources |
| 106 | +```kt |
| 107 | +val dexFiles = patchesResult.dexFiles |
| 108 | +val resources = patchesResult.resources |
105 | 109 | ``` |
106 | 110 |
|
107 | 111 | ## ⏭️ What's next |
|
0 commit comments