在使用BmobSDK开发App的时候,会有很多异步回调,类似如登录成功,插入数据成功的事件,虽然V3.5.0开始内部用rxjava去重构,也提供了rx风格的api,不过写事件回调的方法还是比较烦,这时候你可以会用下流行的EventBus库。下面就逐渐实现一个简单的Demo,第一个版本,先不考虑优化和性能,线程切换之类的!

没有事件总线库之前

你可能写接口回调,发广播,但是Activity和Fragment等组件交互也有点麻烦,写起来代码都是比较冗余的!

用了之后

代码优雅,依赖于注解,使得代码分离开来,在需要的时候send事件,对应注解到的特定方法就会被调用到,其实类似的还有Otto这个库。

开始实现

用法实例

// 注册事件库
Bus.getDefault().register(this);
// 创建自定义事件并发送事件
Event event = new Event();
event.setUserId("111");
Bus.getDefault().post(event);
// 指定了特定注解的合理方法会被调用
@BusReceiver
public void onEvent(Event event){System.out.println("getEvent " + event.getUserId());
}
// 注销事件库
Bus.getDefault().unRegister(this);

基本和EventBus的Api有点类似。

自定义注解


@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface BusReceiver {
}

第一个版本先不考虑事件调度模型,所以该注解目前只是作为代码标识,为了内部处理而已。

注解处理

基本思路

1 注册事件库

注册事件库的时候可以拿到该注册类如Activty和对应改类中包涵了@BusReceiver注解的方法,并创建mMethodMap中(类型为Map<Object,List<Method>>),便于后面查找。

2 发送事件

此时根据事件类型,去mMethodMap中遍历,事件类型判断通过就调用method.invoke()调用特定的注解方法。基本都是对reflect下的api使用,比如拿到该类的方法,判断注解并处理等的操作!

代码

public interface IBus {void register(Object target);void unRegister(Object target);void post(Object event);
}public class Bus implements IBus {// 1 reg时 把target类型 记录// 2 通过target类型(Class)找到含有指定@BusReceiver注解的方法 并拿到方法参数类型 以及事件类型// map<targetType,eventType>// post调用 Bus需要根据发送的事件类型找到 map中含有该事件类型的target中的方法集合并调用方法private static Bus INSTANCE = null;// 某target下的方法集合private Map<Object,List<Method>> mMethodMap = new HashMap<>();public static Bus getDefault(){if (INSTANCE == null){synchronized (Bus.class){if (INSTANCE == null){INSTANCE = new Bus();}}}return INSTANCE;}@Overridepublic void register(Object target) {// 找到target下的带有@BusReceiver注解的合法方法并加到mMethodMap中List<Method> annotatedMethods = Utils.findAnnotatedMethods(target.getClass(), BusReceiver.class);mMethodMap.put(target,annotatedMethods);}@Overridepublic void unRegister(Object target) {mMethodMap.remove(target);}@Overridepublic void post(Object event) {Class<?> eventClass = event.getClass();// mMethodMap中的方法 需要判断事件类型for (Map.Entry<Object, List<Method>> entry : mMethodMap.entrySet()) {Object target = entry.getKey();List<Method> methods = entry.getValue();if (methods == null || methods.isEmpty()){continue;}for (Method method : methods) {if (eventClass.equals(method.getParameterTypes()[0])){try {method.invoke(target,event);} catch (IllegalAccessException e) {e.printStackTrace();} catch (InvocationTargetException e) {e.printStackTrace();}}}}}
}

more

基本的事件驱动思路就是这样,转换思路换来代码的整洁,特别是App客户端事件比较多的情况比较适合用类似的库,不过还有一些不足,后续继续改进:
1 没加入调度和分发模型,指定方法在特定的线程回调;
2 方法查找的效率问题,可以放到map缓存,标准库jdk,Android SDK中的方法是可以跳过的;
3 注解处理的效率问题,判断符合方法的条件的顺序是不是可以调整下;
4 可以适当对方法Method对象做一定的抽象;
5 还没加入支持事件继承;

