Android 进阶4:EventBus3.0源码分析

前几篇文章分析了Activity的源码,后来看了看Window以及ViewRoot的相关源码,这些只是还没梳理,真的是视觉疲劳,来一个EventBus源码分析压压惊~。

其实关于EventBus的源码分析,网上也有很多,但是终究是别人的,以前也看过很多遍,但是决定是自己写下来比较好,座右铭:看一遍,不如自己写一遍。
关于EventBus的小总结我们先看下,带着知识点去看源码,然后分析为什么要这么写,还是必须这样写。

  1. POSTING:发布事件和订阅事件总是在一个线程。避免操作UI,可能造成ANR。
  2. MAIN : 无论发布事件位于什么线程,订阅事件总是在UI主线程
  3. BACKGROUND: 发布事件位于子线程,那么订阅事件就位于该子线程;如果发布事件位于Ui主线程,那么订阅事件就另外开启一个子线程。订阅事件方法中不能更新UI。
  4. ASYNC:无论发布事件位于什么线程,订阅事件总是位于另外在开启子线程。
  5. EventBus索引的添加
  6. 有这样一个场景:我们的EventModel A 继承自EventModel B,并实现了接口EventInterface C,此时在订阅类中,三个订阅方法参数分别为:EventModel A, EventModel B , EventInterface;最后在发布事件 EventModel A, 此时的结果应该是:三个订阅方法都能够收到事件。但是如果我们只想让参数为EventModel A订阅方法收到事件,应该怎么做? 详情看代码描述
  7. EventBus发送粘性事件,等等,说一下粘性时间,ActivityA 先创建,然后发送粘性事件,然后创建并跳转到ActivityB,此时在ActivityB注册了粘性事件的回调方法,此时粘性回调方法将执行,这是什么原理?
  8. 同一个订阅类如果注册两次为什么报错?

问题点6代码描述:

    @Subscribe(threadMode = ThreadMode.MAIN , sticky = true)
    public void onEventObject(EventModelA object) {
        Log.e("-----------","我是子类");
    }

    @Subscribe(threadMode =  ThreadMode.MAIN, sticky = true)
    public void onEventObject(EventModelB event) {
        Log.e("-----------","我是父类");
    }

    @Subscribe(threadMode =  ThreadMode.MAIN, sticky = true)
    public void onEventObject(EventInterfaceC event) {
        Log.e("-----------","我是父接口");
    }
EventBus.getDefault().postSticky(new EventModelA ());

EventBus 的 register(this) 方法

    /**
     * Registers the given subscriber to receive events. Subscribers must call {@link #unregister(Object)} once they
     * are no longer interested in receiving events.
     * <p/>
     * Subscribers have event handling methods that must be annotated by {@link Subscribe}.
     * The {@link Subscribe} annotation also allows configuration like {@link
     * ThreadMode} and priority.
     */
     /*
     翻译:注册给定的订阅服务用于接收事件,订阅者必须调用unregister取消注册对象。
     			订阅服务器有事件处理方法,这些方法需要有ThreadModel(线程模式)和优先级的配置
     */
    public void register(Object subscriber) {
    
        //获取订阅者的Class对象
        Class<?> subscriberClass = subscriber.getClass();
        
        //通过这个类对象获取SubscriberMethod的集合,至于集合是什么后面讲到。
        List<SubscriberMethod> subscriberMethods = subscriberMethodFinder.findSubscriberMethods(subscriberClass);
        synchronized (this) {
        
        //遍历SubscriberMethods集合,执行subscribe方法,参数为:订阅者的类和subscriberMethod。
            for (SubscriberMethod subscriberMethod : subscriberMethods) {
                subscribe(subscriber, subscriberMethod);
            }
        }
    }

