Skip to content

Commit 6d34d1d

Browse files
committed
see 07/18 log
1 parent 948a87b commit 6d34d1d

File tree

1 file changed

+48
-51
lines changed

1 file changed

+48
-51
lines changed

plugin/bus-gradle-plugin/README.md

Lines changed: 48 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,7 @@ BusUtils.unregister(xxx);
114114
要想工具用得舒服,规范肯定要遵守的,所谓无规矩不成方圆,不然五花八门的问题肯定一堆堆,这里推荐如下规范:
115115

116116
* 持有事件的类和函数确保确保都是 `public` 的。
117-
* 由于 `BusUtils` 是用于模块内调用,所以我们可以写一个 `BusConfig` 的类来保存一个模块内所有 bus 的 `Tag`,方便查找到使用方及调用方。
117+
* 由于 `BusUtils` 是用于模块内调用,所以可以写一个 `BusConfig` 的类来保存一个模块内所有 bus 的 `Tag`,方便查找到使用方及调用方。
118118
* `Tag` 中最好还能带有业务模块后缀名防止重复,是 sticky 类型的话也带上 sticky,指定具体线程的话也带上线程名,例如:`update_avatar_sticky_main_info` 这个 `Tag`,让人直接望文生义。
119119
* 如果能结合 **[AucFrame](https://github.com/Blankj/AucFrameTemplate)** 来使用,那就更规范不过了。
120120

@@ -124,7 +124,7 @@ BusUtils.unregister(xxx);
124124

125125
## 性能测试
126126

127-
首先,我们把两者的事件定义好,因为比较的是事件达到的快慢,所以内部都是空实现即可,具体代码如下所示:
127+
首先,把两者的事件定义好,因为比较的是事件达到的快慢,所以内部都是空实现即可,具体代码如下所示:
128128
```java
129129
@Subscribe
130130
public void eventBusFun(String param) {
@@ -135,7 +135,7 @@ public void busUtilsFun(String param) {
135135
}
136136
```
137137

138-
我们的 BusUtils 在编译时会根据 `@BusUtils.Bus` 注解生成一份记录 tag 和 方法签名的映射表,因为是在编译时完成的,这里我们通过反射来完成。
138+
`BusUtils` 在编译时会根据 `@BusUtils.Bus` 注解生成一份记录 tag 和 方法签名的映射表,因为是在编译时完成的,这里我们通过反射来完成。
139139
```java
140140
@Before
141141
public void setUp() throws Exception {
@@ -145,22 +145,22 @@ public void setUp() throws Exception {
145145
}
146146
```
147147

148-
我们通过比较如下几点的测试来完成对比
148+
通过比较如下几点的测试来完成对比
149149

150150
* 注册 10000 个订阅者,共执行 10 次取平均值
151151
* 向 1 个订阅者发送 * 1000000 次,共执行 10 次取平均值
152152
* 向 100 个订阅者发送 * 100000 次,共执行 10 次取平均值
153153
* 注销 10000 个订阅者,共执行 10 次取平均值
154154

155-
我们的测试机器如下所示
155+
测试机器如下所示
156156
```
157157
macOS: 2.2GHz Intel Core i7 16GB
158158
一加6: Android 9 8GB
159159
```
160160

161-
在 Android 上我们加入 `EventBus` 的注解处理器来提升 `EventBus` 效率,让其在最优情况下和 `BusUtils` 比较。
161+
在 Android 上,我们加入 `EventBus` 的注解处理器来提升 `EventBus` 效率,让其在最优情况下和 `BusUtils` 比较。
162162

163-
接下来,我们把测试的模板代码写好,方便我们后续可以直接把两者比较的代码往回调中塞入即可,具体代码如下所示:
163+
接下来,我们把测试的模板代码写好,方便后续可以直接把两者比较的代码往回调中塞入即可,具体代码如下所示:
164164
```java
165165
/**
166166
* @param name 传入的测试函数名
@@ -378,6 +378,42 @@ public void compareUnregister10000Times() {
378378

379379
基于以上说的这么多,如果你项目中事件总线用得比较频繁,那么可以试着用我的 `BusUtils` 来替代 `EventBus` 来提升性能,或者在新的项目中,你也可以使用性能更好的 `BusUtils`
380380

381+
下面我来总结下 `BusUtils` 的优点:
382+
383+
* `BusUtils` 是通过事件 `Tag` 来确定唯一事件的,所以接收函数支持无参或者一个参数,而 `EventBus` 只能通过 MessageEvent 来确定具体的接收者,只能接收一个参数,即便仅仅是通知,也需要定义一个 MessageEvent,所以,`BusUtils` 传参更灵活。
384+
* `BusUtils` 在应用到项目中后,编译后便会在 application 中生成 `__bus__.json` 事件列表,如上生成的事件列表如下所示:
385+
386+
```json
387+
{
388+
"BusUtilsClass": "com.blankj.utilcode.util.BusUtils",
389+
"rightBus": {
390+
"noParamFun": "{ desc: com.blankj.utilcode.pkg.feature.bus.BusActivity#noParamFun(), threadMode: POSTING }",
391+
"oneParamFun": "{ desc: com.blankj.utilcode.pkg.feature.bus.BusActivity#oneParamFun(java.lang.String param), threadMode: POSTING }"
392+
},
393+
"wrongBus": {}
394+
}
395+
```
396+
397+
修改 `oneParamFun` 为两个参数的话,为了确保项目不会因为 `BusUtils` 在运行时崩溃,`api` 插件会使其在编译时就不过,此时 `__bus__.json` 文件如下所示,提示你参数个数不对:
398+
399+
```json
400+
{
401+
"BusUtilsClass": "com.blankj.utilcode.util.BusUtils",
402+
"rightBus": {
403+
"noParamFun": "{ desc: com.blankj.utilcode.pkg.feature.bus.BusActivity#noParamFun(), threadMode: POSTING }",
404+
},
405+
"wrongBus": {
406+
"oneParamFun": "{ desc: com.blankj.utilcode.pkg.feature.bus.BusActivity#oneParamFun(java.lang.String param, java.lang.String param1), threadMode: POSTING, paramSize: 2 }"
407+
}
408+
```
409+
410+
同理,如果两个 bus 的 `Tag` 相同了,也会编译不过,提示你项目中存在 `Tag` 相同的 bus。
411+
412+
所以,`BusUtils` 比 `EventBus` 更友好。
413+
414+
* `BusUtils` 比 `EventBus` 代码少得太多,`BusUtils` 的源码只有区区 300 行,而 `EventBus` 3000 行肯定是不止的哈。
415+
* `BusUtils` 比 `EventBus` 性能更好,下面我会来对其进行性能对比。
416+
381417

382418
## 原理
383419

@@ -479,7 +515,7 @@ private void init() {
479515
}
480516
```
481517

482-
我们来看下 `registerBus` 的实现:
518+
来看下 `registerBus` 的实现:
483519

484520
```java
485521
private void registerBus(String tag,
@@ -489,7 +525,7 @@ private void registerBus(String tag,
489525
}
490526
```
491527

492-
很简单,就是往 `mTag_BusInfoMap` 中插入了 key 为 `tag`,value 为 `BusInfo` 的一个实例,这样我们便把一个事件保留了下来
528+
很简单,就是往 `mTag_BusInfoMap` 中插入了 key 为 `tag`,value 为 `BusInfo` 的一个实例,这样便把一个事件保留了下来
493529

494530
接下来就是使用了,一开始我们都是先 register,源码如下所示:
495531

@@ -515,7 +551,7 @@ private void registerInner(final Object bus) {
515551

516552
我们获取 bus 的类名,然后对 `mClassName_BusesMap` 加锁来把它插入到 `mClassName_BusesMap` 的 value 的集合中,可以看到我们用了线程安全的 `CopyOnWriteArraySet` 集合,然后还需要处理下之前是否订阅过粘性事件 `processSticky`,到这里 register 便结束了。
517553

518-
然后就是 `post` 来发送事件了,我们分析下源码
554+
然后就是 `post` 来发送事件了,源码如下
519555

520556
```java
521557
public static void post(final String tag) {
@@ -617,7 +653,7 @@ private void realInvokeMethod(final String tag, Object arg, BusInfo busInfo, boo
617653
}
618654
```
619655

620-
可以看到代码还是比较多的,不过别急,我们一步步来还是很简单的,首先去我们注入的 `mTag_BusInfoMap` 中查找是否有该 `tag``BusInfo`,没有的话就输出错误日志直接返回。
656+
可以看到代码还是比较多的,不过别急,我们一步步来还是很简单的,首先在我们之前注入的 `mTag_BusInfoMap` 中查找是否有该 `tag``BusInfo`,没有的话就输出错误日志直接返回。
621657

622658
然后我们根据获取到的 `BusInfo` 来找到 `method` 实例,`BusInfo` 第一次会把 `method` 保存在实例中,之后调用的话直接从实例中取出 `method` 即可。
623659

@@ -644,43 +680,4 @@ private void unregisterInner(final Object bus) {
644680
}
645681
```
646682

647-
`unregister``register` 相反,就是从 `mClassName_BusesMap` 的 value 集合中移除,同样需要对 `mClassName_BusesMap` 加锁哦。
648-
649-
650-
## 总结
651-
652-
下面我来总结下 `BusUtils` 的优点:
653-
654-
* `BusUtils` 是通过事件 `Tag` 来确定唯一事件的,所以接收函数支持无参或者一个参数,而 `EventBus` 只能通过 MessageEvent 来确定具体的接收者,只能接收一个参数,即便仅仅是通知,也需要定义一个 MessageEvent,所以,`BusUtils` 传参更灵活。
655-
* `BusUtils` 在应用到项目中后,编译后便会在 application 中生成 `__bus__.json` 事件列表,如上生成的事件列表如下所示:
656-
657-
```json
658-
{
659-
"BusUtilsClass": "com.blankj.utilcode.util.BusUtils",
660-
"rightBus": {
661-
"noParamFun": "{ desc: com.blankj.utilcode.pkg.feature.bus.BusActivity#noParamFun(), threadMode: POSTING }",
662-
"oneParamFun": "{ desc: com.blankj.utilcode.pkg.feature.bus.BusActivity#oneParamFun(java.lang.String param), threadMode: POSTING }"
663-
},
664-
"wrongBus": {}
665-
}
666-
```
667-
668-
我们修改 `oneParamFun` 为两个参数的话,为了确保项目不会因为 `BusUtils` 在运行时崩溃,`api` 插件会使其在编译时就不过,此时 `__bus__.json` 文件如下所示,提示你参数个数不对:
669-
670-
```json
671-
{
672-
"BusUtilsClass": "com.blankj.utilcode.util.BusUtils",
673-
"rightBus": {
674-
"noParamFun": "{ desc: com.blankj.utilcode.pkg.feature.bus.BusActivity#noParamFun(), threadMode: POSTING }",
675-
},
676-
"wrongBus": {
677-
"oneParamFun": "{ desc: com.blankj.utilcode.pkg.feature.bus.BusActivity#oneParamFun(java.lang.String param, java.lang.String param1), threadMode: POSTING, paramSize: 2 }"
678-
}
679-
```
680-
681-
同理,如果两个 bus 的 `Tag` 相同了,也会编译不过,提示你项目中存在 `Tag` 相同的 bus。
682-
683-
所以,`BusUtils` 比 `EventBus` 更友好。
684-
685-
* `BusUtils` 比 `EventBus` 代码少得太多,`BusUtils` 的源码只有区区 300 行,而 `EventBus` 3000 行肯定是不止的哈。
686-
* `BusUtils` 比 `EventBus` 性能更好,下面我们会来对其进行性能对比。
683+
`unregister``register` 相反,就是从 `mClassName_BusesMap` 的 value 集合中移除,同样需要对 `mClassName_BusesMap` 加锁哦。

0 commit comments

Comments
 (0)