你知道event库吗?教你如何写一个自己的event库相关推荐

  1. 2020年如何写一个现代的JavaScript库

    摘要: 最实用的JS库开发指南- 原文:2020年如何写一个现代的JavaScript库 作者:颜海镜 Fundebug经授权转载,版权归原作者所有. 我写过一些开源项目,在开源方面有一些经验,最近开 ...

  2. 吕文翰 php,自己动手写一个 iOS 网络请求库(三)——降低耦合

    自己动手写一个 iOS 网络请求库(三)--降低耦合 2015-5-22 / 阅读数:16112 / 分类: iOS & Swift 本文中,我们将一起降低之前代码的耦合度,并使用适配器模式实 ...

  3. 教你写一个 React 状态管理库

    自从 React Hooks 推行后,Redux 作为状态管理方案就显得格格不入了.Dan Abramov 很早就提到过 "You might not need Redux",开发 ...

  4. 老用别人的库?今天手把手教你动手写一个Python库,真香!

    引子 学习编程以来,接触过Basic,C/C++,Swift,JavaScript和Python五种语言,其中最爱的当属Python,简洁的语法和丰富的库让我一直沉迷于此,尽管最近实习工作中用的是C+ ...

  5. 3.2 写一个UR机器人运动学库

    本博文属于工程机械臂末端柔顺控制(Ros+Gazebo仿真实现) 注:本文参考文献忘了,参考的是一篇中国学者发表的一篇关于和UR构型一致的6自由度机械臂求逆解规避掉第六个关节可能由于奇异构型无法求解的 ...

  6. python 题库自动答题,自动匹配题库_如何用python写一个从题库自动匹配的答题脚本_淘题吧...

    A. web数据库题目:根据用户输入的用户名和密码于数据库中的记录是否匹配制作一个用户登录模块 http://blog.csdn.net/love_leve/article/details/43226 ...

  7. 手把手教你自己写一个js表单验证框架

    其实我自己也就能简单用用js而已,但是呢,相对很多初学者来说多懂了点Know How所以斗 胆孟浪一下,将一些所得记录下来,以供更多的初学者能够知道一个东西的实现过程,省去 在源码里摸索的过程. 在表 ...

  8. 手把手教你如何写一个三子棋/N子棋的小游戏

    这里写目录标题 第一步 游戏进入界面 第二步,初始化棋盘 第三步,打印棋盘 第四步,玩家和电脑下棋 第五步,判断输赢 三子棋或者N子棋怎么写? 让我们先来玩一把.再来看看怎么写. 程序运行界面 1为玩 ...

  9. Python:教你如何写一个测量网速的小工具

    hello,大家好,我是wangzirui32,今天我们来学习如何写一个测量网速的小工具,开始学习吧! 1. pip安装 这个项目主要依赖speedtest_cli模块,pip安装: pip inst ...

最新文章

  1. Docker是世界上最牛逼的CaaS!
  2. 数据结构 线性表java_java数据结构--线性表
  3. 一个http-request的源码及改进
  4. 浅谈游戏视觉包装中的“情感化设计”
  5. 简单工厂 jdk源码解析
  6. BCP timeout prevention - 每秒刷新一次 Fiori
  7. [机器学习] Boosting算法2 --- GBDT
  8. 《vue+vant 文本超出两行部分省略号显示》
  9. 面试官系统精讲Java源码及大厂真题 - 01 开篇词:为什么学习本专栏
  10. Ubuntu 16.04中iptables的工具简介(iptables/iptables-restore/iptables-xml/iptables-apply/iptables-save)...
  11. 计算机组成原理—主存容量扩展
  12. 拼接Sql语句的写法
  13. redis bitmap存储入门
  14. MYSQL的两种存储引擎区别
  15. 史上最全英文免费编程电子书列表
  16. 关于向社会公开征求 深圳市住房公积金贷款管理暂行规定 (征求意见稿)意见的通知
  17. 计算机系统是日语,如何在计算机系统中添加日语输入法
  18. [转]软件开发项目计划编制过程
  19. 《用户至上:用户研究方法与实践(原书第2版)》一2.3 理解产品
  20. 侍魂胧月传说服务器维护,侍魂胧月传说手游7月1日停机维护更新公告

热门文章

  1. Bootstrap之轮播图
  2. 安装交叉工具链arm-linux-gcc
  3. 领域驱动设计实践(一)(转)
  4. WPF 与Surface 2.0 SDK 亲密接触 - ScatterView 篇
  5. EasyNet.Solr架构
  6. [转]int.ToString()输出不同格式的数字字符串
  7. page_index--template.html(0)源码
  8. 一元三次方程求解matlab_初中数学最全函数/方程【实际应用题】分类详解提升必学必练!...
  9. eclipse使用git合并_Eclipse中使用git
  10. Xamarin Essentials教程发送邮件Email