EventBus3.0的基础使用。

EventBus是一款针对Android优化的发布/订阅事件总线。

主要功能是替代Intent,Handler,BroadCast在Fragment,Activity,Service,线程之间传递消息.优点是开销小,代码更优雅。以及将发送者和接收者解耦。

在我看来,eventbus在各个界面的传值特别方便。无论在哪个界面,只要注册了eventBus都可以收到任何界面post过来的消息,类似于观察者模式,但是比观察者模式实现简单很多,不用写太多的接口。

在需要获取值的地方实现订阅,方法如下:

MainActivity.java

    // 在ui线程执行
    @Subscribe(threadMode = ThreadMode.MainThread)
    public void onUserEvent(String content) {
        tv.setText(content);
        Toast.makeText(getApplicationContext(), "MainActivity收到了:"+content, 0).show();
    }

在需要传值的地方使用EventBus.getDefault().post();

ThridActivity.java

@Override
    public void onClick(View v) {
        EventBus.getDefault().post("你好");
    }

回到MainActivity
EventBus3.0的基础使用。_第1张图片

执行post方法的时候,MainActivity的onUserEvent收到post传来的值。需要注意的是如果是int这些基础类型,需要写成Integer等封装类
onUserEvent这个方法名,与EventBus没有关系,是根据自己的情况命名。

现在知道eventBus简单传值了,在很多情况下,简单的传值并不能满足需求。

比如intent传自己的封装类:

1:Gson将他转成字符串,传过去再用Gson转回来。

2:实现Serializable接口,或者Parcelable接口。

在EventBus就直接写好订阅,然后在需要传的地方post就行了。

public class Student {
    String name;
    String age;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getAge() {
        return age;
    }

    public void setAge(String age) {
        this.age = age;
    }
    @Override
    public String toString() {
        return "name = " + name + ",age = " + age;
    }
}

MainActivity.java

    @Subscribe(threadMode = ThreadMode.MainThread)
    public void onUserEvent(Student student) {
        tv.setText(student.toString());
    }

Thrid.java

    @Override
    public void onClick(View v) {
// EventBus.getDefault().post("你好");
        Student s = new Student();
        s.setName("Hoyn");
        s.setAge("18");
        EventBus.getDefault().post(s);
    }

回到MainActivity
EventBus3.0的基础使用。_第2张图片

再接着传更复杂的list集合。

MainActivity.java

    @Subscribe(threadMode = ThreadMode.MainThread)
    public void onUserEvent(List<Student> list_student) {
        String str_student = "";
        for (Student student : list_student) {
            str_student += student.toString();
        }
        tv.setText(str_student);
    }

ThridActivity.java

    @Override
    public void onClick(View v) {
//      EventBus.getDefault().post("你好");
        List<Student> list_student = new ArrayList<Student>();
        Student s = new Student();
        s.setName("Hoyn");
        s.setAge("18");
        list_student.add(s);
        list_student.add(s);
        list_student.add(s);
        EventBus.getDefault().post(list_student);
    }

回到MainActivity
EventBus3.0的基础使用。_第3张图片

好了,简单的传值就这样了。

只不过现在都是main->second->thrid。thrid给main传值。类似于startActivityForResult的回调,只不过他不是Activity之间的回调,而是你想回调给栈内任何一个注册了EventBus的Activity或Fragment(Service什么的就不说了)。

那么,main>second的带值传递要怎么做呢?

一般来说是:

Intent intent = new Intent(xxxx); intent.put(xxxx); startActivity(intent);

EventBus:

MainActivity.java

@Override
    public void onClick(View v) {
        Intent intent = new Intent(MainActivity.this, SecondActivity.class);
        Student student = new Student();
        student.setAge("18");
        student.setName("Hoyn");
        EventBus.getDefault().postSticky(student);
        startActivity(intent);
    }

SecondActivity.java

@Override
    public void onClick(View v) {
        Intent intent = new Intent(MainActivity.this, SecondActivity.class);
        Student student = new Student();
        student.setAge("18");
        student.setName("Hoyn");
        EventBus.getDefault().postSticky(student);
        startActivity(intent);
    }

SecondActivity:
EventBus3.0的基础使用。_第4张图片

接下来就是,比较复杂的就是传list< T >了。EventBus是根据class反射建立对象的,list只有list的class,没有list< T >的class,又没有gson的用type来建立List集合对象

我说下我的解决方法吧。

MainActivity.java

    List<Student> list  = new ArrayList<Student>();

    @Override
    public void onClick(View v) {
        Intent intent = new Intent(MainActivity.this, SecondActivity.class);
        Student student= new Student();
        student.setAge("18");
        student.setName("Hoyn");
        list.add(student);
        list.add(student);
        EventBus.getDefault().postSticky(student);
        startActivity(intent);
    }
    //在第二个页面post(true)过来,他就执行了这个页面的post(List)
    @Subscribe(threadMode = ThreadMode.MainThread)
    public void isOK(Boolean isOK) {
        if(isOK){
            EventBus.getDefault().post(list);
        }
    }

SecondActivity

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

        tv = (TextView) findViewById(R.id.textView);
        findViewById(R.id.button).setOnClickListener(this);
        EventBus.getDefault().register(this);
        EventBus.getDefault().post(true);
    }

    @Subscribe(threadMode = ThreadMode.MainThread)
    public void getStudentList(List<Student> list_student) {
        String str_student = "";
        for (Student student : list_student) {
            str_student += student.toString();
        }
        tv.setText(str_student);
    }

SecondActivity:
EventBus3.0的基础使用。_第5张图片

好了,传值和回调值都解决了。这就是EventBus强大之处。

ps.说一下在使用EventBus3.0遇到的坑。
1、EventBus在post是不需要注册和反注册的,任何界面都能直接EventBus.getDefault().post()
2、在注册和反注册的界面,必须实现至少一个订阅@Subscribe(threadMode = ThreadMode.MainThread)方法,否则提示没有方法,造成崩溃
3、订阅的事件是同时触发的(如果可以单独选择触发请告诉我,谢谢),触发是根据参数,而不是方法名。

在不同的acitivity分别订阅了这两个事件,任何一个地方post(String)两个地方都会触发。
@Subscribe(threadMode = ThreadMode.MainThread)
public void getSS(String aa);

@Subscribe(threadMode = ThreadMode.MainThread)
public void getBB(String bb);
在同一个activity订阅了2个事件,貌似2个都会触发。(记不清了),总之别这样做,很容易出现问题。

4、List< Student >,List< Teacher >在EventBus是认为同一个集合,他只是反射的list.class,至于里面的泛型T他是不管的,也就是说只要post了任何一个集合,订阅了这两个事件的都会收到这个集合,然后报错。所以一般不推荐写太多的集合,如果一定需要,可能需要自己写一个集合类继承ArrayList,用这种方法区别List(未测试,如果不行,请联系我删除这句)

转一下ThreadMode的四中方式,转载自http://blog.csdn.net/angcyo/article/details/48166849

    @Subscribe(threadMode = ThreadMode.MainThread) //在ui线程执行
        public void onUserEvent(UserEvent event) {
    }
    @Subscribe(threadMode = ThreadMode.BackgroundThread) //在后台线程执行
        public void onUserEvent(UserEvent event) {
    }
    @Subscribe(threadMode = ThreadMode.Async) //强制在后台执行
        public void onUserEvent(UserEvent event) {
    }
    @Subscribe(threadMode = ThreadMode.PostThread) //默认方式, 在发送线程执行
        public void onUserEvent(UserEvent event) {
    }

附上Demo

你可能感兴趣的:(android,EventBus)