南充住房和城乡建设厅网站,建设网站模板下载,wordpress固定主题,网站推广及seo方案一、概念
EventBus是一款在 Android 开发中使用的发布-订阅事件总线框架#xff0c;基于观察者模式#xff0c;将事件的接收者和发送者解耦#xff0c;简化了组件之间的通信#xff0c;使用简单、效率高、体积小。
一句话#xff1a;用于Android组件间通信的。
二、原理…一、概念
EventBus是一款在 Android 开发中使用的发布-订阅事件总线框架基于观察者模式将事件的接收者和发送者解耦简化了组件之间的通信使用简单、效率高、体积小。
一句话用于Android组件间通信的。
二、原理 三、简单使用
在app module的builde.gradle文件中导入依赖库
implementation org.greenrobot:eventbus:3.3.1配置混淆
-keepattributes *Annotation*
-keepclassmembers class * {org.greenrobot.eventbus.Subscribe methods;
}
-keep enum org.greenrobot.eventbus.ThreadMode { *; }# Only required if you use AsyncExecutor
-keepclassmembers class * extends org.greenrobot.eventbus.util.ThrowableFailureEvent {init(java.lang.Throwable);
}1、订阅者EventBusService后台注册前台EventBusActivity 发送的数据。注册以后一定要记得解注册否则会内存泄漏。onMsgEventReceived是接收消息的方法该方法定义需要注意
该方法有且仅有一个参数必须用public修饰不能使用static或者abstract需要添加Subscribe()注解
public class EventBusService extends Service {private static final String TAG Test_EventBusService;Overridepublic void onCreate() {super.onCreate();//注册数据监听EventBus.getDefault().register(this);}NullableOverridepublic IBinder onBind(Intent intent) {return null;}Subscribepublic void onMsgEventReceived(String msg) {Log.i(TAG, String msg: msg);}Subscribe(threadMode ThreadMode.MAIN, sticky true, priority 1)public void onMsgEventReceived(MsgEvent event) {Log.i(TAG, MsgEvent msg: event.getMsg());}Overridepublic void onDestroy() {super.onDestroy();//解注册数据监听EventBus.getDefault().unregister(this);}
}2、前台Activity在按钮点击的时候发送信息到后台Service。
public class EventBusActivity extends AppCompatActivity {private static final String TAG Test_EventBusActivity;Overrideprotected void onCreate(Nullable Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_event_bus);Button msg1Btn findViewById(R.id.btn1);Button msg2Btn findViewById(R.id.btn2);msg1Btn.setOnClickListener(new View.OnClickListener() {Overridepublic void onClick(View view) {//发送数据给监听者EventBus.getDefault().post(msg1 - coming);}});msg2Btn.setOnClickListener(new View.OnClickListener() {Overridepublic void onClick(View view) {//发送数据给监听者MsgEvent event new MsgEvent(msg2 - coming);EventBus.getDefault().post(event);}});}Overrideprotected void onDestroy() {super.onDestroy();}
}3、MsgEvent数据类型。
public class MsgEvent {private String msg;public MsgEvent(String msg) {this.msg msg;}public String getMsg() {return msg;}public void setMsg(String msg) {this.msg msg;}Overridepublic String toString() {return MsgEvent{ msg msg \ };}
}4、运行结果
四、Subscribe注解
Subscribe是EventBus自定义的注解共有三个参数可选ThreadMode、boolean sticky、int priority。
Subscribe(threadMode ThreadMode.MAIN, sticky true, priority 1)
public void onMsgEventReceived(MsgEvent event) {Toast.makeText(this, event.getMsg(), Toast.LENGTH_LONG).show();
}1、ThreadMode取值
ThreadMode.POSTING默认的线程模式在哪个线程发送事件就在对应线程处理事件。避免了线程切换效率高。
代码测试
#EventBusActivity
msg1Btn.setOnClickListener(new View.OnClickListener() {Overridepublic void onClick(View view) {//发送数据给监听者new Thread(new Runnable() {Overridepublic void run() {Log.i(TAG, post thread: Thread.currentThread().getName());EventBus.getDefault().post(msg1 - coming);}}).start();}});#EventBusService
Subscribe
public void onMsgEventReceived(String msg) {Log.i(TAG, onMsgEventReceived thread: Thread.currentThread().getName());Log.i(TAG, String msg: msg);
}把post的动作放到子线程中结果如下在哪个线程发送就会在哪个线程执行
ThreadMode.MAIN如在主线程UI线程发送事件则直接在主线程处理事件如果在子线程发送事件则先将事件入队列然后通过Handler切换到主线程依次处理事件。 该模式下在主线程UI线程发送事件则直接在主线程处理事件如果处理方法中有耗时操作就会堵塞进程。 代码测试1
#EventBusActivity
msg1Btn.setOnClickListener(new View.OnClickListener() {Overridepublic void onClick(View view) {//发送数据给监听者new Thread(new Runnable() {Overridepublic void run() {Log.i(TAG, post thread: Thread.currentThread().getName());EventBus.getDefault().post(msg1 - coming);}}).start();}});#EventBusService
Subscribe(threadMode ThreadMode.MAIN)
public void onMsgEventReceived(String msg) {Log.i(TAG, onMsgEventReceived thread: Thread.currentThread().getName());Log.i(TAG, String msg: msg);
}发送post代码放到子线程中处理事件代码加上ThreadMode.MAIN注解参数结果如下可以用在子线程处理耗时操作然后返回值需要切回到主线程刷新UI的场景 代码测试2
#EventBusActivity
msg1Btn.setOnClickListener(new View.OnClickListener() {Overridepublic void onClick(View view) {//发送数据给监听者Log.i(TAG, post thread: Thread.currentThread().getName());EventBus.getDefault().post(msg1 - coming);Log.i(TAG, post thread: Thread.currentThread().getName());EventBus.getDefault().post(msg1-1 - coming);}});#EventBusService
Subscribe(threadMode ThreadMode.MAIN)
public void onMsgEventReceived(String msg) {Log.i(TAG, onMsgEventReceived thread: Thread.currentThread().getName());Log.i(TAG, String msg: msg);try {Thread.sleep(2 * 1000);} catch (InterruptedException e) {e.printStackTrace();}
}发送post放在主线程并连续发送两次接收事件的函数加上耗时操作运行结果如下两次post打印就相隔2s第二次post需要等第一次事件接收处理完以后才能发出所以主线程会阻塞
同样修改下发出post的代码放到子线程后没有这个问题结果如下
ThreadMode.MAIN_ORDERED无论在那个线程发送事件都先将事件入队列然后通过 Handler 切换到主线程依次处理事件。 代码测试
#EventBusActivity
msg1Btn.setOnClickListener(new View.OnClickListener() {Overridepublic void onClick(View view) {//发送数据给监听者Log.i(TAG, post thread: Thread.currentThread().getName());EventBus.getDefault().post(msg1 - coming);Log.i(TAG, post thread: Thread.currentThread().getName());EventBus.getDefault().post(msg1-1 - coming);}});#EventBusService
Subscribe(threadMode ThreadMode.MAIN_ORDERED)
public void onMsgEventReceived(String msg) {Log.i(TAG, onMsgEventReceived thread: Thread.currentThread().getName());Log.i(TAG, String msg: msg);try {Thread.sleep(2 * 1000);} catch (InterruptedException e) {e.printStackTrace();}
}代码和ThreadMode.MAIN测试2一样只是将threadMode改为了MAIN_ORDERED运行结果如下两次post可以连续发出
ThreadMode.BACKGROUND如果在主线程发送事件则先将事件入队列然后通过线程池依次处理事件如果在子线程发送事件则直接在发送事件的子线程处理事件。 代码测试1
msg1Btn.setOnClickListener(new View.OnClickListener() {Overridepublic void onClick(View view) {//发送数据给监听者Log.i(TAG, post thread: Thread.currentThread().getName());EventBus.getDefault().post(msg1 - coming);}});#EventBusService
Subscribe(threadMode ThreadMode.BACKGROUND)
public void onMsgEventReceived(String msg) {Log.i(TAG, onMsgEventReceived thread: Thread.currentThread().getName());Log.i(TAG, String msg: msg);
}运行结果如下主线程发送事件线程池依次处理事件
代码测试2
msg1Btn.setOnClickListener(new View.OnClickListener() {Overridepublic void onClick(View view) {//发送数据给监听者new Thread(new Runnable() {Overridepublic void run() {Log.i(TAG, post thread: Thread.currentThread().getName());EventBus.getDefault().post(msg1 - coming);}}).start();}});#EventBusService
Subscribe(threadMode ThreadMode.BACKGROUND)
public void onMsgEventReceived(String msg) {Log.i(TAG, onMsgEventReceived thread: Thread.currentThread().getName());Log.i(TAG, String msg: msg);
}运行结果子线程发送事件则直接在发送事件的子线程处理事件
ThreadMode.ASYNC无论在那个线程发送事件都将事件入队列然后通过线程池处理。 代码测试1
msg1Btn.setOnClickListener(new View.OnClickListener() {Overridepublic void onClick(View view) {//发送数据给监听者Log.i(TAG, post thread: Thread.currentThread().getName());EventBus.getDefault().post(msg1 - coming);}});#EventBusService
Subscribe(threadMode ThreadMode.ASYNC)
public void onMsgEventReceived(String msg) {Log.i(TAG, onMsgEventReceived thread: Thread.currentThread().getName());Log.i(TAG, String msg: msg);
}运行结果主线程发送线程池处理 代码测试2
msg1Btn.setOnClickListener(new View.OnClickListener() {Overridepublic void onClick(View view) {//发送数据给监听者new Thread(new Runnable() {Overridepublic void run() {Log.i(TAG, post thread: Thread.currentThread().getName());EventBus.getDefault().post(msg1 - coming);}}).start();}});#EventBusService
Subscribe(threadMode ThreadMode.ASYNC)
public void onMsgEventReceived(String msg) {Log.i(TAG, onMsgEventReceived thread: Thread.currentThread().getName());Log.i(TAG, String msg: msg);
}运行结果子线程发送线程池处理
2、sticky
sticky是否为粘性监听boolean类型默认值为false。正常我们都是先订阅才能接收到发出的事件sticky的作用就是订阅者可以先不进行注册事件先发出再注册订阅者同样可以接收到事件并进行处理。
3、priority
priority是优先级int类型默认值为0。值越大优先级越高越优先接收到事件。值得注意的是只有在post事件和事件接收处理处于同一个线程环境的时候才有意义。
参考文章 EventBus详解 (详解 原理)