应用事件中心,事件的生产端和处理端分离,事件处理结果广播通知,事件状态(初始化、处理中和处理完成)管理,事件类型区分(普通事件、DB事件和网络事件)和管理
预览
特性
- 事件生产端和处理端分离,逻辑清晰
- 事件状态管理,让一个事件的处理有迹可循,调试便捷
- 事件类型区分,不同类型可管控
处理中的事件个数
,合理利用系统资源 - 事件loop智能化,无需干预
适用场景
- 事件产生源位置比较深时,利用事件处理器分离具体的处理逻辑
- 多个地方对事件处理结果感兴趣
- 事件之间有依赖关系
- 需要控制不同类型事件并发上限
使用
添加依赖
1 | dependencies { |
定义事件处理器
处理器需要实现IEventProcessor接口,具体的逻辑在process()方法里编写1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35public class DBEventProcessor implements IEventProcessor {
Context mContext;
public DBEventProcessor(Context context) {
mContext = context;
}
public Observable<ProcessResult> process(final Object data) {
Observable<String> dbObservable = Observable.create(new ObservableOnSubscribe<String>() {
public void subscribe(ObservableEmitter<String> e) throws Exception {
Thread.sleep(2000); // db option delay
e.onNext("DB option finished");
}
});
return dbObservable.flatMap(new Function<String, ObservableSource<ProcessResult>>() {
public ObservableSource<ProcessResult> apply(final String data) throws Exception {
return Observable.create(new ObservableOnSubscribe<ProcessResult>() {
public void subscribe(ObservableEmitter<ProcessResult> e) throws Exception {
ProcessResult result = EventDispenser
.getInstance(mContext)
.obtainProcessResult(ProcessResult.okCode(),
Utils.DB_BCR_ACTION,
String.valueOf(data));
e.onNext(result);
}
});
}
});
}
}
注册事件处理器
向框架注册事件处理器,key为事件的唯一标识,value就是该事件的处理器,这样框架就能为事件找到对应的处理器1
2EventDispenser dispenser = EventDispenser.getInstance(this);
dispenser.registerEventProcessor(Utils.DB_EVENT_ACTION, new DBEventProcessor(this));
发送事件
事件处理器注册好之后,只需要发送事件就可以了,框架会帮你找到具体的事件处理器,调用处理方法process()1
2EventDispenser dispenser = EventDispenser.getInstance(this);
dispenser.sendEvent(dispenser.obtainDirectTypeEvent(Utils.DB_EVENT_ACTION, null));
事件处理结果
有些时候我们需要知道事件处理结果,框架利用RxJava flatmap()方法把在事件处理器的结果转换成Observable<ProcessResult>
对象。
然后返回给框架,框架根据ProcessResult的定义,发送BroadcastReceiver广播,并携带结果数据,只需要注册相应的监听器就可以知道事件处理的结果1
2
3
4
5
6
7dbBcr = new ECBcr(this, Utils.DB_BCR_ACTION, new ECBcr.ReceiverHandler() {
public void onReceive(Context context, Intent intent) {
displayInfo(dispenser.ofData(intent));
}
});
dbBcr.register();
自定义配置
框架内置了三种不同类型的事件(普通事件、DB事件和Net事件),分别可以为DB事件和Net事件设置并发上限,达到合理利用稀有资源的目的。
开发阶段可以打开框架的日志系统,方便调试1
2EventDispenser dispenser = EventDispenser.getInstance(this);
dispenser.init(new ECConfig.Builder().dbEventCountLimit(2).netEventCountLimit(5).logEnable(true).build());
事件合并
如果几个事件存在关联关系,比如一个事件要等待另一个事件的结束,这个时候就需要事件合并功能了。
由于框架的事件处理器返回的是Observable<ProcessResult>
对象,所以我们可以完美的利用RxJava强悍的事件流合并功能。
在框架中只需要把这几个事件定义成一个事件,它们之间的关联关系的处理完全交给RxJava1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36/**
* Event combine use RxJava zip operator
*/
public class RxZipEventProcessor implements IEventProcessor {
Context mContext;
public RxZipEventProcessor(Context context) {
mContext = context;
}
public Observable<ProcessResult> process(Object data) {
Observable observable1 = Observable.just("RxJava zip event ");
Observable observable2 = Observable.just(new Random().nextInt(100));
return Observable.zip(observable1, observable2, new BiFunction<String, Integer, String>() {
public String apply(String r1, Integer r2) throws Exception {
return r1 + r2;
}
}).flatMap(new Function<String, Observable<ProcessResult>>() {
public Observable<ProcessResult> apply(final String data) throws Exception {
return Observable.create(new ObservableOnSubscribe<ProcessResult>() {
public void subscribe(ObservableEmitter<ProcessResult> e) throws Exception {
ProcessResult result = EventDispenser
.getInstance(mContext)
.obtainProcessResult(ProcessResult.okCode(), Utils.ZIP_BCR_ACTION, data);
e.onNext(result);
}
});
}
});
}
}
事件顺序
框架预设了三种类型事件(DIRECT_TYPE
, DB_TYPE
, NET_TYPE
),并且为每种类型设定了三种优先级(LOW_PRIORITY
, MIDDLE_PRIORITY
, HIGH_PRIORITY
)。
其中排序规则为DIRECT_TYPE
>DB_TYPE
>NET_TYPE
,LOW_PRIORITY
<MIDDLE_PRIORITY
<HIGH_PRIORITY
。
对事件进行排序很适用于一些特殊的场景,比如某个界面需要三个业务独立的网络请求才能拿到展示所需要的数据,
我们知道数据一般会有重要级的区分,重要的数据需要优先及时的展示给用户,利用事件优先级策略我们可以做到重要的事件优先处理。具体可以查看DEMO中的代码示例
后续开发计划
- 事件类型的定义交给使用者,框架只负责流程管理
- 在工作线程loop事件,不占用UI线程looper资源
详细使用请参照GITHUB工程