看看代码-EventBus

看看代码-EventBus

EventBus是一个非常有名的Android开源项目,能非常方便地对应用内消息进行分发和处理,因近期在看消息通道相关的东西,就看了下代码学习一下,项目地址:EventBus

使用方法

gradle项目中加入dependencies即可使用:

dependencies {
    compile 'org.greenrobot:eventbus:3.1.1'

}

在需要注册的地方使用register方法注册,并给需要接受和处理消息的方法加上Subscribe注解

public class MainActivity extends AppCompatActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        EventBus.getDefault().register(this);
        // 在post方法执行后,onMessageEvent将会收到消息,并且打出对应的Log
        EventBus.getDefault().post(new MessageEvent());
    }

    public interface IMessageEvent{
        void print();
    }

    public abstract static class AbstractMessageEvent {

    }

    public static class MessageEvent extends AbstractMessageEvent implements IMessageEvent{
        @Override
        public void print() {
            Log.d("onMessageEvent","Received.");
        }
    }

    @Subscribe(threadMode = ThreadMode.MAIN)
    public void onMessageEvent(MessageEvent event) {
        event.print();
    }
}

架构概览

image.png

原理分析

EventBus主要使用了观察者模式进行系统的设计。在EventBus中,我们把观察者对象称为订阅者Subscriber,前面的例子中,MainActivity就是一个Subscriber

onMessageEvent则是一个SubscribeMethod

查看EventBus的源码,在EventBus.class中有几个比较重要的变量

eventTypesChahe : 存储Event.class相关的类,包括Event类的父类、以及其实现的接口类

subscriptionsByEventType : 消息-该消息的订阅 的Map,根据发送的消息类型,可以获取到所有的Subscription(一个Subscription由一个Subscriber和一个SubscribeMethod组成) 。

typesBySubscriber:消息-订阅该消息的订阅者类型列表Class(订阅者的对象类型)的Map,根据指定的消息类型,可以找到所有的订阅者类型

register过程

重点方法在register跟subscribe中,主要流程:

EventBust.getDefault().register(Subscriber)

r

  1. 找到Subscriber中所有需要接收消息的方法(SubscriberMethod),以及这些方法接受的消息种类。 这一个步在SubscriberMethodFinder中完成
  2. 将订阅者和订阅方法封装成订阅(SUbscription)并存储在subscriptionsByEventType中
  3. 将消息类型和订阅者类型进行关联,存储在typesBySubscriber

post过程

在subscriptionsByEventType中找到Subscription并取出Subscriber和SubscribMethod,根据设置线程模式的不同,使用不同的Poster,在对应的线程中对订阅方法进行反射调用,实现消息接收和处理

总结

EventBus通过对订阅者和发布者的解耦,简化了消息发送和注册的流程,且消息主体可以为任意类的对象,使得消息虽然在EventBus中进行统一的分发和管理,但并不需要在同一地方集中注册和索引。

EventBus的代码量不多,算是一个比较轻量的框架,暂不支持跨进程的消息传递,且由于EventBus中维护的Subscriber引用都是强引用,没有及时unregister的话,可能会导致内存泄漏。

原创声明,本文系作者授权云+社区发表,未经许可,不得转载。

如有侵权,请联系 yunjia_community@tencent.com 删除。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏Android知识点总结

1-EI-灵魂画手解释安卓的Message对象

442
来自专栏公有云大数据平台弹性MapReduce

Hbase 调优之 RPC

本文暂时先研究了hbaserpc部分的代码,rpc作为调用的入口,先从入口处明白原理以及内部实际控制参数进行调整来满足自己的以为需要。

1.4K0
来自专栏Java学习123

Java中的日志——Java.util.logging、log4j、commons-logging

2439
来自专栏Java与Android技术栈

基于RxJava2实现的简单图片爬虫

今年十月份以来,跟朋友尝试导入一些图片到tensorflow来生成模型,这就需要大量的图片。刚开始我只写了一个简单的HttpClient程序来抓取图片,后来为了...

842
来自专栏XAI

微信二次开发Java自定义菜单事件实现

微信二次开发--java http://blog.csdn.net/lyq8479/ 这个是柳峰的CSDN博客。大家可以看大神的教程。里面有所有的代码。 项目整...

5176
来自专栏向治洪

系统捕获异常并发送到服务器

大家都知道,现在安装Android系统的手机版本和设备千差万别,在模拟器上运行良好的程序安装到某款手机上说不定就出现崩溃的现象,开发者个人不可能购买所有设备逐个...

1867
来自专栏沃趣科技

复制状态与变量记录表 | performance_schema全方位介绍

不知不觉中,performance_schema系列快要接近尾声了,今天将带领大家一起踏上系列第六篇的征程(全系共7个篇章),在这一期里,我们将为大家全面讲解p...

1323
来自专栏偏前端工程师的驿站

JAVA魔法堂:读取.properties配置文件

一、前言                                 Java工程中想log4j、数据库连接等配置信息一般都写在.properties文件中...

1855
来自专栏向治洪

IntentService简介

在manifest中声明服务 和activity、content provider一样,服务也必须要在AndroidManifest文件中进行声明是<app...

17210
来自专栏飞雪无情的博客

Go语言实战笔记(十五)| Go 并发示例-Runner

这篇通过一个例子,演示使用通道来监控程序的执行时间,生命周期,甚至终止程序等。我们这个程序叫runner,我们可以称之为执行者,它可以在后台执行任何任务,而且我...

543

扫码关注云+社区