EventBus机制

1.EventBus是一个单例

public static EventBus getDefault() {
    if (defaultInstance == null) {
        synchronized (EventBus.class) {
            if (defaultInstance == null) {
                defaultInstance = new EventBus();
            }
        }
    }
    return defaultInstance;
}

2.构造方法

实例化一个集合放置订阅方法,事件类型等…
实例化Poster,处理不同线程的问题,具体在第五步

1)mainThreadPoster

public class HandlerPoster extends Handler implements Poster{}
如何生成HandlerPoster代码省略

以上,mainThreadPoster是一个Handler类继承了Poster接口,
其中Handler持有的Looper是主线程Looper,
所以mainThreadPoster的handleMessage()方法会在主线程执行

2)backgroundPoster

final class BackgroundPoster implements Runnable, Poster {}

3)asyncPoster

class AsyncPoster implements Runnable, Poster {}

以上继承Runnable接口,
所以(2)+(3)poster会在工作线程执行

3.register

public void register(Object subscriber) {
    Class<?> subscriberClass = subscriber.getClass();
    //通过反射找到注册类所有含有@Subscribe注解的公共方法
    List<SubscriberMethod> subscriberMethods = subscriberMethodFinder.findSubscriberMethods(subscriberClass);
    synchronized (this) {
        for (SubscriberMethod subscriberMethod : subscriberMethods) {
            //注册类订阅
            subscribe(subscriber, subscriberMethod);
        }
    }
}

通过反射找到注册类所有含有@Subscribe注解的公共方法
并调用subscribe()

4.subscribe(注册调用的方法)

private void subscribe(Object subscriber, SubscriberMethod subscriberMethod) {
    //1.实例化subscriptionsByEventType:Map<事件对象,订阅方法>,就是将带有@Subscribe注解的公共方法按优先级顺序放进这个Map中
    //  每个订阅方法都是subscriptionsByEventType中的一项
    //2.实例化typesBySubscriber:Map<注册类(activity,fragemnt),List<EventType>>,每个订阅方法都有一个参数就是EventType,
    //  把所有EventType放进一个叫做subscribedEvents:List<Class<?>>的list,在和类组成typesBySubscriber。
    //  每个注册类以及注册类中的事件类型列表就是typesBySubscriber中的一项
    //3.粘性事件注册时直接回调订阅方法     
}

生成post事件时需要遍历的订阅方法列表

5.post

post方法会携带EventType类型,通过EventType类型遍历注册时生成的subscriptionsByEventType列表
subscriptions = subscriptionsByEventType.get(eventClass);
for (Subscription subscription : subscriptions) {
    postToSubscription(subscription, event, postingState.isMainThread);
}

根据EventType类型取到对应的注册订阅方法列表,再根据订阅方法的线程模式分情况执行
1)POSTING:同一个线程执行 不需要处理
2)MAIN:主线程执行,需要判断post所在的线程是不是主线程,是就直接执行,不是通过mainThreadPoster(Handler)执行
3)BACKGROUND:后台线程判断post所在线程是不是主线程,是就用backgroundPoster(Runnable)执行,不是就直接执行
4)ASYNC:异步线程 不管是不是主线程都利用asyncPoster(Runnable)执行

private void postToSubscription(Subscription subscription, Object event, boolean isMainThread) {
    switch (subscription.subscriberMethod.threadMode) {
        case POSTING:
            invokeSubscriber(subscription, event);
            break;
        case MAIN:
            if (isMainThread) {
                invokeSubscriber(subscription, event);
            } else {
                mainThreadPoster.enqueue(subscription, event);
            }
            break;
        case MAIN_ORDERED:
            if (mainThreadPoster != null) {
                mainThreadPoster.enqueue(subscription, event);
            } else {
                // temporary: technically not correct as poster not decoupled from subscriber
                invokeSubscriber(subscription, event);
            }
            break;
        case BACKGROUND:
            if (isMainThread) {
                backgroundPoster.enqueue(subscription, event);
            } else {
                invokeSubscriber(subscription, event);
            }
            break;
        case ASYNC:
            asyncPoster.enqueue(subscription, event);
            break;
        default:
            throw new IllegalStateException("Unknown thread mode: " + subscription.subscriberMethod.threadMode);
    }
}

6.Note

Note1:是否主线程判断

根据Looper.prepare()==Looper.getMainLooper()判断
Looper.prepare():获取所在线程的Looper
Looper.getMainLooper():获取主线程Looper

Note2:后台和异步的区别

后台线程单个执行(BackgroundPoster是加锁synchronized的),异步来一个执行一个

后台线程enqueue() public void enqueue(Subscription subscription, Object
event) {
PendingPost pendingPost = PendingPost.obtainPendingPost(subscription, event);
synchronized (this) {
queue.enqueue(pendingPost);
if (!executorRunning) {
executorRunning = true;
eventBus.getExecutorService().execute(this);
}
}
}

异步线程enqueue() public void enqueue(Subscription subscription, Object
event) {
PendingPost pendingPost = PendingPost.obtainPendingPost(subscription, event);
queue.enqueue(pendingPost);
eventBus.getExecutorService().execute(this);
}

Note3:invokeSubscriber()

subscription.subscriberMethod.method.invoke(subscription.subscriber,
event); 利用反射直接调用订阅方法

目录 1.介绍............................................................................................................................................................3 2.基本概念....................................................................................................................................................3 3.报文传输....................................................................................................................................................6 3.1 帧类型..................................................................................................................................................6 3.1.1 数据帧...........................................................................................................................................6 3.1.2 远程帧...........................................................................................................................................9 3.1.3 错误帧.........................................................................................................................................10 3.1.4 过载帧......................................................................................................................................... 11 3.1.5 帧间空间..................................................................................................................................... 11 3.2 发送器/接收器的定义.........................................................................................................................12 4.报文校验..................................................................................................................................................12 5.编码..........................................................................................................................................................13 6.错误处理..................................................................................................................................................13 6.1 错误检测............................................................................................................................................13 6.2 错误标定............................................................................................................................................13 7.故障界定..................................................................................................................................................13 8.位定时要求..............................................................................................................................................15 9 增加CAN 振荡器容差...............................................................................................................................16 9.1 协议修改............................................................................................................................................17
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值