EventBus源码解析一,安卓面试项目

EventBus源码解析一,安卓面试项目

1.3.2、EventBus的优点

EventBus源码解析一,安卓面试项目

2、使用

====

EventBus源码解析一,安卓面试项目

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)

最后相关架构及资料领取方式:

点击我的GitHub免费领取获取往期Android高级架构资料、源码、笔记、视频。高级UI、性能优化、架构师课程、NDK、混合式开发(ReactNative+Weex)微信小程序、Flutter全方面的Android进阶实践技术,群内还有技术大牛一起讨论交流解决问题。

上一篇:Vue eventBus组件通信使用方法(转载)


下一篇:MASA Framework - EventBus设计