Android Rxbus事件总线
最近在项目中使用了Rxjava和RxAndroid,确实感觉挺不错的,然后听说可以用RxBus来替换掉EventBus等事件分发的三方库,然后就上午找比较好的RxBus开源项目(以为是有统一标准的),然而后面才知道,RxBus没有绝对的,只是一种想法而已,借助Rxjava的特性来实现的。既然这样,我也就自己实现了一个(可以设置tag,并指定事件接收的线程类型),测试效果还是蛮不错的。先看效果图:
途中,在第一个activity中发送事件,并在其中接收到事件,文本框内容改变;打开第二个activity,发送相同tag的事件,所以第一个activity中也接收到了第二个activity发送的事件。
一:首先添加依赖库
[html]view plaincopy
dependencies {
compile 'io.reactivex:rxjava:1.1.0'
compile 'io.reactivex:rxandroid:1.1.0'
}
二:编写RxBus类
[java]view plaincopy
packagecom.ywl5320.rxbusdemo.RxBus;
importjava.util.HashMap;
importjava.util.Map;
importrx.android.schedulers.AndroidSchedulers;
importrx.functions.Action1;
importrx.schedulers.Schedulers;
importrx.subjects.PublishSubject;
importrx.subjects.SerializedSubject;
importrx.subjects.Subject;
/**
* Created by ywl on 2016/5/20.
*/
publicclassRxBus {
privatefinalSubject _bus =newSerializedSubject<>(PublishSubject.create());
privatefinalMap tags =newHashMap<>();
privatestaticRxBus rxbus;
publicstaticRxBus getInstance()
{
if(rxbus ==null)
{
synchronized(RxBus.class) {
if(rxbus ==null) {
rxbus =newRxBus();
}
}
}
returnrxbus;
}
/**
* 发送事件消息
* @param tag 用于区分事件
* @param object 事件的参数
*/
publicvoidpost(String tag, Object object)
{
_bus.onNext(object);
if(!tags.containsKey(tag))
{
tags.put(tag, object);
}
}
/**
* 主线程中执行
* @param tag
* @param rxBusResult
*/
publicvoidtoObserverableOnMainThread(finalString tag,finalRxBusResult rxBusResult) {
_bus.observeOn(AndroidSchedulers.mainThread()).subscribe(newAction1() {
@Override
publicvoidcall(Object o) {
if(tags.containsKey(tag)) {
rxBusResult.onRxBusResult(o);
}
}
});
}
/**
* 子线程中执行
* @param tag
* @param rxBusResult
*/
publicvoidtoObserverableChildThread(finalString tag,finalRxBusResult rxBusResult) {
_bus.observeOn(Schedulers.io()).subscribe(newAction1() {
@Override
publicvoidcall(Object o) {
if(tags.containsKey(tag)) {
rxBusResult.onRxBusResult(o);
}
}
});
}
/**
* 移除tag
* @param tag
*/
publicvoidremoveObserverable(String tag)
{
if(tags.containsKey(tag))
{
tags.remove(tag);
}
}
/**
* 退出应用时,清空资源
*/
publicvoidrelease()
{
tags.clear();
rxbus =null;
}
}
在RxBus类中,使用到了Subject引用网上的解释:“Subject在ReactiveX是作为observer和observerable的一个bridge或者proxy。因为它是一个观察者,所以它可以订阅一个或多个可观察对象,同时因为他是一个可观测对象,所以它可以传递和释放它观测到的数据对象,并且能释放新的对象。”
Subject表示一个同时是Observable和Observer的对象,所以Subject即使订阅者也是观察者,利用这个特性,我们就可以利用它发送和接收消息。Subject的onNext(Object)方法会向所有订阅者发送事件,但是我们在项目中一般都是点对点的发送,不希望其他无关的订阅者也接收到事件,所以在RxBus中添加了一个Map来管理事件的tag,来区别该事件来自哪里,将要去哪里。
为了接收时写更少的代码,写了一个回调函数来处理接收到的信息:
[java]view plaincopy
packagecom.ywl5320.rxbusdemo.RxBus;
/**
* Created by ywl on 2016/5/20.
*/
publicinterfaceRxBusResult {
/**
* 事件回调接口
* @param o
*/
voidonRxBusResult(Object o);
}
二:怎么使用
1、首先定义RxBus并初始化
[java]view plaincopy
privateRxBus rxBus = RxBus.getInstance();
2、发送消息
[java]view plaincopy
btnsend.setOnClickListener(newView.OnClickListener() {
@Override
publicvoidonClick(View v) {
rxBus.post("first",newString("hello rxbus"));
}
});
其中,“first”即为区分事件的tag,第二个参数是发送的对象。
3、接收消息
[java]view plaincopy
rxBus.toObserverableOnMainThread("first",newRxBusResult() {
@Override
publicvoidonRxBusResult(Object o) {
finalString msg = (String)o;
mtvmsg.setText("first收到消息;"+ msg);
Toast.makeText(MainActivity.this,"收到消息;"+ msg, Toast.LENGTH_SHORT).show();
}
});
这里指定在主线程中接收tag为“first”的消息并处理。
这样发送接收就都完成了,但是为了更好的管理tag,我们在退出时最好把相应的tag清除掉,如:
[java]view plaincopy
@Override
protectedvoidonDestroy() {
super.onDestroy();
rxBus.removeObserverable("first");
}
最后:在应用程序完全退出时还需调用rxBus.release()方法释放资源(也避免了一个问题:就是如果不释放,第二次启动应用时,不能更新UI,可能是rxBus和第二次启动的应用不在同一个进程中造成的,因为第一次退出应用时,rxBus是没有销毁的,第二次不会重新创建,所以导致了这个问题)
最后把MainActivity和SecondActivity中代码贴出来:
[java]view plaincopy
packagecom.ywl5320.rxbusdemo;
importandroid.content.Intent;
importandroid.support.v7.app.AppCompatActivity;
importandroid.os.Bundle;
importandroid.view.View;
importandroid.widget.Button;
importandroid.widget.TextView;
importandroid.widget.Toast;
importcom.ywl5320.rxbusdemo.RxBus.RxBus;
importcom.ywl5320.rxbusdemo.RxBus.RxBusResult;
publicclassMainActivityextendsAppCompatActivity {
privateButton btnsend;
privateButton btnsecond;
privateTextView mtvmsg;
privateRxBus rxBus = RxBus.getInstance();
@Override
protectedvoidonCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
btnsend = (Button) findViewById(R.id.btn_send);
btnsecond = (Button) findViewById(R.id.btn_second);
mtvmsg = (TextView) findViewById(R.id.tv_msg);
btnsend.setOnClickListener(newView.OnClickListener() {
@Override
publicvoidonClick(View v) {
rxBus.post("first",newString("hello rxbus"));
}
});
btnsecond.setOnClickListener(newView.OnClickListener() {
@Override
publicvoidonClick(View v) {
Intent intent =newIntent(MainActivity.this, SecondActivity.class);
MainActivity.this.startActivity(intent);
}
});
rxBus.toObserverableOnMainThread("first",newRxBusResult() {
@Override
publicvoidonRxBusResult(Object o) {
finalString msg = (String)o;
mtvmsg.setText("first收到消息;"+ msg);
Toast.makeText(MainActivity.this,"收到消息;"+ msg, Toast.LENGTH_SHORT).show();
}
});
rxBus.toObserverableOnMainThread("second",newRxBusResult() {
@Override
publicvoidonRxBusResult(Object o) {
String msg = (String)o;
mtvmsg.setText("second收到消息;"+ msg);
Toast.makeText(MainActivity.this,"second收到消息;"+ msg, Toast.LENGTH_SHORT).show();
}
});
}
/**
* 退出时,释放rxbus
*/
@Override
protectedvoidonDestroy() {
super.onDestroy();
rxBus.release();
}
}
[java]view plaincopy
packagecom.ywl5320.rxbusdemo;
importandroid.os.Bundle;
importandroid.support.annotation.Nullable;
importandroid.support.v7.app.AppCompatActivity;
importandroid.view.View;
importandroid.widget.Button;
importcom.ywl5320.rxbusdemo.RxBus.RxBus;
/**
* Created by ywl on 2016/5/20.
*/
publicclassSecondActivityextendsAppCompatActivity {
privateButton mbtnsend;
privateRxBus rxBus = RxBus.getInstance();
@Override
protectedvoidonCreate(@NullableBundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.second_activity);
mbtnsend = (Button) findViewById(R.id.btn_send);
mbtnsend.setOnClickListener(newView.OnClickListener() {
@Override
publicvoidonClick(View v) {
rxBus.post("second",newString("第二个页面的数据"));
}
});
}
@Override
protectedvoidonDestroy() {
super.onDestroy();
rxBus.removeObserverable("first");
}
}
这样就完成了RxBus工具类的编写Demo下载地址(注:demo的RxBus有Bug,就是不能同时两个接收同一个发送的消息,这里可以以博客中为准,博客中已经修改了,可以对比下改了什么哟 哈哈哈)。
github:https://github.com/wanliyang1990/rxbusDemo
转自:http://blog.****.net/ywl5320/article/details/51481103