EventBus之简单用法

来源:互联网 发布:同济启明星软件 编辑:程序博客网 时间:2024/05/21 17:23

什么是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 的事件确实没有接收到消息。

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

原创粉丝点击