EventBus源码解析一,阿里Android开发面试解答

视频:https://study.163.com/course/courseLearn.htm?courseId=1209174836#/learn/video?lessonId=1278769701&courseId=1209174836

手写EventBus框架——源码分析1(2017年写的,参照3.0版本)

1、EventBus概述

============

1.1、两种概述


1.1.1、概述一

图一:

1.1.2、概述二

图二:

EventBus除了可以在四大组件之间通信外,还可以在异步线程与主线程之间进行通信。

EventBus流程图(官网):

1.2、常见的组件间通信方式


  1. Intent

  2. Handler

  3. Interface

  4. BroadcastReceiver

  5. AIDL

  6. Messenger

1.3、思考


1.3.1、一种思路:

1.3.2、EventBus的优点

2、使用

====

2.1、引入依赖:


implementation ‘org.greenrobot:eventbus:3.1.1’

2.2、使用:


/**

  • Created by songzi522 on 2019/12/9.

  • 定义事件

*/

public class MyBusEvent {

public final String message;

public MyBusEvent(String message) {

this.message = message;

}

}

public class EventBusTest3Activity extends AppCompatActivity {

@BindView(R.id.btn1)

Button btn1;

@BindView(R.id.btn2)

Button btn2;

@BindView(R.id.btn3)

Button btn3;

@BindView(R.id.btn4)

Button btn4;

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_event_bus_test3);

ButterKnife.bind(this);

}

@OnClick({R.id.btn1, R.id.btn2, R.id.btn3, R.id.btn4})

public void onViewClicked(View view) {

switch (view.getId()) {

case R.id.btn1:

EventBus.getDefault().postSticky(new MyBusEvent(“Hello Android”));

break;

case R.id.btn2:

break;

case R.id.btn3:

break;

case R.id.btn4:

break;

}

}

// EventBus 的注册与注销最好与Activity和Fragment的生命周期绑定

@Override

protected void onStart() {

super.onStart();

EventBus.getDefault().register(this);

}

@Override

protected void onStop() {

super.onStop();

EventBus.getDefault().unregister(this);

}

// 订阅 事件 准备订阅者

@Subscribe(threadMode = ThreadMode.MAIN)

public void onMessageEvent(MyBusEvent event) {

SmartToast.show(event.message);

}

}

3、自己手写一个EventBus

================

3.1、GsEventBus.java


/**

  • Created by songzi522 on 2019/12/11.

  • 自己手写一个 EventBus

  • 该类可以理解为一个专门负责管理 需要传递的事件 的管理类

  • Activity1(事件发送方)把事件传递给 GsEventBus

  • Activity2(事件接收方)把接受事件传递的方法传给 GsEventBus

  • 所有的事情都由 GsEventBus 来处理,与 Activity1 和 Activity2 无关

  • 因此,第一,GsEventBus 得是一个单例模式

*/

public class GsEventBus {

//定义一个用来装方法的容器

private Map<Object, List> cacheMap;

private static volatile GsEventBus instance;

// 用来切换线程

private Handler mHandler;

private GsEventBus() {

cacheMap = new HashMap<>();

mHandler = new Handler();

}

public static GsEventBus getDefault() {

if (instance == null) {

synchronized (GsEventBus.class) {

if (instance == null) {

instance = new GsEventBus();

}

}

}

return instance;

}

/**

  • 当我们调用 register 方法的时候,就把接收消息的方法放到 cacheMap 中

  • @param object

*/

public void register(Object object) {

List list = cacheMap.get(object);

if (list == null) {

list = findGsSubscribeMethods(object);

cacheMap.put(object, list);

}

}

private List findGsSubscribeMethods(Object object) {

List list = new ArrayList<>();

//获取 activity

Class<?> clazz = object.getClass();

// 除了获取当前activity的有添加注解的方法,它的父类中如果有添加注解的方法,也要放进list

while (clazz != null) {

// 过滤作用:凡是系统级别的父类,直接省略

String name = clazz.getName();

if (name.startsWith(“java.”) || name.startsWith(“javax.”) || name.startsWith(“android.”)) {

break;

}

//获取 activity 中的所有方法

Method[] methods = clazz.getDeclaredMethods();

for (Method method : methods) {

//找到带有 GsSubscribe 的方法

GsSubscribe gsSubscribe = method.getAnnotation(GsSubscribe.class);

//如果为空,我们就继续寻找下一个

if (gsSubscribe == null) {

continue;

}

//如果找到的话,我们就判断带有 GsSubscribe 注解的方法中的参数类型

Class<?>[] types = method.getParameterTypes();

//用以限制 传递事件的方法有且只有一个参数

if (types.length != 1) {

LogUtils.e(“GsEventBus only accept one parameter”);

}

// 判断线程类型

GsThreadMode gsThreadMode = gsSubscribe.gsThreadMode();

// 封装

GsSubscribeMethod gsSubscribeMethod = new GsSubscribeMethod(method, gsThreadMode, types[0]);

list.add(gsSubscribeMethod);

}

// 转到当前activity的父类中

clazz = clazz.getSuperclass();

}

return list;

}

public void unRegister(Object object) {

}

public void post(Object type) {

//直接循环 cacheMap,然后找到对应的方法进行回调

Set set = cacheMap.keySet();

Iterator iterator = set.iterator();

while (iterator.hasNext()) {

Object object = iterator.next();

//找到对应的activity中的含有注解的方法列表

List list = cacheMap.get(object);

for (GsSubscribeMethod gsSubscribeMethod : list) {

// 比对 post传递的参数对象与接收信息的方法的参数对象是否相同

if (gsSubscribeMethod.getType().isAssignableFrom(type.getClass())) {

// 判断在哪个线程

switch (gsSubscribeMethod.getmGsThreadMode()) {

case MAIN:

// 主线程 --> 主线程

if (Looper.myLooper() == Looper.getMainLooper()) {

invoke(gsSubscribeMethod, object, type);

}else { // 子线程 --> 主线程

mHandler.post(() ->

invoke(gsSubscribeMethod, object, type));

}

break;

case BACKGRUOND:

// 主线程 --> 子线程

// 子线程 --> 子线程

break;

}

}

}

}

}

private void invoke(GsSubscribeMethod gsSubscribeMethod, Object object, Object type) {

Method method = gsSubscribeMethod.getmMethod();

try {

method.invoke(object, type);

} catch (IllegalAccessException e) {

e.printStackTrace();

} catch (InvocationTargetException e) {

e.printStackTrace();

}

}

}

