EventBus 听起来好像很厉害的样子:哪么他是用来干什么的呢?
EventBus 是一个通信框架,,,线程与线程之间的通信,在认识它之前是用Handler来进行通信的.
EventBus是一款针对Android的publish/subscribe(发布 / 订阅)消息事件总线,它简化了组件之间的通信,使我们的应用程序更加简单、通信更加快捷。
再来看看它的组成
EventBus事件主线由四大部分组成:
- Publisher发布者:用于分发我们的Event事件,在EventBus中通过post方法进行分发传送。
- Subscriber订阅者:用于接受我们的事件,我们在订阅事件中处理我们接收的数据。订阅事件有四种,都是以onEvent开发。
- Event事件:任何一个对应都可以作为事件,比如任何字符串,事件是发布者和订阅者之间的通信载体。
- EventBus:类似于中转站,将我们的事件进行对应的分发处理。
Subscriber的ThreadMode
EventBus中的Subscriber有四种订阅函数。
- onEvent:使用onEvent作为订阅函数,则事件在哪个线程发布出来的,onEvent就会在这个线程中运行,也就是说发布事件和接收事件线程在同一个线程。使用这个方法时,在onEvent方法中不能执行耗时操作,如果执行耗时操作容易导致事件分发延迟。
- onEventMainThread:使用onEventMainThread作为订阅函数,则不论事件是在哪个线程中发布出来的,onEventMainThread都会在UI线程中执行,接收事件就会在UI线程中运行,这个在Android中是非常有用的,因为在Android中只能在UI线程中跟新UI,所以在onEvnetMainThread方法中是不能执行耗时操作,不然引起ANR异常。
- onEventBackground:使用onEventBackgrond作为订阅函数,如果事件是在UI线程中发布出来的,那么onEventBackground就会在子线程中运行,如果事件本来就是子线程中发布出来的,那么onEventBackground函数直接在该子线程中执行。
- onEventAsync:使用这个函数作为订阅函数,那么无论事件在哪个线程发布,都会创建新的子线程在执行onEventAsync.
分析以上四种ThreadMode,我们可以明显发现上面四种类型就是为了解决我们的组件之间通信,举个例子,以往我们开启一个子线程进行download,然后通过Hanlder进行发布消息在UI线程中更新我们的UI组件。、
、EventBus的使用步骤
使用快捷键shift+Ctrl+Alt+S然后添加依赖 搜索EventBus3.0进行导入依赖
我们在Activity的onCreate()方法中进行注册:
EventBus.getDefault().register(this);
在onDestroy()方法中进行反注册:
protected void onDestroy() {
super.onDestroy();
EventBus.getDefault().unregister(this);
}
根据我们的需要进行一种接收处理即可。例如:
public void onEvent(EventText eventText){
tv_textTextView.setText(eventText.getText());
}
这些是EventBus的最基本使用步骤,我们先来概括性的总结几个方法:
- EventBus.getDefault().register(Object subscriber):注册EventBus
- EventBus.getDefault().unregister(Object subscriber):反注册EventBus
- EventBus.getDefault().post(Object event):发送消息事件
- public void onEvent*****(Object event):消息接收处理
- EventBus.getDefault().registerSticky(Object subscriber):粘性EventBus注册,用在此种情况消息先发送,后注册订阅者,如果使用register,会导致我们接收不到消息。
Intent通过跳转时,intent.put跳转到第二个Activitiy,在第二个Activity中 通过getIntent().getxxx来进行Activity之间的数据交流.而EventBus则是通过一个post方法来使其他注册过EventBus的类来得到数据.相对来说,EventBus的结构更方便于数据的传递,因为他的post方法传递的是一个对象(一个Javaben),我们可以根据需求去定义这个JavaBean的成员变量,可以放集合,基本数据类型等.而在数据的传递之间可以通过简单的set,get方法来进行.简化了数据传递的逻辑.并且接收消息的这个在onCreate()方法之前调用
可以反注册 即释放资源 优化资源至关重要
注意:Event只是线程间的通信,并不能进行进程间的通信.
MainAcivity
public class MainActivity extends Activity { Button btn; TextView tv; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); EventBus.getDefault().register(this); btn = (Button) findViewById(R.id.btn_try); tv = (TextView)findViewById(R.id.tv); btn.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { // TODO Auto-generated method stub Intent intent = new Intent(getApplicationContext(), SecondActivity.class); startActivity(intent); } }); } @Subscribe public void aa(EventBusMessage event) { String msg = "aa:" + event.getMessage(); Log.d("harvic", msg); tv.setText(msg); Toast.makeText(this, msg, Toast.LENGTH_LONG).show(); } @Override protected void onDestroy(){ super.onDestroy(); EventBus.getDefault().unregister(this); } } 容器类
public class EventBusMessage { //定义了发送类型 public String Message; //有参构造 public EventBusMessage(String message) { Message = message; } //写一个GET方法 public String getMessage() { return Message; } }SecondActivitypublic class SecondActivity extends AppCompatActivity { private Button btn_FirstEvent; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_second); btn_FirstEvent = (Button) findViewById(R.id.btn_first_event); btn_FirstEvent.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { // TODO Auto-generated method stub EventBus.getDefault().post( new EventBusMessage("FirstEvent btn clicked")); } }); } }
MainXML<?xml version="1.0" encoding="utf-8"?> <LinearLayout 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" android:orientation="vertical"> <Button android:id="@+id/btn_try" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="btn_bty"/> <TextView android:id="@+id/tv" android:layout_width="wrap_content" android:layout_height="match_parent"/> </LinearLayout>activity_second.xml<?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:id="@+id/activity_second" android:layout_width="match_parent" android:layout_height="match_parent" android:paddingBottom="@dimen/activity_vertical_margin" android:paddingLeft="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin" android:paddingTop="@dimen/activity_vertical_margin" tools:context="com.example.anadministrator.eventbus.SecondActivity"> <Button android:id="@+id/btn_first_event" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="First Event"/> </RelativeLayout>
/
接下来是粘性事件的代码
效果:第一个Activity发消息,点击跳转到第二个Activity接收到消息并吐司//EventBus消息类,一个容器,负责存放一些数据,方便另一个订阅者(接受者),获取消息 public class EventMessage { //定义发送的数据类型 public String message; //有参构造 public EventMessage(String message) { this.message = message; } //get方法 public String getMessage() { return message; } List<String> list; public List<String> getList() { return list; } public void setList(List<String> list) { this.list = list; } }MainActivitypublic class MainActivity extends AppCompatActivity implements View.OnClickListener { private Button butJump; private Button mBtnTry; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); initView(); } private void initView() { butJump = (Button) findViewById(R.id.butJump); butJump.setOnClickListener(this); mBtnTry = (Button) findViewById(R.id.butSend); mBtnTry.setOnClickListener(this); } @Override public void onClick(View v) { switch (v.getId()) { case R.id.butJump: startActivity(new Intent(MainActivity.this, Main2Activity.class)); break; case R.id.butSend: EventMessage message = new EventMessage("发消息到Main2"); EventBus.getDefault().postSticky(message); break; } } }Main2Activitypublic class Main2Activity extends AppCompatActivity { /** * 收到的消息: */ private TextView mTv; /** * 跳转到第三个Activity */ private Button mButTo3; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main2); initView(); EventBus.getDefault().register(this); } @Subscribe(sticky = true) public void onEventMainThread(EventMessage event) { System.out.println("onEventMainThread"); String msg = "onEventMainThread收到了消息:" + event.getMessage(); mTv.setText(msg); Toast.makeText(this, msg, Toast.LENGTH_LONG).show(); } private void initView() { mTv = (TextView) findViewById(R.id.tv); } @Override protected void onDestroy() { super.onDestroy(); EventBus.getDefault().removeAllStickyEvents(); EventBus.getDefault().unregister(this); } }activity_mainXml<?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:id="@+id/activity_main" android:layout_width="match_parent" android:layout_height="match_parent" android:paddingBottom="@dimen/activity_vertical_margin" android:paddingLeft="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin" android:paddingTop="@dimen/activity_vertical_margin" > <Button android:layout_centerInParent="true" android:id="@+id/butJump" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="跳转到第二个Activity"/> <Button android:layout_below="@id/butJump" android:layout_centerInParent="true" android:id="@+id/butSend" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="发消息"/> </RelativeLayout>
activity_main2.xml<?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:id="@+id/activity_main2" android:layout_width="match_parent" android:layout_height="match_parent" android:paddingBottom="@dimen/activity_vertical_margin" android:paddingLeft="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin" android:paddingTop="@dimen/activity_vertical_margin" > <TextView android:id="@+id/tv" android:text="收到的消息:" android:textSize="20sp" android:layout_width="wrap_content" android:layout_height="wrap_content"/> <TextView android:id="@+id/tvvv" android:text="这里是第二个Activity" android:layout_centerInParent="true" android:textSize="20sp" android:layout_width="wrap_content" android:layout_height="wrap_content"/> </RelativeLayout>