register的注释翻译,这个不需要解释了, 方法内,先获取了订阅类的Class对象,把这个Class对象为参数,通过
findSubscriberMethods(Class) 方法获取到List集合泛型为SubscriberMethod, 从findSubscriberMethods方法名来看,就是:找到订阅的方法。 至于这个方法是怎么工作的我们下文分析。有必要看下SubscriberMethod类了:

/** Used internally by EventBus and generated subscriber indexes. */
public class SubscriberMethod {
    final Method method; //Java通过反射获取到的订阅类的信息
    final ThreadMode threadMode; //订阅类中订阅方法的线程模型TreadMode
    final Class<?> eventType; //订阅方法参数的Class对象,也就是我们的Model的Class对象
    final int priority; //订阅回调方法的优先级
    final boolean sticky; //订阅回调方法是否是粘性的
    /** Used for efficient comparison */
    String methodString; //订阅方法的方法名
	.........

通过代码可以看出 SubscriberMethod 其实就是一个Model类,它代表了:某一个订阅类的订阅方法信息。
那么回过头看下findSubscriberMethods(Class)就是:返回某一个注册订阅类的订阅方法的集合。然后接下来遍历这个集合,执行subscribe方法,参数为:订阅类(subscriber)和其某一个订阅的方法(subscriberMethod);

    private void subscribe(Object subscriber, SubscriberMethod subscriberMethod) {
    	//获得订阅方法的Class对象。
        Class<?> eventType = subscriberMethod.eventType;
        
        //创建Subscription,参数为:订阅者(subscriber)和订阅方法的信息类(subscriberMethod)
        Subscription newSubscription = new Subscription(subscriber, subscriberMethod);
        
        //subscriptionsByEventType获得CopyOnWriteArrayList集合,泛型为Subscription
        //eventType就是注册回调方法类的参数的Class对象,也就是上述例子中的:EventModelA的Class对象
        //subscriptions也就是所有包含该回调方法的订阅类和该回调方法的信息集合
        CopyOnWriteArrayList<Subscription> subscriptions = subscriptionsByEventType.get(eventType);
        if (subscriptions == null) {
          //以该参数Class为Key值的Value是null,也就是同一进程中这是这个订阅类是第一个使用该Model为参数的回调方法
            subscriptions 
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
大学生参加学科竞赛有着诸多好处,不仅有助于个人综合素质的提升,还能为未来职业发展奠定良好基础。以下是一些分析: 首先,学科竞赛是提高专业知识和技能水平的有效途径。通过参与竞赛,学生不仅能够深入学习相关专业知识,还能够接触到最新的科研成果和技术发展趋势。这有助于拓展学生的学科视野,使其对专业领域有更深刻的理解。在竞赛过程中,学生通常需要解决实际问题,这锻炼了他们独立思考和解决问题的能力。 其次,学科竞赛培养了学生的团队合作精神。许多竞赛项目需要团队协作来完成,这促使学生学会有效地与他人合作、协调分工。在团队合作中,学生们能够学到如何有效沟通、共同制定目标和分工合作,这对于日后进入职场具有重要意义。 此外,学科竞赛是提高学生综合能力的一种途径。竞赛项目通常会涉及到理论知识、实际操作和创新思维等多个方面,要求参赛者具备全面的素质。在竞赛过程中,学生不仅需要展现自己的专业知识,还需要具备创新意识和解决问题的能力。这种全面的综合能力培养对于未来从事各类职业都具有积极作用。 此外,学科竞赛可以为学生提供展示自我、树立信心的机会。通过比赛的舞台,学生有机会展现自己在专业领域的优势,得到他人的认可和赞誉。这对于培养学生的自信心和自我价值感非常重要,有助于他们更加积极主动地投入学习和未来的职业生涯。 最后,学科竞赛对于个人职业发展具有积极的助推作用。在竞赛中脱颖而出的学生通常能够引起企业、研究机构等用人单位的关注。获得竞赛奖项不仅可以作为个人履历的亮点,还可以为进入理想的工作岗位提供有力的支持。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值