|
1 | 1 | ## BCU
|
2 | 2 |
|
3 |
| -本库是一个安卓平台上的基于 [ASM](https://asm.ow2.io/index.html) 实现的轻量级高性能字节码操作平台。目前已经 `AGP 8+`。 |
| 3 | +本库是一个安卓平台上的基于 [ASM](https://asm.ow2.io/index.html) 实现的轻量级高性能字节码操作平台。目前已经兼容 `AGP 8+`。 |
4 | 4 |
|
5 |
| -此外,本库从设计之初就考虑了 `Transform ` 过程对构建时间的影响,经过优化的转换流程和,配合缓存,增量,过滤机制,只为能减少你的等待时间。 |
| 5 | +此外,本库从设计之初就考虑了 `Transform ` 过程对构建时间的影响,因此特别优化了整体构建流程,能更好的利用缓存,增量,过滤机制,从而大幅减少构建所需的时间。 |
| 6 | + |
| 7 | +[](https://jitpack.io/#Ysj001/BytecodeUtil) |
6 | 8 |
|
7 | 9 |
|
8 | 10 |
|
|
23 | 25 |
|
24 | 26 | - **BytecodeUtil**
|
25 | 27 |
|
26 |
| - - `app` 用于演示的 application Demo |
27 |
| - - `demo1` 用于演示的 library Demo1 |
28 |
| - - `buildSrc` 管理 maven 发布和版本控制 |
| 28 | + - `app` 用于演示 |
| 29 | + - `buildSrc` 管理 maven 发布和版本控制项目统一配置 |
29 | 30 | - `repos` 的本地 maven 仓库,便于开发时调试
|
30 | 31 | - `lib_bcu_plugin` 插件工程编译时修改字节码在这里实现
|
31 | 32 | - `plugin-api` 插件对外提供的 API,基于此可实现自定义的字节码修改器
|
32 |
| - - `lib_modifier_aspect` 用于实现 AOP 的字节码修改器 |
33 |
| - - `aspect-api` 使用该修改器时,上层业务需要用到的接口 |
34 |
| - - `lib_modifier_component_di` 用于实现组件依赖注入的字节码修改器 |
35 |
| - - `component-di-api` 使用该修改器时,上层业务需要用到的接口 |
36 | 33 |
|
37 |
| -- **注意:在构建前先在项目根目录下执行该命令来生成插件** |
| 34 | +- **注意:在构建前先在项目根目录下执行该命令来生成插件后重新 sync 项目** |
38 | 35 |
|
39 | 36 | `gradlew publishAllPublicationsToLocalRepository`
|
40 | 37 |
|
41 |
| -- [了解 Gradle 和 Transform 点这(文章基于 AGP4)](https://blog.csdn.net/qq_35365635/article/details/120355777) |
42 |
| - |
43 | 38 |
|
44 | 39 |
|
45 | 40 | ### 如何使用
|
|
61 | 56 |
|
62 | 57 | #### 使用
|
63 | 58 |
|
64 |
| -1. 先在 release 中下载所需的 `repos.zip` 后在你的 `Gradle` 项目根目录下解压 |
65 |
| - |
66 |
| -2. 配置根目录下的 `build.gradle` 来使用解压中的 jar 包 |
| 59 | +1. 配置根目录下的 `build.gradle` 来使用解压中的 jar 包 |
67 | 60 |
|
68 | 61 | ```groovy
|
69 | 62 | // Top-level build file
|
70 | 63 | buildscript {
|
71 |
| - // 解压的仓库地址 |
72 |
| - ext.repos = uri('./repos') |
73 | 64 | repositories {
|
74 | 65 | // 使用仓库中的 jar
|
75 | 66 | maven { url repos }
|
76 |
| - ... ... |
77 | 67 | }
|
78 | 68 | dependencies {
|
79 |
| - ... ... |
80 |
| - classpath "io.github.ysj001.bcu:plugin:<last version>" |
| 69 | + classpath "com.github.Ysj001.BytecodeUtil:plugin:<lastest-version>" |
81 | 70 | }
|
82 | 71 | }
|
83 | 72 |
|
|
88 | 77 | ... ...
|
89 | 78 | }
|
90 | 79 | }
|
91 |
| - // =========================================== |
92 |
| - // Android application build file |
| 80 | + ``` |
| 81 | + |
| 82 | +2. 在 `android application` 模块中使用并配置插件 |
| 83 | + |
| 84 | + ```groovy |
93 | 85 | apply plugin: 'com.android.application'
|
94 | 86 | // 使用 bcu 插件
|
95 | 87 | apply plugin: 'bcu-plugin'
|
|
103 | 95 | // 你要挂载的修改器的 class
|
104 | 96 | Class.forName("xxxxx")
|
105 | 97 | ]
|
106 |
| - // 不需要处理的 class 文件过滤器。合理配置可提大幅升编译速度 |
| 98 | + // 不需要处理的 class 文件过滤器,合理配置可提大幅升编译速度。 |
107 | 99 | notNeed = { entryName ->
|
108 | 100 | // 这里传 false 表示不过滤
|
109 | 101 | false
|
110 | 102 | }
|
111 | 103 | }
|
112 | 104 | ```
|
113 | 105 |
|
| 106 | +3. 混淆配置 |
| 107 | + |
| 108 | + ```tex |
| 109 | + -keepclassmembers class * { |
| 110 | + @com.ysj.lib.bytecodeutil.plugin.api.BCUKeep <methods>; |
| 111 | + } |
| 112 | + ``` |
| 113 | + |
| 114 | + |
| 115 | + |
| 116 | +#### 开发自定义 Modifier 并使用 |
| 117 | + |
| 118 | +**推荐直接查看 `app` 模块,或者查看下文中那些基于 `BCU` 实现的库。** |
| 119 | + |
| 120 | +开发并使用一个自定义的 `Modifier` 非常简单,主要为以下几个步骤: |
| 121 | + |
| 122 | +1. 创建一个用于开发 `Modifier` 的 `java` 模块,并依赖 `plugin-api` 和 `gradleApi` |
| 123 | + |
| 124 | + ```groovy |
| 125 | + plugins { |
| 126 | + id("java-library") |
| 127 | + id("kotlin") |
| 128 | + } |
| 129 | + dependencies { |
| 130 | + implementation(gradleApi()) |
| 131 | + implementation("com.github.Ysj001.BytecodeUtil:plugin-api:<lastest-version>") |
| 132 | + } |
| 133 | + ``` |
| 134 | + |
| 135 | +2. 继承 `IModifier` 接口并重写对应方法 |
| 136 | + |
| 137 | + ```kotlin |
| 138 | + class CustomModifier( |
| 139 | + // 注意:executor , allClassNode 顺序不能变 |
| 140 | + override val executor: Executor, |
| 141 | + override val allClassNode: Map<String, ClassNode>, |
| 142 | + ) : IModifier { |
| 143 | + |
| 144 | + private val logger = YLogger.getLogger(javaClass) |
| 145 | + override fun initialize(project: Project) { |
| 146 | + super.initialize(project) |
| 147 | + // 初始化阶段,可以通过 project 拿到所需的配置参数 |
| 148 | + logger.lifecycle("step1:initialize") |
| 149 | + // 演示获取自定义参数 |
| 150 | + logger.lifecycle(project.properties["modifier.custom"].toString()) |
| 151 | + } |
| 152 | + |
| 153 | + override fun scan(classNode: ClassNode) { |
| 154 | + // 扫描阶段,该阶段可以获取到所有过滤后需要处理的 class |
| 155 | + logger.lifecycle("step2:scan -->$classNode") |
| 156 | + // 你可以在这里过收集需要处理的 class |
| 157 | + // 注意:该方法非多线程安全,内部处理记得按需加锁 |
| 158 | + } |
| 159 | + |
| 160 | + override fun modify() { |
| 161 | + // 处理阶段,该阶段是最后一个阶段,用于修改 scan 阶段收集的 class |
| 162 | + logger.lifecycle("step3:modify") |
| 163 | + } |
| 164 | + } |
| 165 | + ``` |
| 166 | + |
| 167 | +3. 在 `app` 模块中使用 `bcu-plugin` 插件并添加这个自定义的 `Modifier` |
| 168 | + |
| 169 | + ```kotlin |
| 170 | + plugins { |
| 171 | + id("com.android.application") |
| 172 | + id("org.jetbrains.kotlin.android") |
| 173 | + id("bcu-plugin") |
| 174 | + } |
| 175 | + |
| 176 | + bytecodeUtil { |
| 177 | + loggerLevel = 2 |
| 178 | + modifiers = arrayOf( |
| 179 | + // 将 CustomModifier 添加到 bcu 中 |
| 180 | + CustomModifier::class.java, |
| 181 | + ) |
| 182 | + notNeed = { entryName -> |
| 183 | + // 自定义过滤规则 |
| 184 | + false |
| 185 | + } |
| 186 | + } |
| 187 | + |
| 188 | + // 演示给 CustomModifier 传递自定义参数 |
| 189 | + ext["modifier.custom"] = "这是自定义的参数" |
| 190 | + ``` |
| 191 | + |
| 192 | + |
| 193 | + |
| 194 | +#### 日志解析 |
| 195 | + |
| 196 | +了解 `BCU` 的日志系统有助于帮助你开发出更高性能的 `Modifier` ,它能够直观的告诉你各个不同阶段的耗时,好让你便于进行优化。 |
114 | 197 |
|
| 198 | +如下图所示 `BCU` 在运行过程中会执行 2 个任务。 |
115 | 199 |
|
116 |
| -#### 混淆配置 |
| 200 | +分别为 `<variant>BCUTransformTask` 和 `<variant>BCUAppendTask` 。 |
117 | 201 |
|
118 |
| -```text |
119 |
| --keepclassmembers class * { |
120 |
| - @com.ysj.lib.bytecodeutil.plugin.api.BCUKeep <methods>; |
121 |
| -} |
122 |
| -``` |
| 202 | +`BCUAppendTask` 负责处理增量而 `BCUTransformTask` 负责处理整个修改字节码的过程,因此下面的参数解析主要针对该任务中的 log。 |
123 | 203 |
|
| 204 | + |
124 | 205 |
|
| 206 | +log 对应的具体含义: |
125 | 207 |
|
126 |
| -#### 性能 |
| 208 | +| log key | 对应含义 | |
| 209 | +| ------------------------------- | ------------------------------------------- | |
| 210 | +| >>> loggerLevel | 当前 BCU 的日志等级(0~5) | |
| 211 | +| >>> apply modifier | 添加进 BCU 的 Modifier | |
| 212 | +| >>> xxxModifier initialize time | xxxModifier 在 initialize 阶段的耗时 | |
| 213 | +| >>> bcu scan time | BCU 在 scan 阶段的总耗时 | |
| 214 | +| >>> xxxModifier process time | xxxModifier 在 modify 阶段的耗时 | |
| 215 | +| >>> bcu modify time | BCU 在 modify 阶段的总耗时 | |
| 216 | +| >>> bcu transform output time | BCU 将 transform 结果输出到 jar file 的耗时 | |
| 217 | +| >>> total process time | BCUTransformTask 处理过程的总耗时 | |
127 | 218 |
|
128 |
| -**// TODO** |
129 | 219 |
|
130 | 220 |
|
| 221 | +### **基于 BCU 实现的库** |
131 | 222 |
|
132 |
| -#### Modifiers |
| 223 | +- **[modifier-aspect](https://github.com/Ysj001/bcu-modifier-aspect) :用于实现 AOP 的字节码修改器。** |
| 224 | + - **[PermissionMonitor](https://github.com/Ysj001/PermissionMonitor):Android 隐私政策敏感权限监控。** |
133 | 225 |
|
134 |
| -- [modifier-aspect](lib_modifier_aspect/README.md) :用于实现 AOP 的字节码修改器 |
135 |
| -- [modifier-component-di](lib_modifier_component_di/README.md) :用于实现组件依赖注入的字节码修改器 |
| 226 | +- **[modifier-component-di](https://github.com/Ysj001/bcu-modifier-component-di) :用于实现组件依赖注入的字节码修改器。** |
136 | 227 |
|
137 | 228 |
|
138 | 229 |
|
139 |
| -### 其它 |
| 230 | +### **其它** |
140 | 231 |
|
| 232 | +- **[了解 Gradle 和 Transform 点这(文章基于 AGP4)](https://blog.csdn.net/qq_35365635/article/details/120355777)** |
| 233 | +- **如果本项目给予了你帮助那就给个 start 吧。** |
| 234 | +- **如果对本项目有疑问欢迎提 issues。** |
0 commit comments