`
dawuafang
  • 浏览: 1107497 次
文章分类
社区版块
存档分类
最新评论

Android EventBus 简化应用程序组件(Activity、Fragment、线程)间通信的开源项目

 
阅读更多

项目地址:https://github.com/greenrobot/EventBus/


项目使用的技术呢,说白了,就是将要传递的event(一个Object对象,可任意自定义),发送到公共的组件EventBus中进行存储,

在通过EventBus传递给订阅者(使用者),订阅者收到event消息,就可以自行处理了。


不要被标题迷惑了,其实在任何地方 都可以发送和接收event(event,是一个通称,表示任意的数据对象,是一个消息类型)。

当然有需要注意的地方了,往下看吧。


分析一个基本的使用流程:


1. 自定义一个event类型:需要什么样的数据,就定义成什么样,随意了


2. 确定在哪里来接收该event,就在哪里调用EventBus.getDefault().register()进行订阅者的注册。

EventBus 一看就是个单例类,所以通过它存储、发送event。

可以在要处理事件的地方注册和接收;在发送事件的地方直接调用post(event)

register()有多个重载方法:

    public void register(Object subscriber) {
        register(subscriber, false, 0);
    }

    public void register(Object subscriber, int priority) {
        register(subscriber, false, priority);
    }

    public void registerSticky(Object subscriber) {
        register(subscriber, true, 0);
    }

    public void registerSticky(Object subscriber, int priority) {
        register(subscriber, true, priority);
    }
    private void subscribe(Object subscriber, SubscriberMethod subscriberMethod, boolean sticky, int priority) {
        ...
    }

看名字也很好理解,subscriber即订阅者(接收处理event的类);priority即优先级,表示优先处理;

sticky粘性的意思,在源码中会有一个map对象,来存储sticky的event,

因为map的key是onEvent...()方法的第一个参数类型,

一般呢,这第一个参数就是订阅者对象,所以map会存储该类型的最后一次发送的event对象。

这些register都会最终调用一个私有register方法实现的,在这个方法里有个参数是SubscriberMethod对象。

调用subscriberMethod.findSubscriberMethods(), 查找到订阅者定义的接收处理event的方法,

并在EventBus中存起来。


3. 在订阅者中定义接收处理event的方法,约定为:

onEvent、onEventMainThread、onEventBackgroundThread、onEventAsync

使用时类似这样的:public void onEvent(Object event)。 onEvent对应PostThread,其他各自对应ThreadMode中的其他定义。

onEvent后面跟的这些名称的意义,见ThreadMode


4. 发送事件

调用EventBus.getDefault().post(Object event),发送事件

源码中会调用postToSubscription(),发送event给对应的订阅者方法


ThreadMode

这是一个枚举类。定义了四种类型:PostThread、MainThread、BackgroundThread、Async

PostThread 事件event的处理和发送都在相同线程中

MainThread 事件event的处理在主线程中,小心ANR

BackgroundThread事件event的处理在后台线程(非主线程)中,它是阻塞式的,如有多个事件发送过来,会一个一个处理

Async事件event的处理是异步的,即新开一个线程进行处理。

对应的接收事件方法:

PostThread ---- onEvent() 在发送事件的线程中接收事件

MainThread ---- onEventMainThread() 在主线程中接收

BackgroundThread ---- onEventBackgroundThread 在后台线程中接收

Async ---- onEventAsync 在异步线程中接收


例:在activity2中post(event),在activity1中注册为订阅者 并 接收事件 onEvent。 要在哪种类型线程中接收 ,参考上面的说明

public class EventBusActivity1 extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        EventBus.getDefault().register(this); //注册接收器
    }

    //两个activity中使用eventBus
    public void eventBusEventWith2Acti(View view) {//onClick方法
        startActivity(new Intent(this, EventBusActivity2.class));
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();

        EventBus.getDefault().unregister(this); 
    }

    public void onEvent(Object event) { //接收方法  在发关事件的线程接收
        Looper.prepare();
        Toast.makeText(this, "recevie a event:" + event + Thread.currentThread().getName(), Toast.LENGTH_SHORT).show();
        Looper.loop();
    }

}

public class EventBusActivity2 extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        new Thread() {
            @Override
            public void run() {
                EventBus.getDefault().post(this.getClass().getSimpleName() + " 发了一个消息");
            }
        }.start();
        finish();
    }
}


使用注意:

1. 在register(Object subscription) 注册的subscription对象中 定义onEvent... 方法,至少需要定义一种

2. 如果所有的onEvent... 方法都注册 那么 都将收到消息(内部机制就是反射判断有哪些方法,从消息队列中取event)

3. onEvent(event) 所接收到的消息的数据类型任意(随你的意),在任意位置使用post(event)发送事件

4. 实际使用时,异步操作选用onEventAsync,主界面操作选用onEventMainThread

5. 在代码混淆时,注意保留onEvent... 方法


----------------------------------------------------------------------------------------------------分隔线-----------------------------------------------------------------------------------

实际工作中,我把该组件用于,跨activity、fragment等通知,即只要不是在同一个class文件中,需要通知交互的地方,就可以使用它

使用流程

> 定义一个事件类, class EventBean;在里面定义每种通知事件的常量类型。这样对于不需要传参的通知是够用了

> 在EventBean中,定义一个属性:Object data; 用于存储任意参数类型

> 如果当前在A-Fragment中,需要传一个 List<User> users; 给MainActivity,对users排序

/**
 * @Description: 管理所有跨界面消息通知事件
 * @author aa86799@163.com
 */
public class EventBean {

	private int mEvent;
	private Object mData;
	
	/**主界面 对User 集合排序*/
	public static final int EVENT_MAINACTIVITY_SORT_USER = 1;


	public EventBean() {

	}
	
	public EventBean(int event) {
		this.mEvent = event;
	}

	public EventBean(int event, Object data) {
		this(event);
		this.mData = data;
	}

	public int getEvent() {
		return this.mEvent;
	}

	public void setEvent(int event) {
		this.mEvent = event;
	}

	public Object getData() {
		return mData;
	}

	public void setData(Object data) {
		this.mData = data;
	}
	
	
}

在fragment中,发消息通知时大概是这样的:

EventBus.getDefault().post(new EventBean(EventBean.EVENT_MAINACTIVITY_SORT_USER,  users));

在MainActivity中

@Override
public void onEventMainThread(EventBean event) { //在主线程中接收  
	switch (event.getEvent()) {
	case EventBean.Event_SORT_USERS:
		LogUtil.i(TAG, "用户排序");
                List<user> users = (List<user>)event.getData();
		sortUsers(users);
		break;
	default:
		break;
	}
}

—————————————————————2016-04-26——————————————————————

用Android Studio 加载了EventBus的Library;发现已经升级到3.0了,用法有变化:

主要是订阅(接收)事件消息的方法上,需要一个注解,这个比较麻烦


订阅事件的方法随意命名(即不用像老版本一样,必须使用约定的方法名),只要在方法上加一个注解

@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD})
public @interface Subscribe {
    ThreadMode threadMode() default ThreadMode.PostThread;

    
    boolean sticky() default false;

    
    int priority() default 0;
}

使用如下:

@Subscribe(threadMode = ThreadMode.MainThread, sticky = true, priority = 1)
public void onEvent(EventBean event){}

注解中的属性,都有默认值的:

threadMode 表示在哪个线程中接收消息

sticky 如果为true,表示收到粘性事件;相应的在发送事件时,要使用postSticky(Object event);

priority 优先级,值越大,越先处理


关于sticky,EventBus类中源码:

    /**
     * Posts the given event to the event bus and holds on to the event (because it is sticky). The most recent sticky
     * event of an event's type is kept in memory for future access by subscribers using {@link Subscribe#sticky()}.
     */
    public void postSticky(Object event) {
        synchronized (stickyEvents) {
            stickyEvents.put(event.getClass(), event);
        }
        // Should be posted after it is putted, in case the subscriber wants to remove immediately
        post(event);
    }

    /**
     * Gets the most recent sticky event for the given type.
     *
     * @see #postSticky(Object)
     */
    public <T> T getStickyEvent(Class<T> eventType) {
        synchronized (stickyEvents) {
            return eventType.cast(stickyEvents.get(eventType));
        }
    }

源码中的stickyEvents是一个Map类型。由此可见,多次postSticky同一类型后,

由getStickyEvent(class),可以拿到最新的该类型对象


其它方法:

eventbus.removeAllStickyEvents(); //删除所有粘性事件
eventbus.cancelEventDelivery(Object event); //取消事件提供(发送)




分享到:
评论

相关推荐

    Android中使用开源框架eventbus3.0实现fragment之间的通信交互

    1.概述 ...作用是可以代替传统的Intent,Handler,Broadcast或接口函数在Fragment、Activity、Service、线程之间传递数据进行通信,执行方法。做为消息总线,有三个主要元素: (1)Event:事件 (2)Subs

    EventBus实现activity跟fragment交互数据

    EventBus实现activity跟fragment交互数据 博客地址:http://blog.csdn.net/lowprofile_coding/article/details/48645441

    Android组件间通信库EventBus

    EventBus是GreenRobot出品的Android系统的一个Event Bus类库,使用起来和之前我们所介绍的Square的Otto差不多,都是用来简化应用组件之间的通信。 使用介绍http://blog.chengyunfeng.com/?p=452

    android EventBus

    android EventBus

    Android EventBus通信

    EventBus**是一个Android端简化了应用程序内各组件间、组件与后台线程间的通信。

    AndroidEventBus.jar

    AndroidEventBus 事件总线的jar,版本是1.0.2

    AndroidEventBus Jar

    AndroidEventBus是一个Android平台轻量级的事件总线框架, 它简化了Activity、Fragment、Service等组件之间的交互,很大程度上降低了它们之间的耦合,使得我们的代码更加简洁,耦合性更低,提升我们的代码质量。

    Android 自己实现组件间通信框架EventBus

    代码为博客的实例代码:http://blog.csdn.net/lmj623565791/article/details/41096639 有问题请博客留言

    Android Eventbus 总线jia包

    android eventbus总线jar包就2积分,多下载,谢谢亲们。

    fragment之间通信 eventbus

    fragment之间通信 eventbus!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

    android EventBus简单使用Demo

    这个是一个简单使用EventBus的Demo,里面实现了在线程里通过EventBus发送消息给主线程,实现加载框的变化功能

    EventBusDemo

    EventBus**是一个Android端优化的publish/subscribe消息总线,简化了应用程序内各组件间、组件与后台线程间的通信。比如请求网络,等网络返回时通过Handler或Broadcast通知UI,两个Fragment之间需要通过Listener通信...

    Android EventBus框架使用详细介绍(一)

    Android EventBus框架使用详细介绍(一)

    android eventbus source code

    当我们想通知其他组件某些事情发生时,我们通常使用观察者模式,正式因为观察者模式非常常见,所以在jdk1.5中已经帮助我们实现了观察者模式,我们只需要简单的继承一些类就可以快速使用观察者模式,在Android中也有...

    android eventbus 最新jar

    android Event bus 3.0 加入注解的使用的方式

    Android eventbus使用demo

    android eventbus 简单使用的详细介绍。

    android消息机制EventBus

    EventBus是基于Otto的消息发送机制,经过开源大神们的封装,已经越来越好用了。

    eventBus 3.0.0的jar包

    EventBus 3.0.0Jar包. EventBus是Android中组件与组件之间通信的框架,可以解耦和简化Activity与Activity、Activity和Fragment、Fragment和Fragment之间的通信。

    Android EventBus使用,粘性事件postSticky使用

    Android EventBus使用,粘性事件postSticky使用 https://blog.csdn.net/qq_31939617/article/details/80860615

Global site tag (gtag.js) - Google Analytics