EventBus源码解析一,华为的面试流程是怎样的分五步走

  • 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;

}

3.3、GsSubscribeMethod.java


/**

  • Created by songzi522 on 2019/12/11.

  • 用来封装需要 GsEventBus 保存的方法

*/

public class GsSubscribeMethod {

//回调方法

private Method mMethod;

//线程模式

private GsThreadMode mGsThreadMode;

//回调方法中的参数类型

private Class<?> type;

public GsSubscribeMethod(Method mMethod, GsThreadMode mGsThreadMode, Class<?> type) {

this.mMethod = mMethod;

this.mGsThreadMode = mGsThreadMode;

this.type = type;

}

public Method getmMethod() {

return mMethod;

}

public void setmMethod(Method mMethod) {

this.mMethod = mMethod;

}

public GsThreadMode getmGsThreadMode() {

return mGsThreadMode;

}

public void setmGsThreadMode(GsThreadMode mGsThreadMode) {

this.mGsThreadMode = mGsThreadMode;

}

public Class<?> getType() {

return type;

}

public void setType(Class<?> type) {

this.type = type;

}

}

3.4、GsThreadMode


/**

  • Created by songzi522 on 2019/12/11.

  • 一个枚举类,它代表EventBus通过post发送消息时,接收的线程是在主线程还是子线程

*/

public enum GsThreadMode {

MAIN,

BACKGRUOND

}

3.5、EventBusTest4Activity.java


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

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

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

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

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

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

最后

最后这里放上我这段时间复习的资料,这个资料也是偶然一位朋友分享给我的,里面包含了腾讯、字节跳动、阿里、百度2020-2021面试真题解析,并且把每个技术点整理成了视频和PDF(知识脉络 + 诸多细节)。

还有 高级架构技术进阶脑图、高级进阶架构资料 帮助大家学习提升进阶,这里我也免费分享给大家也节省大家在网上搜索资料的时间来学习,也可以分享给身边好友一起学习。

一起互勉~

一个人可以走的很快,但一群人才能走的更远。不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎扫码加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
img
95%以上Android开发知识点,真正体系化!**

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

如果你觉得这些内容对你有帮助,可以添加V获取:vip204888 (备注Android)
[外链图片转存中…(img-MkBM1dZ6-1712785115175)]

最后

最后这里放上我这段时间复习的资料,这个资料也是偶然一位朋友分享给我的,里面包含了腾讯、字节跳动、阿里、百度2020-2021面试真题解析,并且把每个技术点整理成了视频和PDF(知识脉络 + 诸多细节)。

还有 高级架构技术进阶脑图、高级进阶架构资料 帮助大家学习提升进阶,这里我也免费分享给大家也节省大家在网上搜索资料的时间来学习,也可以分享给身边好友一起学习。

[外链图片转存中…(img-1BrnFq9O-1712785115176)]

[外链图片转存中…(img-ktfoo3BI-1712785115176)]

一起互勉~

一个人可以走的很快,但一群人才能走的更远。不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎扫码加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
[外链图片转存中…(img-Fv0smHUO-1712785115176)]

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值