EventBus(组件与后台线程间的通信)的简单使用
2018-01-28 22:25
405 查看
一、EventBus简介
EventBus是一个Android端优化的publish/subscribe消息总线,简化了应用程序内各组件间、组件与后台线程间的通信。作为一个消息总线主要有三个组成部分:
事件(Event):可以是任意类型的对象。通过事件的发布者将事件进行传递。
事件订阅者(Subscriber):接收特定的事件。
事件发布者(Publisher):用于通知 Subscriber 有事件发生。可以在任意线程任意位置发送事件。
上图解释了整个EventBus的大概工作流程:事件的发布者(Publisher)将事件(Event)通过post()方法发送。EventBus内部进行处理,找到订阅了该事件(Event)的事件订阅者(Subscriber)。然后该事件的订阅者(Subscriber)通过onEvent()方法接收事件进行相关处理(关于onEvent()在EventBus 3.0中有改动,下面详细说明)。
1、把EventBus依赖到项目
module gradledependencies { compile 'org.greenrobot:eventbus:3.0.0' }
2、构造事件(Event)对象。也就是发送消息类
/** * 构造事件(Event)对象,也就是发送消息类 */ public class MsgEvent { private String message; public String getMessage() { return message; } public void setMessage(String message) { this.message = message; } public MsgEvent(String message) { this.message = message; } }
3、注册/解除事件订阅(Subscriber)
EventBus.getDefault().register(this);//注册事件 其中this代表订阅者通过register(this)来表示该订阅者进行了订阅,通过onToastEvent(ToastEvent event)表示指定对事件ToastEvent的订阅。到这里订阅就完成了。
需要注意的是:一般在onCreate()方法中进行注册订阅。在onDestory()方法中进行解除订阅。
4 、发送消息
订阅已经完成,那么便可以发送订阅了。EventBus.getDefault().post(new ToastEvent(“Toast,发个提示,祝大家新年快乐!”));
那么onToastEvent(ToastEvent event)会收到事件,并弹出提示。
1.线程模式ThreadMode:关于ThreadMode,一共有四种模式PostThread,MainThread,BackgroundThread以及Async。
PostThread:事件的处理在和事件的发送在相同的进程,所以事件处理时间不应太长,不然影响事件的发送线程。MainThread: **事件的处理会在UI线程中执行。事件处理时间不能太长,这个不用说的,长了会ANR的。
BackgroundThread:如果事件是在UI线程中发布出来的,那么事件处理就会在子线程中运行,如果事件本来就是子线程中发布出来的,那么事件处理直接在该子线程中执行。所有待处理事件会被加到一个队列中,由对应线程依次处理这些事件,如果某个事件处理时间太长,会阻塞后面的事件的派发或处理。
Async:事件处理会在单独的线程中执行,主要用于在后台线程中执行耗时操作,每个事件会开启一个线程。
2.priority事件优先级
事件的优先级类似广播的优先级,优先级越高优先获得消息。当多个订阅者(Subscriber)对同一种事件类型进行订阅时,即对应的事件处理方法中接收的事件类型一致,则优先级高(priority 设置的值越大),则会先接收事件进行处理;优先级低(priority 设置的值越小),则会后接收事件进行处理。
例子
在mainactivity中注册接收SecondActivity发送来的消息/** * 优先级priority * 当多个订阅者(Subscriber)对同一种事件类型进行订阅时,即对应的事件处理方法中接收的事件类型一致, * 则优先级高(priority 设置的值越大),则会先接收事件进行处理;优先级低(priority 设置的值越小), * 则会后接收事件进行处理。 * * @Subscribe(priority = 100) public void onToastEvent(ToastEvent event){ Toast.makeText(MainActivity.this,event.getContent(),Toast.LENGTH_SHORT).show(); } */ public class MainActivity extends AppCompatActivity { private TextView textView; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); Button button = (Button) findViewById(R.id.btn); textView = (TextView) findViewById(R.id.tv); textView.setText("Mainactivity"); button.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { startActivity(new Intent(MainActivity.this, SecondActivity.class)); } }); //在发送消息类中注册事件 EventBus.getDefault().register(this); } @Subscribe public void accept(MsgEvent msgEvent) { textView.setText(msgEvent.getMessage()); } /** * threadMode = ThreadMode.POSTING * 事件的处理在和事件的发送在相同的进程 */ @Subscribe(threadMode = ThreadMode.POSTING) public void accept1(MsgEvent msgEvent) { System.out.println("accept1++++++++++" + Thread.currentThread().getName()); } /** * threadMode = ThreadMode.MAIN * 事件的处理会在UI线程中执行 */ @Subscribe(threadMode = ThreadMode.MAIN) public void accept2(MsgEvent msgEvent) { System.out.println("accept2++++++++++" + Thread.currentThread().getName()); } /** * threadMode = ThreadMode.BACKGROUND * 如果事件是在UI线程中发布出来的,那么事件处理就会在子线程中运行,如果事件本来就是子线程中发布出来的,那么事件 4000 处理直接在该子线程中执行 */ @Subscribe(threadMode = ThreadMode.BACKGROUND) public void accept3(MsgEvent msgEvent) { System.out.println("accept3++++++++++" + Thread.currentThread().getName()); } /** * threadMode = ThreadMode.ASYNC * 事件处理会在单独的线程中执行,主要用于在后台线程中执行耗时操作,每个事件会开启一个线程。 */ @Subscribe(threadMode = ThreadMode.ASYNC) public void accept4(MsgEvent msgEvent) { System.out.println("accept4++++++++++" + Thread.currentThread().getName()); } @Override protected void onDestroy() { super.onDestroy(); //避免内存泄漏,取消注册 EventBus.getDefault().unregister(this); } }
public class SecondActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_second); Button button = (Button) findViewById(R.id.btn); Button button2 = (Button) findViewById(R.id.btn2); TextView textView = (TextView) findViewById(R.id.tv); textView.setText("SecondActivity"); button.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { EventBus.getDefault().post(new MsgEvent("你好,您的订阅到了")); finish(); } }); button2.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { EventBus.getDefault().postSticky("我是粘性事件"); startActivity(new Intent(SecondActivity.this,ThirdActivity.class)); } }); } }
接收粘性事件,先发送,后订阅接收
public class ThirdActivity extends AppCompatActivity { private static final String TAG = "ThirdActivity"; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_third); EventBus.getDefault().register(this); } @Subscribe(threadMode = ThreadMode.MAIN,sticky = true) public void accept3(String msg){ Log.d(TAG, "accept3: "+msg); } @Override protected void onDestroy() { super.onDestroy(); EventBus.getDefault().unregister(this); } }
相关文章推荐
- EventBus的使用与原理 组件通信 线程通信(1)
- EventBus的使用(组件间通信)
- .net学习之多线程、线程死锁、线程通信 生产者消费者模式、委托的简单使用、GDI(图形设计接口)常用的方法
- vue 2 使用Bus.js进行兄弟(非父子)组件通信 简单案例
- vue 2 使用Bus.js进行兄弟(非父子)组件通信 简单案例
- vue 2 使用Bus.js进行兄弟(非父子)组件通信 简单案例
- vue 2 使用Bus.js进行兄弟(非父子)组件通信 简单案例
- 安卓组件通信:eventBus的使用
- 简单快速实现使用线程后台执行作业的方法
- Android线程间通信--- eventbus3.0的简单使用
- Android EventBus 简化应用程序组件(Activity、Fragment、线程)间通信的开源项目
- 简单的,使用套接字实现TCP通信(用线程实现并发)
- Android开发线程间的交互之EventBus简单使用
- .net学习之多线程、线程死锁、线程通信 生产者消费者模式、委托的简单使用、GDI(图形设计接口)常用的方法
- 使用EventBus轻松实现组件间通信
- 敏捷思维学习Ext.Net MVC--3.8Form表单组件之使用Enum升级复选组件组(CheckboxGroup)暨前后台终极通信方式
- [转] 最简单的使用UDP通信的Python Socket例子
- 使用后台线程备份单个数据表
- C#如何使用BackgroundWork后台辅助线程控件
- 构建简单的 C++ 服务组件,第 2 部分: 通过服务组件体系结构使用 Python、Ruby 和 Web 服务