-
EventBus使用详解(一)——初步使用EventBus
2014-10-31 20:16:10前言:EventBus是上周项目中用到的,网上的文章大都一样,或者过时,有用的没几篇,经过琢磨,请教他人,也终于弄清楚点眉目,记录下来分享给大家。 相关文章: 1、《EventBus使用详解(一)——初步使用EventBus...前言:EventBus是上周项目中用到的,网上的文章大都一样,或者过时,有用的没几篇,经过琢磨,请教他人,也终于弄清楚点眉目,记录下来分享给大家。
相关文章:
1、《EventBus使用详解(一)——初步使用EventBus》
2、《EventBus使用详解(二)——EventBus使用进阶》
一、概述
EventBus是一款针对Android优化的发布/订阅事件总线。主要功能是替代Intent,Handler,BroadCast在Fragment,Activity,Service,线程之间传递消息.优点是开销小,代码更优雅。以及将发送者和接收者解耦。
1、下载EventBus的类库
源码:https://github.com/greenrobot/EventBus2、基本使用
(1)自定义一个类,可以是空类,比如:
public class AnyEventType { public AnyEventType(){} }
(2)在要接收消息的页面注册:
eventBus.register(this);
(3)发送消息
eventBus.post(new AnyEventType event);
(4)接受消息的页面实现(共有四个函数,各功能不同,这是其中之一,可以选择性的实现,这里先实现一个):
public void onEvent(AnyEventType event) {}
(5)解除注册
eventBus.unregister(this);
顺序就是这么个顺序,可真正让自己写,估计还是云里雾里的,下面举个例子来说明下。
首先,在EventBus中,获取实例的方法一般是采用EventBus.getInstance()来获取默认的EventBus实例,当然你也可以new一个又一个,个人感觉还是用默认的比较好,以防出错。
二、实战
先给大家看个例子:
当击btn_try按钮的时候,跳到第二个Activity,当点击第二个activity上面的First Event按钮的时候向第一个Activity发送消息,当第一个Activity收到消息后,一方面将消息Toast显示,一方面放入textView中显示。
按照下面的步骤,下面来建这个工程:
1、基本框架搭建
想必大家从一个Activity跳转到第二个Activity的程序应该都会写,这里先稍稍把两个Activity跳转的代码建起来。后面再添加EventBus相关的玩意。
MainActivity布局(activity_main.xml)
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <Button android:id="@+id/btn_try" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="btn_bty"/> <TextView android:id="@+id/tv" android:layout_width="wrap_content" android:layout_height="match_parent"/> </LinearLayout>
新建一个Activity,SecondActivity布局(activity_second.xml)
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" tools:context="com.harvic.try_eventbus_1.SecondActivity" > <Button android:id="@+id/btn_first_event" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="First Event"/> </LinearLayout>
MainActivity.java (点击btn跳转到第二个Activity)
public class MainActivity extends Activity { Button btn; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); btn = (Button) findViewById(R.id.btn_try); btn.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { // TODO Auto-generated method stub Intent intent = new Intent(getApplicationContext(), SecondActivity.class); startActivity(intent); } }); } }
到这,基本框架就搭完了,下面开始按步骤使用EventBus了。
2、新建一个类FirstEvent
package com.harvic.other; public class FirstEvent { private String mMsg; public FirstEvent(String msg) { // TODO Auto-generated constructor stub mMsg = msg; } public String getMsg(){ return mMsg; } }
这个类很简单,构造时传进去一个字符串,然后可以通过getMsg()获取出来。
3、在要接收消息的页面注册EventBus:
在上面的GIF图片的演示中,大家也可以看到,我们是要在MainActivity中接收发过来的消息的,所以我们在MainActivity中注册消息。
通过我们会在OnCreate()函数中注册EventBus,在OnDestroy()函数中反注册。所以整体的注册与反注册的代码如下:
package com.example.tryeventbus_simple; import com.harvic.other.FirstEvent; import de.greenrobot.event.EventBus; import android.app.Activity; import android.content.Intent; import android.os.Bundle; import android.util.Log; import android.view.View; import android.widget.Button; import android.widget.TextView; import android.widget.Toast; public class MainActivity extends Activity { Button btn; TextView tv; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); //注册EventBus EventBus.getDefault().register(this); btn = (Button) findViewById(R.id.btn_try); 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(getApplicationContext(), SecondActivity.class); startActivity(intent); } }); } @Override protected void onDestroy(){ super.onDestroy(); EventBus.getDefault().unregister(this);//反注册EventBus } }
4、发送消息
发送消息是使用EventBus中的Post方法来实现发送的,发送过去的是我们新建的类的实例!
EventBus.getDefault().post(new FirstEvent("FirstEvent btn clicked"));
完整的SecondActivity.java的代码如下:
package com.example.tryeventbus_simple; import com.harvic.other.FirstEvent; import de.greenrobot.event.EventBus; import android.app.Activity; import android.os.Bundle; import android.view.View; import android.widget.Button; public class SecondActivity extends Activity { 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) { // TODO Auto-generated method stub EventBus.getDefault().post( new FirstEvent("FirstEvent btn clicked")); } }); } }
5、接收消息
接收消息时,我们使用EventBus中最常用的onEventMainThread()函数来接收消息,具体为什么用这个,我们下篇再讲,这里先给大家一个初步认识,要先能把EventBus用起来先。
在MainActivity中重写onEventMainThread(FirstEvent event),参数就是我们自己定义的类:
在收到Event实例后,我们将其中携带的消息取出,一方面Toast出去,一方面传到TextView中;
public void onEventMainThread(FirstEvent event) { String msg = "onEventMainThread收到了消息:" + event.getMsg(); Log.d("harvic", msg); tv.setText(msg); Toast.makeText(this, msg, Toast.LENGTH_LONG).show(); }
完整的MainActiviy代码如下:
package com.example.tryeventbus_simple; import com.harvic.other.FirstEvent; import de.greenrobot.event.EventBus; import android.app.Activity; import android.content.Intent; import android.os.Bundle; import android.util.Log; import android.view.View; import android.widget.Button; import android.widget.TextView; import android.widget.Toast; public class MainActivity extends Activity { Button btn; TextView tv; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); EventBus.getDefault().register(this); btn = (Button) findViewById(R.id.btn_try); 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(getApplicationContext(), SecondActivity.class); startActivity(intent); } }); } public void onEventMainThread(FirstEvent event) { String msg = "onEventMainThread收到了消息:" + event.getMsg(); Log.d("harvic", msg); tv.setText(msg); Toast.makeText(this, msg, Toast.LENGTH_LONG).show(); } @Override protected void onDestroy(){ super.onDestroy(); EventBus.getDefault().unregister(this); } }
好了,到这,基本上算初步把EventBus用起来了,下篇再讲讲EventBus的几个函数,及各个函数间是如何识别当前如何调用哪个函数的。
如果我的文章有帮到你,请关注哦。
源码地址:http://download.csdn.net/detail/harvic880925/8111357
请大家尊重原创者版权,转载请标明出处:http://blog.csdn.net/harvic880925/article/details/40660137 谢谢!
如果你喜欢我的文章,你可能更喜欢我的公众号
-
eventbus
2017-01-11 14:47:11EventBus概述
EventBus是一款针对Android优化的发布/订阅(publish/subscribe)事件总线。基于观察者模式的事件发布/订阅框架,开发者可以通过极少的代码去实现多个模块之间的通信,而不需要以层层传递接口的形式去单独构建通信桥梁。从而降低因多重回调导致的模块间强耦合,同时避免产生大量内部类。它拥有使用方便,性能高,接入成本低和支持多线程的优点,实乃模块解耦、代码重构必备良药。
主要功能是替代Intent,Handler,BroadCast在Fragment,Activity,Service,线程之间传递消息。简化了应用程序内各组件间、组件与后台线程间的通信。
优点是开销小,代码更优雅。以及将发送者和接收者解耦。比如请求网络,等网络返回时通过Handler或Broadcast通知UI,两个Fragment之间需要通过Listener通信,这些需求都可以通过EventBus实现。EventBus作为一个消息总线,有三个主要的元素:
- Event:事件。可以是任意类型的对象
- Subscriber:事件订阅者,接收特定的事件。在EventBus中,使用约定来指定事件订阅者以简化使用。即所有事件订阅都都是以onEvent开头的函数,具体来说,函数的名字是onEvent,onEventMainThread,onEventBackgroundThread,onEventAsync这四个,这个和ThreadMode(下面讲)有关。
- Publisher:事件发布者,用于通知 Subscriber
有事件发生。可以在任意线程任意位置发送事件,直接调用eventBus.post(Object) 方法,可以自己实例化 EventBus
对象,但一般使用默认的单例就好了:EventBus.getDefault(),
根据post函数参数的类型,会自动调用订阅相应类型事件的函数。
关于ThreadMode
前面说了,Subscriber的函数只能是那4个,因为每个事件订阅函数都是和一个ThreadMode相关联的,ThreadMode指定了会调用的函数。有以下四个ThreadMode:-
PostThread:事件的处理在和事件的发送在相同的进程,所以事件处理时间不应太长,不然影响事件的发送线程,而这个线程可能是UI线程。对应的函数名是onEvent。
-
MainThread:
事件的处理会在UI线程中执行。事件处理时间不能太长,这个不用说的,长了会ANR的,对应的函数名是onEventMainThread。 -
BackgroundThread:事件的处理会在一个后台线程中执行,对应的函数名是onEventBackgroundThread,虽然名字
是BackgroundThread,事件处理是在后台线程,但事件处理时间还是不应该太长,因为如果发送事件的线程是后台线程,会直接执行事件,如果当前线程是UI线程,事件会被加到一个队列中,由一个线程依次处理这些事件,如果某个事件处理时间太长,会阻塞后面的事件的派发或处理。 -
Async:事件处理会在单独的线程中执行,主要用于在后台线程中执行耗时操作,每个事件会开启一个线程(有线程池),但最好限制线程的数目。
根据事件订阅都函数名称的不同,会使用不同的ThreadMode,比如果在后台线程加载了数据想在UI线程显示,订阅者只需把函数命名onEventMainThread。
对相应的函数名,进一步解释一下:
-
onEvent:如果使用onEvent作为订阅函数,那么该事件在哪个线程发布出来的,onEvent就会在这个线程中运行,也就是说发布事件和接收事件线程在同一个线程。使用这个方法时,在onEvent方法中不能执行耗时操作,如果执行耗时操作容易导致事件分发延迟。
-
onEventMainThread:如果使用onEventMainThread作为订阅函数,那么不论事件是在哪个线程中发布出来的,onEventMainThread都会在UI线程中执行,接收事件就会在UI线程中运行,这个在Android中是非常有用的,因为在Android中只能在UI线程中跟新UI,所以在onEvnetMainThread方法中是不能执行耗时操作的。
-
onEventBackground:如果使用onEventBackgrond作为订阅函数,那么如果事件是在UI线程中发布出来的,那么onEventBackground就会在子线程中运行,如果事件本来就是子线程中发布出来的,那么onEventBackground函数直接在该子线程中执行。
-
onEventAsync:使用这个函数作为订阅函数,那么无论事件在哪个线程发布,都会创建新的子线程在执行onEventAsync。
使用步骤:
【引入】eventbus
compile 'org.greenrobot:eventbus:3.0.0'
【定义】event事件消息实体类:Event可以是任意类型的对象。
【订阅者】:
(谁接收onEvent谁注册eventbus、取消eventbus)
【①注册】eventbus(OnCreate()、onCreateView函数中注册EventBus)//事件注册 EventBus.getDefault().register(this);
【②接收】事件
(注意:1、所有事件订阅都都是以onEvent开头的函数:
onEvent,onEventMainThread,onEventBackgroundThread,onEventAsync。2、要加上 @Subscribe的注解,
3、所有事件处理方法必需是public void
类型的,并且只有一个参数表示)//定义处理接收方法 @Subscribe public void onEventMainThread(UserEvent event) { btn.setText(event.getUserName()); service_tv.setText(event.getUserName()); }
【③取消注册】:(OnDestroy()函数中反注册eventbus)
//取消注册 EventBus.getDefault().unregister(this);
【发布者】
【发布】事件:直接调用EventBus的
post(Object)
方法//事件发送 EventBus.getDefault().post(new MainSendEvent("from TwoActivity msg"));
关于Activity之间的通信
第一步:自定义一个定义Event事件,用来封装信息
例子如下:public class UserEvent { private String userName; public UserEvent() { } public UserEvent(String userName) { this.userName = userName; } public String getUserName() { return userName; } public void setUserName(String userName) { this.userName = userName; } }
第二步:注册订阅者和定义处理方法:第一个activity注册和接收
public class MainActivity extends Activity { private Button btn, fragment_btn; private TextView service_tv; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); //注册订阅者 EventBus.getDefault().register(this); btn = (Button) findViewById(R.id.btn); 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); } }); fragment_btn = (Button) findViewById(R.id.fragment_btn); fragment_btn.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Intent intent = new Intent(MainActivity.this, FragmenTestActivity.class); startActivity(intent); } }); service_tv = (TextView) findViewById(R.id.service_tv); startService(new Intent(this, EventTestService.class)); } //定义处理接收方法 @Subscribe public void onEventMainThread(UserEvent event) { btn.setText(event.getUserName()); service_tv.setText(event.getUserName()); } @Override protected void onDestroy() { super.onDestroy(); EventBus.getDefault().unregister(this); } }
第三步:第二个activity发送事件
public class SecondActivity extends Activity { private Button btn; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_second); btn = (Button) findViewById(R.id.btn); btn.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { final UserEvent ue = new UserEvent(); ue.setUserName("非著名程序员"); EventBus.getDefault().post(ue); finish(); } }); } }
fragment,service等之间的通信和activity之间的基本一样,就不过多的贴代码解释了,感兴趣的同学可以直接下载demo,里面有它们之间的通信。
使用EventBus应该注意以下几点:
- 同一个onEvent函数(处理接收函数)不能被注册两次,所以不能在一个类中注册同时还在父类中注册。
- 消息的接收是根据参数中的类名来决定执行哪一个接收处理方法的。即:订阅者的处理方法是根据订阅事件的类型来确定订阅函数的。
- 每个事件可以有多个订阅者。
- 当Post一个事件时,这个事件类的父类的事件也会被Post。
- 所有事件处理方法必需是public void类型的,并且只有一个参数表示EventType。
-
Eventbus
2016-09-19 15:58:39EventbusEventBus是一个Android端优化的publish/subscribe消息总线,简化了应用程序内各组件间、组件与后台线程间的通信。比如请求网络,等网络返回时通过Handler或Broadcast通知UI,两个Fragment之间需要通过Listener通信,这些需求都可以通过。
EventBus是一款针对Android优化的发布/订阅事件总线。主要功能是替代Intent,Handler,BroadCast在Fragment,Activity,Service,线程之间传递消息.优点是开销小,代码更优雅。以及将发送者和接收者解耦。
源码:https://github.com/greenrobot/EventBus
具体看看代码怎么写
1.导入架包
compile 'org.greenrobot:eventbus:3.0.0'
2.自定义一个类
public class FirstEvent implements Serializable{ private String mMsg; public FirstEvent(String msg) { mMsg = msg; } public String getmMsg() { return mMsg; } }
3.初始化注册
EventBus.getDefault().register(this);
4.发送信息
EventBus.getDefault().post(new FirstEvent("我是EventBus的返回值!!!"));
5.接收信息
@Subscribe
public void onEventMainThread(FirstEvent event) { String msg = "onEventMainThread收到了消息:" + event.getmMsg(); Log.d("harvic", msg); tv_main = (TextView) findViewById(R.id.tv_main); tv_main.setText(msg); // Toast.makeText(this, msg, Toast.LENGTH_LONG).show(); }
在这里有几种方式结束onEvent:如果使用onEvent作为订阅函数,那么该事件在哪个线程发布出来的,onEvent就会在这个线程中运行,也就是说发布事件和接收事件线程在同一个线程。使用这个方法时,在onEvent方法中不能执行耗时操作,如果执行耗时操作容易导致事件分发延迟。
onEventMainThread:如果使用onEventMainThread作为订阅函数,那么不论事件是在哪个线程中发布出来的,onEventMainThread都会在UI线程中执行,接收事件就会在UI线程中运行,这个在Android中是非常有用的,因为在Android中只能在UI线程中跟新UI,所以在onEvnetMainThread方法中是不能执行耗时操作的。
onEventBackground:如果使用onEventBackgrond作为订阅函数,那么如果事件是在UI线程中发布出来的,那么onEventBackground就会在子线程中运行,如果事件本来就是子线程中发布出来的,那么onEventBackground函数直接在该子线程中执行。
onEventAsync:使用这个函数作为订阅函数,那么无论事件在哪个线程发布,都会创建新的子线程在执行
6.解除注册EventBus.getDefault().unregister(this);
具体也就这些步骤 不过有一点没弄明白的就是只有在点击返回键的时候他才会把文本显示在Textview上面 我用Intent跳转就不能把值赋TextView上面 如果哪位知道 请告诉我 非常感谢!!
如果你想看了解更仔细点 请访问
http://blog.csdn.net/harvic880925/article/details/40660137
-
EventBus
2016-05-09 14:44:23EventBus概述
EventBus是一款针对Android优化的发布/订阅事件总线。
主要功能是替代Intent,Handler,BroadCast在Fragment,Activity,Service,
线程之间传递消息.优点是开销小,代码更优雅。以及将发送者和接收者解耦。
1、下载EventBus的类库
jar:http://download.csdn.net/detail/menglele1314/9514367
EventBus的使用
首先必须要入库
onCreate() 注册EventBus EventBus.register(Object ),注册的对象决定发布事件的参数
所在方法的反射范围,一般用this,表示扫描当前类中所有的方法。
onDestroy() 注销EventBus EventBus.unRegister(Object)
发布事件:EventBus.post(参数) 参数可以是任何类型,一般为实体类。
一般在子线程中发布获得的数据,然后通过在主线程中的方法来接收参数,并更新UI。
注意:处理事件的方法一定要加上@Subscribe注解EventBus.getDefault().register(this);//订阅事件 EventBus.getDefault().post(object);//发布事件 EventBus.getDefault().unregister(this);//取消订阅
PostThread
这是默认的模式,订阅者会在发布者所在的线程中调用。这种模式开销最小,避免了线程之间的切换。所以完成时间很短,并且不需要主线程参与的简单任务建议使用这种模式。例如:public void onEvent(FirstEvent event) { log(event.getMsg()); }
MainThread
这种模式订阅者会在主线程中调用。如果事件发布是在主线程,那么事件处理程序会立即被调用。使用这种模式事件处理必须尽快返回,以避免阻塞主线程。例如:public void onEventMainThreadFirstEvent event) { log(event.getMsg()); }
BackgroundThread
这种模式订阅者会在后台线程中调用。如果事件发布不在主线程,事件处理方法会直接在发布线程中调用;如果事件发布在主线程,EventBus则会依次传递所有的事件到一个后台进程。使用这种模式必须尽快返回以避免阻塞后台进程。public void onEventBackgroundThread(MessageEvent event){ log(event.getMsg()); }
Async
事件处理方法在一个单独的线程中调用。他始终是独立于发布线程和主线程。发布事件不需要等待事件处理方法的完成。如果使用耗时的操作应当使用这种模式,比如连接网络。应当避免同一时间触发大量的、长时间运行的异步处理方法,从而限制并发线程的数量。EventBus使用了线程池来有效的重用线程。public void onEventAsync(MessageEvent event){ log(event.getMsg()); }
-
eventBus
2020-11-10 16:50:29import eventBus from ‘…/mlib/util/eventbus.js’; beforeDestroy(){ var that = this; eventBus.$emit('configItemKey', { 'configItemKey': that.configItemKeylist, 'type': that.type, 'scrollTop':...
-
处理机调度的层次
-
最新人教版五年级下册语文第七单元基础过关知识整理.doc
-
2013年水资源公报.docx
-
OpenCV中的显著性检测 Saliency Detection
-
OSG学习源代码学习+cmake
-
python从入门到全栈开发·入门篇
-
移动端rem布局项目源码.zip
-
单元测试UnitTest+Pytest【Selenium3】
-
基于Java的RTSP服务源码
-
XLSReadWritell 6.00.26 for Tokyo 10.2
-
golang组合模式
-
树莓派搭建开发环境所需的工具.zip
-
学生管理系统.cpp
-
学生信息管理系统python
-
机器学习Attack and Defense.pdf
-
完美解码软件安装包purecode2009
-
mybatis基础操作(CRUD+注解)
-
【数据分析-随到随学】Tableau数据分 析+PowerBI
-
使用Python编写目录扫描工具
-
QC_T29106-2014汽车电线束技术条件最新_PDF解密.pdf