飙车资深老教练 - 手撸一个 EventBus
- 2022 年 7 月 13 日
本文字数:5347 字
阅读完需:约 18 分钟

👉关于作者
众所周知,人生是一个漫长的流程,不断克服困难,不断反思前进的过程。在这个过程中会产生很多对于人生的质疑和思考,于是我决定将自己的思考,经验和故事全部分享出来,以此寻找共鸣!!!专注于 Android/Unity 和各种游戏开发技巧,以及各种资源分享(网站、工具、素材、源码、游戏等)
👉即将学会
经过前面两节内容学习,我们已经学会了 EventBus 很多的内容,今天小空带你自己手撸一个这种框架。
👉背景
🙈小空(坏笑):小芝,昨天和前天的内容学习的怎么样啦。
🙎小芝(😝):还用说吗,肯定没学会啊。
🙈小空(😎):好,今天我们继续,直接自己写一个类似框架。
🙎小芝(😥):等等,我说的是没学会啊。啊?
👉实践过程
基本的反射调用
首先是事件总线的工具类,我们需要管理的有很多,所以有必要泛型一下
public static EventCar eventCar;private EventCar() { }单例完,就是 add,remove 等类似注册解注册的方法了,因为需要 Activity/Fragment 等类型,所以使用 obj 类型合适
private ArrayList<Object> objects = new ArrayList<Object>(); public void add(Object object){ objects.add(object);} public void remove(Object object){ objects.remove(object); }这个时候基本的注册反注册就上线了,调用我们上面刚写的两个方法。
@Overrideprotected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); initView(); EventCar.getInstance().add(this);} @Overrideprotected void onDestroy() { EventCar.getInstance().remove(this); super.onDestroy();}小关键来了,这个时候函数的反射调用要上了,因为不止 Activity,所以我们要将里面分清楚
public void post(T obj) { for (Object object : objects) { //在这区分了activity fragment等 if (object instanceof Activity) { Activity activity= (Activity) object; Class<? extends Activity> cls =activity.getClass(); try { Method declaredMethod = cls.getDeclaredMethod("receive", obj.getClass()); //""内的方法名之自定的 declaredMethod.invoke(activity, (Object) obj); } catch (InvocationTargetException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } catch (NoSuchMethodException e) { e.printStackTrace(); } } }}好了,我们小小的实验一下。看看能否出现效果
public void receive(MessageEvent msg) { Log.e("TAG","接受到了消息"+msg.getName());} @Overrideprotected void onDestroy() { EventCar.getInstance().remove(this); super.onDestroy();} @Overridepublic void onClick(View v) { switch (v.getId()) { default: break; case R.id.ceshi: EventCar.getInstance().post(new MessageEvent("空名先生")); break; }}运行,结果出现
恩,效果可看,让我们继续的深入。
指定接收线程
@Target(ElementType.METHOD)@Retention(RetentionPolicy.RUNTIME)public @interface Process { int value() default 0; }我们调用一下看看
@Process(EventCar.SubThread) //内容在EventCar中有定义 public void receive(MessageEvent msg) { Log.e("TAG","接受到了消息"+msg.getName());}回到 EventCar 中补全逻辑
final Method declaredMethod = cls.getDeclaredMethod("receive", obj.getClass()); //""内的方法名之自定的Annotation[] annotations = declaredMethod.getAnnotations();for(Annotation annotation : annotations){ //因为类可能不止一个标记 ,遍历获得对应的Process标记注解 if(annotation.annotationType() == Process.class){ Process process = (Process)annotation; value = process.value(); }} if(value == MainThread){ activity.runOnUiThread(new Runnable() { //在ui线程 @Override public void run() { try { declaredMethod.invoke(activity, (Object) obj); } catch (IllegalAccessException e) { e.printStackTrace(); } catch (InvocationTargetException e) { e.printStackTrace(); } } });}else if(value == SubThread){ new Thread(new Runnable() { //如果在子线程的话 @Override public void run() { try { declaredMethod.invoke(activity, (Object) obj); } catch (IllegalAccessException e) { e.printStackTrace(); } catch (InvocationTargetException e) { e.printStackTrace(); } } }).start();}去测试下,咦,还是没问题;
好,满足了 activity 的 就该有 fragment/activity/service 各种交叉通信,这也是上面我们使用泛型和 obj 类型的原因
最终修补完善 EventCar:
public void post(final T obj) { for (Object object : objects) { //在这区分了activity fragment等 int value = 0; if (object instanceof Activity) { final Activity activity = (Activity) object; Class<? extends Activity> cls = activity.getClass(); try { final Method declaredMethod = cls.getDeclaredMethod("receive", obj.getClass()); //""内的方法名之自定的 Annotation[] annotations = declaredMethod.getAnnotations(); for (Annotation annotation : annotations) { //因为类可能不止一个标记 ,遍历获得对应的Process标记注解 if (annotation.annotationType() == Process.class) { Process process = (Process) annotation; value = process.value(); } } if (value == MainThread) { activity.runOnUiThread(new Runnable() { //在ui线程 @Override public void run() { try { declaredMethod.invoke(activity, (Object) obj); } catch (IllegalAccessException e) { e.printStackTrace(); } catch (InvocationTargetException e) { e.printStackTrace(); } } }); } else if (value == SubThread) { new Thread(new Runnable() { //如果在子线程的话 @Override public void run() { try { declaredMethod.invoke(activity, (Object) obj); } catch (IllegalAccessException e) { e.printStackTrace(); } catch (InvocationTargetException e) { e.printStackTrace(); } } }).start(); } } catch (NoSuchMethodException e) { e.printStackTrace(); } } else if (object instanceof Fragment) { final Fragment fragment = (Fragment) object; Class<? extends Fragment> cls = fragment.getClass(); try { final Method declaredMethod = cls.getDeclaredMethod("receive", obj.getClass()); Annotation[] annotations = declaredMethod.getAnnotations(); for (Annotation annotation : annotations) { if (annotation.annotationType() == Process.class) { Process process = (Process) annotation; value = process.value(); } } if (value == MainThread) { fragment.getActivity().runOnUiThread(new Runnable() { @Override public void run() { try { declaredMethod.invoke(fragment, (Object) obj); } catch (IllegalAccessException e) { e.printStackTrace(); } catch (InvocationTargetException e) { e.printStackTrace(); } } }); } else if (value == SubThread) { new Thread(new Runnable() { @Override public void run() { try { declaredMethod.invoke(fragment, (Object) obj); } catch (IllegalAccessException e) { e.printStackTrace(); } catch (InvocationTargetException e) { e.printStackTrace(); } } }).start(); } } catch (NoSuchMethodException e) { e.printStackTrace(); } } else if (object instanceof Service) { final Service service = (Service) object; Class<? extends Service> cls = service.getClass(); try { final Method declaredMethod = cls.getDeclaredMethod("receive", obj.getClass()); Annotation[] annotations = declaredMethod.getAnnotations(); for (Annotation annotation : annotations) { if (annotation.annotationType() == Process.class) { Process process = (Process) annotation; value = process.value(); } } if (value == MainThread) { try { declaredMethod.invoke(service, (Object) obj); } catch (IllegalAccessException e) { e.printStackTrace(); } catch (InvocationTargetException e) { e.printStackTrace(); } } else if (value == SubThread) { new Thread(new Runnable() { @Override public void run() { try { declaredMethod.invoke(service, (Object) obj); } catch (IllegalAccessException e) { e.printStackTrace(); } catch (InvocationTargetException e) { e.printStackTrace(); } } }).start(); } } catch (NoSuchMethodException e) { e.printStackTrace(); } } }}👉其他
📢作者:小空和小芝中的小空
📢转载说明-务必注明来源:https://www.infoq.cn/profile/DB2492B85795C4/publish
📢这位道友请留步☁️,我观你气度不凡,谈吐间隐隐有王者霸气💚,日后定有一番大作为📝!!!旁边有点赞👍收藏🌟今日传你,点了吧,未来你成功☀️,我分文不取,若不成功⚡️,也好回来找我。
版权声明: 本文为 InfoQ 作者【芝麻粒儿】的原创文章。
原文链接:【http://xie.infoq.cn/article/79c3d57958f02ace970f32e40】。文章转载请联系作者。
芝麻粒儿
尺有所短;寸有所长。 2020.08.29 加入
👑CSDN博客专家-华为云享专家-Android/Unity领域优质作者 🏅目前在模拟医学行业做Android/Unity双端开发 🏆微信公众号:【空名先生】 🏆QQ交流群:204918251或877807592










评论