EventBus源码解析一

  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;

}

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;

}

《设计思想解读开源框架》

第一章、 热修复设计

  • 第一节、 AOT/JIT & dexopt 与 dex2oat

  • 第二节、 热修复设计之 CLASS_ISPREVERIFIED 问题

  • 第三节、热修复设计之热修复原理

  • 第四节、Tinker 的集成与使用(自动补丁包生成)

    第二章、 插件化框架设计

  • 第一节、 Class 文件与 Dex 文件的结构解读

  • 第二节、 Android 资源加载机制详解

  • 第三节、 四大组件调用原理

  • 第四节、 so 文件加载机制

  • 第五节、 Android 系统服务实现原理

    第三章、 组件化框架设计

  • 第一节、阿里巴巴开源路由框——ARouter 原理分析

  • 第二节、APT 编译时期自动生成代码&动态类加载

  • 第三节、 Java SPI 机制

  • 第四节、 AOP&IOC

  • 第五节、 手写组件化架构

    第四章、图片加载框架

  • 第一节、图片加载框架选型

  • 第二节、Glide 原理分析

  • 第三节、手写图片加载框架实战

    第五章、网络访问框架设计

  • 第一节、网络通信必备基础

  • 第二节、OkHttp 源码解读

  • 第三节、Retrofit 源码解析

    第六章、 RXJava 响应式编程框架设计

  • 第一节、链式调用

  • 第二节、 扩展的观察者模式

  • 第三节、事件变换设计

  • 第四节、Scheduler 线程控制

    第七章、 IOC 架构设计

  • 第一节、 依赖注入与控制反转

  • 第二节、ButterKnife 原理上篇、中篇、下篇

  • 第三节、Dagger 架构设计核心解密

    第八章、 Android 架构组件 Jetpack

  • 第一节、 LiveData 原理

  • 第二节、 Navigation 如何解决 tabLayout 问题

  • 第三节、 ViewModel 如何感知 View 生命周期及内核原理

  • 第四节、 Room 架构方式方法

  • 第五节、 dataBinding 为什么能够支持 MVVM

  • 第六节、 WorkManager 内核揭秘

  • 第七节、 Lifecycles 生命周期


    本文包含不同方向的自学编程路线、面试题集合/面经、及系列技术文章等,资源持续更新中…

加入社区》https://bbs.csdn.net/forums/4304bb5a486d4c3ab8389e65ecb71ac0
件变换设计**

  • 第四节、Scheduler 线程控制

    [外链图片转存中…(img-QG8NuWlD-1725769174677)]

    第七章、 IOC 架构设计

  • 第一节、 依赖注入与控制反转

  • 第二节、ButterKnife 原理上篇、中篇、下篇

  • 第三节、Dagger 架构设计核心解密

    [外链图片转存中…(img-XnZSFtJU-1725769174677)]

    第八章、 Android 架构组件 Jetpack

  • 第一节、 LiveData 原理

  • 第二节、 Navigation 如何解决 tabLayout 问题

  • 第三节、 ViewModel 如何感知 View 生命周期及内核原理

  • 第四节、 Room 架构方式方法

  • 第五节、 dataBinding 为什么能够支持 MVVM

  • 第六节、 WorkManager 内核揭秘

  • 第七节、 Lifecycles 生命周期

    [外链图片转存中…(img-4tkDZ5dn-1725769174678)]
    本文包含不同方向的自学编程路线、面试题集合/面经、及系列技术文章等,资源持续更新中…
    [外链图片转存中…(img-0GMHiJ0M-1725769174678)]

加入社区》https://bbs.csdn.net/forums/4304bb5a486d4c3ab8389e65ecb71ac0

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值