EventBus是一款针对Android优化的发布/订阅事件总线。主要功能是替代Intent,Handler,BroadCast在Fragment,Activity,Service,
它可以让我们很轻松的实现在Android各个组件之间传递消息,并且代码的可读性更好,耦合度更低,开销小,代码更优雅.
本程序演示得为EventBus的初步使用
代码结构
程序结果
使用方法
1.在studio中关联EventBus
按Ctrl+Alt+Shift+s,弹出此对话框,之后选择"+"号,选择第一个
之后搜索EventBus 选择该项,单机ok即可
2.关联后开始写主窗体(接收信息)的布局
xml version=
"1.0"
encoding=
"utf-8"
?>
<
RelativeLayout
xmlns:
android
=
"http://schemas.android.com/apk/res/android"
xmlns:
tools
=
"http://schemas.android.com/tools"
android
:layout_width=
"match_parent"
android
:layout_height=
"match_parent"
tools
:context=
".activity.MainActivity">
<
Button
android
:id=
"@+id/btn_ok"
android
:layout_width=
"wrap_content"
android
:layout_height=
"wrap_content"
android
:layout_centerHorizontal=
"true"
android
:text=
"
由主页面跳转到发送事件的页面
"
android
:textSize=
"30sp"/>
<
TextView
android
:id=
"@+id/txtShow"
android
:layout_width=
"wrap_content"
android
:layout_height=
"wrap_content"
android
:text=
"
展示
EventBus
发送过来的数据
"
android
:layout_centerHorizontal=
"true"
android
:layout_below=
"@+id/btn_ok"/>
RelativeLayout>
3.创建一个activity用来发送数据起名为EventBusSendActivity,之后编写该窗体的布局
xml version=
"1.0"
encoding=
"utf-8"
?>
<
RelativeLayout
xmlns:
android
=
"http://schemas.android.com/apk/res/android"
xmlns:
tools
=
"http://schemas.android.com/tools"
android
:layout_width=
"match_parent"
android
:layout_height=
"match_parent"
tools
:context=
".activity.EventBusSendActivity">
<
EditText
android
:id=
"@+id/edt_SendContent"
android
:layout_width=
"match_parent"
android
:layout_height=
"wrap_content"
android
:hint=
"
输入要发送的内容
"
android
:lines=
"5"/>
<
Button
android
:id=
"@+id/btn_Send"
android
:layout_width=
"wrap_content"
android
:layout_height=
"wrap_content"
android
:layout_below=
"@+id/edt_SendContent"
android
:text=
"
向主界面发送一个
eventBus
事件
"
android
:textSize=
"30sp"/>
RelativeLayout>
4.创建一个EventBus的事件类
该类的一个容器,负责存放一些数据,从而让另一个订阅者(接收者),获取消息
代码如下
public class EventBusMessage {
//
定义发送的消息必须是
String
public String
Message;
public EventBusMessage(String message){
Message =message;
}
}
5.
EventBusSendActivity发送窗体的代码
package com.dubuwucool.eventbusdemo.activity;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.text.TextUtils;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;
import com.dubuwucool.eventbusdemo.R;
import com.dubuwucool.eventbusdemo.event.EventBusMessage;
import org.greenrobot.eventbus.EventBus;
public class EventBusSendActivity
extends AppCompatActivity
implements View.OnClickListener {
private Button
btn_Send;
private EditText
edt_SendContent;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.
activity_event_bus_send);
initView();
}
private void initView() {
btn_Send = (Button) findViewById(R.id.
btn_Send);
btn_Send.setOnClickListener(
this);
edt_SendContent = (EditText) findViewById(R.id.
edt_SendContent);
}
@Override
public void onClick(View v) {
switch (v.getId()) {
//
点击按钮
,
发送数据
case R.id.
btn_Send:
String content =
edt_SendContent.getText().toString();
//
使用
Event
发送事件
,
需要
post
方法
,
参数也比细数
Event
消息
,
且要和接收数据保持一直
EventBus.getDefault().post(new EventBusMessage(content));
//传送消息后
,关闭此窗体
finish();
break;
}
}
}
6.主窗体(接收)代码
package com.dubuwucool.eventbusdemo.activity;
import android.content.Intent;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import com.dubuwucool.eventbusdemo.R;
import com.dubuwucool.eventbusdemo.event.EventBusMessage;
import org.greenrobot.eventbus.EventBus;
import
org.greenrobot.eventbus.Subscribe;
import org.greenrobot.eventbus.ThreadMode;
public class MainActivity
extends AppCompatActivity
implements View.OnClickListener {
private Button
btn_ok;
private TextView
txtShow;
//EventBus
实际和广播非常相似
,
只不过使用简单
,
代码量少
,
性能更好
//MainActivity
就是接收消息的类
,
你的事件在哪接收
,
就在哪个类进行
EventBus
的注册和解除操作
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.
activity_main);
//
初始化控件
initView();
//
注册
EventBus,
参数是上下文
//
有注册
EventBus
就必须有解除注册的操作
(
一般在
onDestory
方法里执行解除注册
),
防止
oom
EventBus.
getDefault().register(
this);
}
private void initView() {
btn_ok = (Button) findViewById(R.id.
btn_ok);
txtShow = (TextView) findViewById(R.id.
txtShow);
btn_ok.setOnClickListener(
this);
}
@Override
public void onClick(View v) {
switch (v.getId()) {
//
根据点击事件跳转到发送事件的
activity
里面
case R.id.
btn_ok:
Intent intent =
new Intent(MainActivity.
this, EventBusSendActivity.
class);
startActivity(intent);
break;
}
}
//
接收消息
,
参数就是我们定义的
EventBus
消息类
,
和发送消息必须是同一个
,
加
EventBus
的注解
//
在写接收消息的方法时
,
方法名可自动能够自定义
,
参数必须是消息类设置的参数
,
权限必须是
public
//
方法名是灰色
,
是由于
studio
不识别
EventBus,
但仍可使用
@Subscribe(threadMode = ThreadMode.
MAIN)
public void receiveMessage(EventBusMessage eventBusMessage){
txtShow.setText(eventBusMessage.
Message);
}
//
销毁时解除
EventBus
@Override
protected void onDestroy() {
EventBus.
getDefault().unregister(
this);
super.onDestroy();
}
}
由此便完成了EventBus的简单使用
补充:
在3.0之前,EventBus还没有使用注解方式。消息处理的方法也只能限定于onEvent、onEventMainThread、onEventBackgroundThread和onEventAsync,分别代表四种线程模型。而在3.0之后,消息处理的方法可以随便取名,但是需要添加一个注解@Subscribe,并且要指定线程模型(默认为PostThread),四种线程模型.
注意,事件处理函数的访问权限必须为public,否则会报异常
这里对注解的ThreadMode共有4中方法,做进一步说明这四种方法的区别
这四种方法分别是
ThreadMode.MAIN
ThreadMode.BACKGROUND
ThreadMode.ASYNC
ThreadMode.POSTING
主线程发送消息时
public class MainActivity
extends AppCompatActivity
implements View.OnClickListener {
private Button
btn_ok;
private TextView
txtShow;
private EditText
edt_SendContent;
//EventBus
实际和广播非常相似
,
只不过使用简单
,
代码量少
,
性能更好
//MainActivity
就是接收消息的类
,
你的事件在哪接收
,
就在哪个类进行
EventBus
的注册和解除操作
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.
activity_main);
//
初始化控件
initView();
//
注册
EventBus,
参数是上下文
//
有注册
EventBus
就必须有解除注册的操作
(
一般在
onDestory
方法里执行解除注册
),
防止
oom
// EventBus.getDefault()
获取
EventBus
对象
EventBus.
getDefault().register(
this);
}
private void initView() {
btn_ok = (Button) findViewById(R.id.
btn_ok);
txtShow = (TextView) findViewById(R.id.
txtShow);
btn_ok.setOnClickListener(
this);
edt_SendContent = (EditText) findViewById(R.id.
edt_SendContent);
}
@Override
public void onClick(View v) {
switch (v.getId()) {
//
根据点击事件跳转到发送事件的
activity
里面
case R.id.
btn_ok:
String content =
edt_SendContent.getText().toString();
//
使用
Event
发送事件
,
需要
post
方法
,
参数也比细数
Event
消息
,
且要和接收数据保持一直
EventBus.
getDefault().post(
new EventBusMessage(content));
Log.
d(
"eventBusThread", Thread.
currentThread().getName());
}
}
//接收消息,参数就是我们定义的EventBus消息类,和发送消息必须是同一个,加EventBus的注解
//
在写接收消息的方法时
,
方法名可自动能够自定义
,
参数必须是消息类设置的参数
,
权限必须是
public
//
方法名是灰色
,
是由于
studio
不识别
EventBus,
但仍可使用
@Subscribe(threadMode = ThreadMode.
MAIN)
public void receiveMessage(EventBusMessage eventBusMessage) {
txtShow.setText(eventBusMessage.
Message);
Log.
d(
"eventBusThread",
"ThreadMode.MAIN" + Thread.
currentThread().getName());
}
@Subscribe(threadMode = ThreadMode.
BACKGROUND)
public void receiveMessage1(EventBusMessage eventBusMessage) {
txtShow.setText(eventBusMessage.
Message);
Log.
d(
"eventBusThread",
"ThreadMode.MAIN111" + Thread.
currentThread().getName());
}
//
无论发送方实在子线程还是主线程
,
都会开一个新的子线程去运行
//
@Subscribe(threadMode = ThreadMode.
ASYNC)
public void receiveMessage2(EventBusMessage eventBusMessage) {
txtShow.setText(eventBusMessage.
Message);
Log.
d(
"eventBusThread",
"ThreadMode.ASYNC" + Thread.
currentThread().getName());
}
//
如果发送方实在主线程 就会开一个新的子线程去运行
//
如果发送方实在子线程 就会在子线程去运行
//
表示该方法和消息发送在同一个线程
@Subscribe(threadMode = ThreadMode.
POSTING)
public void receiveMessage3(EventBusMessage eventBusMessage) {
txtShow.setText(eventBusMessage.
Message);
Log.
d(
"eventBusThread",
" ThreadMode.POSTING" + Thread.
currentThread().getName());
}
//
销毁时解除
EventBus
@Override
protected void onDestroy() {
EventBus.
getDefault().unregister(
this);
super.onDestroy();
}
}
由图可见:
posting和MAIN仍会在主线程中运行 ,而BACKGROUND和ASYNC分别会创建一个新的子线程
子线程发送消息时
public class MainActivity
extends AppCompatActivity
implements View.OnClickListener {
private Button
btn_ok;
private TextView
txtShow;
private EditText edt_SendContent;
//EventBus
实际和广播非常相似
,
只不过使用简单
,
代码量少
,
性能更好
//MainActivity
就是接收消息的类
,
你的事件在哪接收
,
就在哪个类进行
EventBus
的注册和解除操作
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.
activity_main);
//
初始化控件
initView();
//
注册
EventBus,
参数是上下文
//
有注册
EventBus
就必须有解除注册的操作
(
一般在
onDestory
方法里执行解除注册
),
防止
oom
// EventBus.getDefault()
获取
EventBus
对象
EventBus.
getDefault().register(
this);
}
private void initView() {
btn_ok = (Button) findViewById(R.id.
btn_ok);
txtShow = (TextView) findViewById(R.id.
txtShow);
btn_ok.setOnClickListener(
this);
edt_SendContent = (EditText) findViewById(R.id.
edt_SendContent);
}
@Override
public void onClick(View v) {
switch (v.getId()) {
//
根据点击事件跳转到发送事件的
activity
里面
case R.id.
btn_ok:
new Thread(
new Runnable() {
@Override
public void run() {
String content =
edt_SendContent.getText().toString();
//
使用
Event
发送事件
,
需要
post
方法
,
参数也比细数
Event
消息
,
且要和接收数据保持一直
EventBus.
getDefault().post(
new EventBusMessage(content));
Log.
d(
"eventBusThread",Thread.
currentThread().getName());
}
}).start();
break;
}
}
//
接收消息
,
参数就是我们定义的
EventBus
消息类
,
和发送消息必须是同一个
,
加
EventBus
的注解
//在写接收消息的方法时,方法名可自动能够自定义,参数必须是消息类设置的参数,权限必须是public
//
方法名是灰色
,
是由于
studio
不识别
EventBus,
但仍可使用
@Subscribe(threadMode = ThreadMode.
MAIN)
public void receiveMessage(EventBusMessage eventBusMessage) {
txtShow.setText(eventBusMessage.
Message);
Log.
d(
"eventBusThread",
"ThreadMode.MAIN"+Thread.
currentThread().getName());
}
@Subscribe(threadMode = ThreadMode.
BACKGROUND)
public void receiveMessage1(EventBusMessage eventBusMessage) {
txtShow.setText(eventBusMessage.
Message);
Log.
d(
"eventBusThread",
"ThreadMode.MAIN111"+Thread.
currentThread().getName());
}
//
无论发送方实在子线程还是主线程
,
都会开一个新的子线程去运行
//
@Subscribe(threadMode = ThreadMode.
ASYNC)
public void receiveMessage2(EventBusMessage eventBusMessage) {
txtShow.setText(eventBusMessage.
Message);
Log.
d(
"eventBusThread",
"ThreadMode.ASYNC"+Thread.
currentThread().getName());
}
//
如果发送方实在主线程 就会开一个新的子线程去运行
//如果发送方实在子线程 就会在子线程去运行
//
表示该方法和消息发送在同一个线程
@Subscribe(threadMode = ThreadMode.
POSTING)
public void receiveMessage3(EventBusMessage eventBusMessage) {
txtShow.setText(eventBusMessage.
Message);
Log.
d(
"eventBusThread",
" ThreadMode.POSTING"+Thread.
currentThread().getName());
}
//
销毁时解除
EventBus
@Override
protected void onDestroy() {
EventBus.
getDefault().unregister(
this);
super.onDestroy();
}
}
输出的Log如下
由此可见
当发送方在子线程运行时
posting和background都会在这个子线程下运行, ASYNC会在一个新的子线程中运行,MAIN在主线程中运行
综上所述,可得出结论:
|
发送方在主线程 |
发送方在子线程 |
MAIN |
在主线程中运行 |
在主线程中运行 |
BACKGROUND |
在一个新建的子线程下运行 |
在该子线程下运行 |
ASYNC |
在一个新建的子线程下运行 |
在一个新建的子线程下运行 |
POSTING |
在主线程中运行 |
在该子线程下运行 |