EventBus之简单用法

xiaoxiao2021-02-28  112

什么是EventBus

先不去看官方的理解,我个人理解为就是在任何你想和UI线程传递数据时候他都能给你进行数据传递,UI线程和传输数据的子线程是高度解耦合的,可以说是相当流氓,想怎么传数据就怎么传数据。

用法

用法比较简单,首先在build.gradle里添加

compile 'org.greenrobot:eventbus:3.0.0'

这里为了方便使用,同时添加了butterKnife的依赖,butterKnife的使用请自行百度

先声明事件消息的实体类,并写一个get方法 public class MyEvent { private String msg ; public MyEvent(String msg) { this.msg= msg; } public String getMsg(){ return msg; } } 接下来我们创建两个Activity,一个作为接收方的MainActivity,另一个作为发送方的SecondActivity

MainActivity

public class MainActivity extends AppCompatActivity { @BindView(R.id.tv_1) TextView tv_1; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); ButterKnife.bind(this); EventBus.getDefault().register(this); //在要接收消息的地方注册EventBus } @OnClick(R.id.btn_1) public void onTest(View view){ Intent intent = new Intent(MainActivity.this,SecondActivity.class); startActivity(intent); //跳转到SecondActivity } //收到SecondActivity发送的消息 @Subscribe public void onMessageEvent(MyEvent event){ String msg = event.getMsg(); tv_1.setText(msg); //将收到的消息输入TextView Toast.makeText(MainActivity.this,msg,Toast.LENGTH_SHORT).show(); } } @Override protected void onDestroy(){ super.onDestroy(); EventBus.getDefault().unregister(this);//注销EventBus }

SecondActivity

public class SecondActivity extends AppCompatActivity { @BindView(R.id.et_2) EditText et_2; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_second); ButterKnife.bind(this); } @OnClick(R.id.btn_2) public void onTest2(View view){ String str = et_2.getText().toString(); //获取EditText内容 EventBus.getDefault().post(new MyEvent(str)); //发送消息给MainActivity super.onBackPressed(); //调用返回键回到MainActivity } }

两个布局文件 activity_main.xml

<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" xmlns:app="http://schemas.android.com/apk/res-auto" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" tools:context="com.example.eventbusdemo.MainActivity"> <TextView android:id="@+id/tv_1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Hello World!" /> <Button android:id="@+id/btn_1" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="跳转到第二个界面"/> </LinearLayout>

activity_second.xml

<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" tools:context="com.example.eventbusdemo.SecondActivity"> <EditText android:id="@+id/et_2" android:layout_width="match_parent" android:layout_height="wrap_content" /> <Button android:id="@+id/btn_2" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="向第一个页面发送消息,并显示在TextView上"/> </LinearLayout>

运行结果如下:

这样就完成了一个简单的使用EventBus来传递消息的Demo

EventBus的线程模式

EventBus有四种线程模式:

ThreadMode: POSTING 这时候订阅者执行的线程与事件的发布者所在的线程为同一个线程。也就是说事件由哪个线程发布的,订阅者就在哪个线程中执行。这个也是EventBus默认的线程模式,也就是说在上面的例子中用的就是这种ThreadMode。由于没有线程的切换,也就意味消耗的资源也是最小的。如果一个任务不需要多线程的,也是推荐使用这种ThreadMode的。在EventBus以前的版本中对应onEvent方法。例如: @Subscribe public void onMessageEvent(MyEvent event){ ........ }

或者

@Subscribe(threadMode = ThreadMode.POSTING) public void onMessageEvent(MyEvent event){ ......... } ThreadMode: MAIN 从它的名字就很容易可以看出,他是在Android的主线程中运行的。如果提交的线程也是主线程,那么他就和ThreadMode.POSTING一样了。当然在这里由于是在主线程中运行的,所以在这里就不能执行一些耗时的任务。在EventBus以前的版本中对应onEventMainThread方法。例如: //在Android主线程中执行 @Subscribe(threadMode = ThreadMode.MAIN) public void onMessageEvent(MyEvent event){ ......... } ThreadMode: BACKGROUND 这种模式下,我们的订阅者将会在后台线程中执行。如果发布者是在主线程中进行的事件发布,那么订阅者将会重新开启一个子线程运行,若是发布者在不是在主线程中进行的事件发布,那么这时候订阅者就在发布者所在的线程中执行任务。在EventBus以前的版本中对应onEventBackground方法。例如: //在后台线程中执行 @Subscribe(threadMode = ThreadMode.BACKGROUND) public void onMessageEvent(MyEvent event){ ......... } ThreadMode: ASYNC 在这种模式下,订阅者将会独立运行在一个线程中。不管发布者是在主线程还是在子线程中进行事件的发布,订阅者都是在重新开启一个线程来执行任务。在EventBus以前的版本中对应onEventAsync方法。例如: // 在独立的线程中执行 @Subscribe(threadMode = ThreadMode.ASYNC) public void onMessageEvent(MyEvent event){ ......... }

具体例子不贴上来,根据实际情况调用就好

消息接收的优先级与取消事件

在EventBus中是可以定义接收消息的优先级的,就是指定谁先接收,谁后接收 用法如下:

//这里使用默认的接收线程方式,不指定线程,根据发送方来确定 @Subscribe(priority = 1) public void onMessageEvent1(MyEvent event){ Log.d("1", "1收到了消息"); }

那么我们就可以写出这样的例子:

public class MainActivity extends AppCompatActivity { @BindView(R.id.tv_1) TextView tv_1; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); ButterKnife.bind(this); EventBus.getDefault().register(this); } @OnClick(R.id.btn_1) public void onTest(View view){ Intent intent = new Intent(MainActivity.this,SecondActivity.class); startActivity(intent); } @Subscribe(priority = 1) public void onMessageEvent1(MyEvent event){ Log.d("1", "1收到了消息"); } @Subscribe(priority = 2) public void onMessageEvent2(MyEvent event){ Log.d("2", "2收到了消息"); } @Subscribe(priority = 3) public void onMessageEvent3(MyEvent event){ Log.d("3", "3收到了消息"); EventBus.getDefault().cancelEventDelivery(event); //取消事件 } @Subscribe(priority = 4) public void onMessageEvent4(MyEvent event){ Log.d("4", "4收到了消息"); } @Subscribe(priority = 5) public void onMessageEvent5(MyEvent event){ Log.d("5", "5收到了消息"); } @Override protected void onDestroy(){ super.onDestroy(); EventBus.getDefault().unregister(this);//注销EventBus } }

从上面的代码可以看出,我们定义了一系列的接收事件,并给它们定义优先级,并在优先级为3的接收事件中取消消息发送事件,那么执行的结果如下:

可以看出 优先级为 2 和 1 的事件确实没有接收到消息。

本文讲解就到这里,之后会陆续补充内容

转载请注明原文地址: https://www.6miu.com/read-79815.html

最新回复(0)