3.2、GsSubscribe


/**

  • Created by songzi522 on 2019/12/11.

  • 注解类,作用:一个标记,它标记的方法都将被GsEventBus收录

*/

// 表示注解的是一个方法

@Target(ElementType.METHOD)

// 表示它是运行时的注解

@Retention(RetentionPolicy.RUNTIME)

public @interface GsSubscribe {

GsThreadMode gsThreadMode() default GsThreadMode.MAIN;

}

自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数Android工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年Android移动开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
img
img
img
img
img
img
img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Android开发知识点,真正体系化!

由于文件比较大,这里只是将部分目录大纲截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且后续会持续更新

如果你觉得这些内容对你有帮助,可以添加V获取:vip204888 (备注Android)
img

Android高级架构师

由于篇幅问题,我呢也将自己当前所在技术领域的各项知识点、工具、框架等汇总成一份技术路线图,还有一些架构进阶视频、全套学习PDF文件、面试文档、源码笔记。

  • 330页PDF Android学习核心笔记(内含上面8大板块)

  • Android学习的系统对应视频

  • Android进阶的系统对应学习资料

  • Android BAT部分大厂面试题(有解析)

好了,以上便是今天的分享,希望为各位朋友后续的学习提供方便。觉得内容不错,也欢迎多多分享给身边的朋友哈。

本文已被CODING开源项目:《Android学习笔记总结+移动架构视频+大厂面试真题+项目实战源码》收录

一个人可以走的很快,但一群人才能走的更远。如果你从事以下工作或对以下感兴趣,欢迎戳这里加入程序员的圈子,让我们一起学习成长!

AI人工智能、Android移动开发、AIGC大模型、C C#、Go语言、Java、Linux运维、云计算、MySQL、PMP、网络安全、Python爬虫、UE5、UI设计、Unity3D、Web前端开发、产品经理、车载开发、大数据、鸿蒙、计算机网络、嵌入式物联网、软件测试、数据结构与算法、音视频开发、Flutter、IOS开发、PHP开发、.NET、安卓逆向、云计算

(img-Tl0HYjqa-1712173381268)]

  • Android学习的系统对应视频

  • Android进阶的系统对应学习资料

[外链图片转存中…(img-6zle0wmh-1712173381268)]

  • Android BAT部分大厂面试题(有解析)

[外链图片转存中…(img-4ZYJRBYN-1712173381268)]

好了,以上便是今天的分享,希望为各位朋友后续的学习提供方便。觉得内容不错,也欢迎多多分享给身边的朋友哈。

本文已被CODING开源项目:《Android学习笔记总结+移动架构视频+大厂面试真题+项目实战源码》收录

一个人可以走的很快,但一群人才能走的更远。如果你从事以下工作或对以下感兴趣,欢迎戳这里加入程序员的圈子,让我们一起学习成长!

AI人工智能、Android移动开发、AIGC大模型、C C#、Go语言、Java、Linux运维、云计算、MySQL、PMP、网络安全、Python爬虫、UE5、UI设计、Unity3D、Web前端开发、产品经理、车载开发、大数据、鸿蒙、计算机网络、嵌入式物联网、软件测试、数据结构与算法、音视频开发、Flutter、IOS开发、PHP开发、.NET、安卓逆向、云计算

  • 9
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值