当前位置:   article > 正文

EventBus的使用简介_org.greenrobot.eventbus.eventbusexception: subscri

org.greenrobot.eventbus.eventbusexception: subscriber class com.csxbank.oto.

EventBus的简介

官网是对EventBus给出的解释如下:
/**
 * EventBus is a central publish/subscribe event system for Android. Events are posted ({@link #post(Object)}) to the
 * bus, which delivers it to subscribers that have a matching handler method for the event type. To receive events,
 * subscribers must register themselves to the bus using {@link #register(Object)}. Once registered, subscribers
 * receive events until {@link #unregister(Object)} is called. Event handling methods must be annotated by
 * {@link Subscribe}, must be public, return nothing (void), and have exactly one parameter
 * (the event).
 */
大体的意思是:EventBus是Android的中央发布/订阅事件系统。事件通过post()方法被发布到总线,并将其(事件)传递给与事件类型匹配的处方的订阅者当订阅者需要接收事件时,订阅者必须通过register()方法将自己注册到总线。完成注册后,订阅者就可以接收打牌事件,直到订阅者调用unregister()方法。订阅者用于事件处理方法必须用Subscribe进行注释,而且该方法必须是必须是公用的(public),没有返回值(void),并且只有一个参数(事件)方法。

EventBus的引入

在build.gradle引入'org.greenrobot:eventbus:3.0.0'

dependencies {
    compile 'org.greenrobot:eventbus:3.0.0'
}

EventBus的基本使用

现在需要解决一个问题:需要在2个不同界面之间实现数据(事件)的传递。即将在界面1中进行按钮点击操作的时候,程序需要向界面2发送消息。

1.新建一个类,用作EventBus的事件

package com.ymsoft.eventbustest;

/**
 * Created by Xiongxl on 2017/2/24.
 */
public class FirstEvent
{
    private String mMsg;
    public FirstEvent(String msg)
    {
        mMsg = msg;
    }

    public String getMsg()
    {
        return mMsg;
    }
}

2.创建活动1:MainActivity

public class MainActivity extends AppCompatActivity
{
    Button btn;
    TextView tv;

    @Override
    protected void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        btn = (Button) findViewById(R.id.btn_next);
        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(MainActivity.this, SecondActivity.class);
                startActivity(intent);
            }
        });
    }
}

3.MainActivity对应的布局文件

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
              android:layout_width="match_parent"
              android:layout_height="match_parent"
              android:background="#00FF00"
              android:orientation="vertical">
    <Button
        android:id="@+id/btn_next"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="跳转界面2"/>
    <TextView
        android:id="@+id/tv"
        android:layout_width="wrap_content"
        android:layout_height="match_parent"/>
</LinearLayout>

4.创建活动2:SecondActivity

public 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)
            {

            }
        });
    }
}

5.SecondActivity相对应的布局文件:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
              android:layout_width="match_parent"
              android:layout_height="match_parent"
              android:background="#ff0000"
              android:orientation="vertical">

    <Button
        android:id="@+id/btn_first_event"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="First Event"/>

</LinearLayout>

6.EventBus的使用过程

现在实现的效果为:通过在SecondActivity中点击Button,向MainActivity中发送一个消息/事件,并将消息内容赋值给MainActivity的TextView控件。此时我们采用EventBus来完成该任务。
根据API文档可知,需要使用EventBus必须进行注册register();所以在MainActivity的onCreate()方法中添加代码:
EventBus.getDefault().register(this);
当MainActivity停止时,需要注销EventBus,重写onStop()方法
@Override
protected void onStop()
{
    super.onStop();
    EventBus.getDefault().unregister(this);
}
在secondActivity的Button控件的点击事件中,使用EventBus的post方法,将消息传递给MainActivity。并将消息内容赋值给MainActivity中TextView的Text属性。
btn_FirstEvent.setOnClickListener(new View.OnClickListener()
{
    @Override
    public void onClick(View v)
    {
        // TODO Auto-generated method stub
        EventBus.getDefault().post(new FirstEvent("FirstEvent btn clicked"));
    }
});
在MainActivity中,需要有一个方法,接收由SecondActivity发送过来的消息。
注意:根据API文件的解释,用于接收消息的方法必须用Subscribe修饰,同时为public和没有放回数据(void)的只有一个参数(事件)的方法。
@Subscribe
public void onEventMainThread(FirstEvent event)
{
    String msg = "获取到了SecondActivity发送过来的信息:" + event.getMsg();
    tv.setText(msg);
    Toast.makeText(this, msg, Toast.LENGTH_LONG).show();
}
假如方法没有使用Subscribe注释,将报如下错误:
org.greenrobot.eventbus.EventBusException: Subscriber class **** and its super classes have no public methods with the @Subscribe annotation

EventBus的其他介绍

1.EventBus的四种ThreadMode(线程模型)

EventBus3.0有以下四种ThreadMode:

  • POSTING(默认):如果使用事件处理函数指定了线程模型为POSTING,那么该事件在哪个线程发布出来的,事件处理函数就会在这个线程中运行,也就是说发布事件和接收事件在同一个线程。在线程模型为POSTING的事件处理函数中尽量避免执行耗时操作,因为它会阻塞事件的传递,甚至有可能会引起ANR。
  • MAIN: 
    事件的处理会在UI线程中执行。事件处理时间不能太长,长了会ANR的。
  • BACKGROUND:如果事件是在UI线程中发布出来的,那么该事件处理函数就会在新的线程中运行,如果事件本来就是子线程中发布出来的,那么该事件处理函数直接在发布事件的线程中执行。在此事件处理函数中禁止进行UI更新操作。
  • ASYNC:无论事件在哪个线程发布,该事件处理函数都会在新建的子线程中执行,同样,此事件处理函数中禁止进行UI更新操作。
指定线程模式的方法:在注释中指定线程模式@Subscribe(threadMode = ThreadMode.MAIN)
@Subscribe(threadMode = ThreadMode.MAIN)
public void onEventMainThread(SecondEvent event)
{
    String msg = "SecondEvent onEventMainThread收到了消息:" + event.getMsg();
    tv.setText(msg);
    Toast.makeText(this, msg, Toast.LENGTH_LONG).show();
}
注:接收消息的方法的参数(事件)名称与post()中的参数(事件)一致,否则,将接收不到post传递的消息。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/我家小花儿/article/detail/251295
推荐阅读
相关标签
  

闽ICP备14008679号