EventBus3.0的基础使用。
来源:互联网 发布:python正则表达式大全 编辑:程序博客网 时间:2024/05/19 13:06
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
执行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
再接着传更复杂的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
好了,简单的传值就这样了。
只不过现在都是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:
接下来就是,比较复杂的就是传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:
好了,传值和回调值都解决了。这就是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
- EventBus3.0的基础使用。
- EventBus3.0的使用
- EventBus3.0的使用
- EventBus3.0的使用
- EventBus3.0的使用
- EventBus3.0的使用
- EventBus3.0的使用
- EventBus3.0的使用
- EventBus3.0的使用
- EventBus3.0的使用
- EventBus3.0的使用
- EventBus3.0的使用
- EventBus3.0的初次使用
- EventBus3.0的简单使用
- Eventbus3.0的简单使用
- EventBus3.0的使用详解
- EventBus3.0的简单使用
- EventBus3.0的简单使用
- 如何快速定位自己代码中出现的问题
- Red Hat 7.X安装VMware Tools
- 文章标题
- ArrayList和数组间的相互转换
- Css定位
- EventBus3.0的基础使用。
- springboot加载jsp的问题
- linux中Apache 2.4.7打开cgi功能模块与测试
- 调用手机震动
- JAVA语言之归并排序
- private,public,protected
- bnu 51644 Whalyzh's Problem(网络流,最大密度图) (北师16校赛)
- 利用Python下的draw_net.py画网络结构图
- RecyclerView可以在xml文件中配置的特别属性