Android EventBus的使用
项目中用到了以前没接触过的EventBus, 初步学习之后记录一下EventBus的用法:
一、概述
EventBus是一款基于观察者模式针对Android优化的发布/订阅事件总线。主要功能是替代Intent,Handler,BroadCast在Fragment,Activity,Service,线程之间传递消息.优点是开销小,代码更优雅以及将发送者和接收者解耦。
有关观察者设计模式可以参考 http://www.cnblogs.com/mengdd/archive/2013/02/07/2908929.html
二、使用
使用EventBus的步骤如下:
1.首先在项目的build.gradle中添加dependencies:
dependencies {
classpath 'com.android.tools.build:gradle:2.1.0'
}
2.新建一个用于传递的消息类
public class EventMessage {
private String msg;
public EventMessage(String msg){
this.Msg = msg;
}
public String getString(){
return msg;
}
}
3、在需要接受事件消息的Activity或者Fragment中注册EventBus
EventBus.getDefault().register(this);
4.同时需要在Activity或者Fragment生命周期结束后,注销EventBus
EventBus.getDefault().unregister(this);
5.在另外的Activity或者Fragment中发送消息
EventBus.getDefault().post(EventMessage eventMessage);
6.接收消息并处理
接受消息的函数有4种,后面会详细介绍四种不同函数的区别,此处列出其中一种
public void onEvent(EventMessage eventMessage){
//do something here...
}
准备工作到此结束,下面是一个实际的测试项目。
三、实战
首先是一个MainActivity,将会在其中注册EventBus和编写消息处理函数。对应的XML布局文件为R.layout.activity_main,代码如下:
package com.seven.hzxubowen.eventbustest;
import android.content.Intent;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;
import de.greenrobot.event.EventBus;
public class MainActivity extends AppCompatActivity {
TextView textView;
Button button;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
button = (Button) findViewById(R.id.test);
EventBus.getDefault().register(this);
}
public void goFirstActivity(View view){
Intent intent = new Intent(MainActivity.this, FirstActivity.class);
startActivity(intent);
}
public void onEvent(EventMessage eventMessage){
textView = (TextView) findViewById(R.id.onReceive);
textView.setText(eventMessage.getString());
Toast.makeText(this, "Message received", Toast.LENGTH_LONG).show();
}
@Override
public void onDestroy(){
super.onDestroy();
EventBus.getDefault().unregister(this);
}
}
相应的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"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context="com.seven.hzxubowen.eventbustest.MainActivity">
<Button
android:id="@+id/test"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:onClick="goFirstActivity"/>
<TextView
android:id="@+id/onReceive"
android:layout_gravity="center_horizontal"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>
可以看到,该页面有一个Button和一个TextView组件,其中点击Button会跳转至另外到FirstActivity。值得注意的是,在此Activity中我们注册了一个EventBus,并且编写了相应的消息处理函数,如果接受到对应的消息类EventMessage,将会在TextView组件中显示信息,并且发出一个Toast。
然后是FirstActivity的代码及其XML布局文件:
package com.seven.hzxubowen.eventbustest;
import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import de.greenrobot.event.EventBus;
/**
* Created by hzxubowen on 2016/5/12.
*/
public class FirstActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_first);
}
public void postMsg(View view){
EventBus.getDefault().post(new EventMessage("Hello world"));
}
}
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="postMsg"/>
</LinearLayout>
首先, 我们进入MainActivity 然后点击Button进入FirstActivity, 在FirstActivity中我们点击Button,会发现此时弹出了Toast并且回退至MainActivity时,Textview控件出现了我们预先在onEvent中设定的内容,至此一个完整的EventBus使用流程介绍完毕。
4、四种消息处理函数
实际上,EventBus有四种消息处理函数:
1、onEvent()
2、onEventMainThread()
3、onEventBackgroundThread()
4、onEventAsync()
这四种订阅函数都是使用onEvent开头的,它们的功能稍有不同,在介绍不同之前先介绍两个概念:
告知观察者事件发生时通过EventBus.post函数实现,这个过程叫做事件的发布,观察者被告知事件发生叫做事件的接收,是通过下面的订阅函数实现的。
onEvent:如果使用onEvent作为订阅函数,那么该事件在哪个线程发布出来的,onEvent就会在这个线程中运行,也就是说发布事件和接收事件线程在同一个线程。使用这个方法时,在onEvent方法中不能执行耗时操作,如果执行耗时操作容易导致事件分发延迟。
onEventMainThread:如果使用onEventMainThread作为订阅函数,那么不论事件是在哪个线程中发布出来的,onEventMainThread都会在UI线程中执行,接收事件就会在UI线程中运行,这个在Android中是非常有用的,因为在Android中只能在UI线程中跟新UI,所以在onEvnetMainThread方法中是不能执行耗时操作的。
onEventBackground:如果使用onEventBackgrond作为订阅函数,那么如果事件是在UI线程中发布出来的,那么onEventBackground就会在子线程中运行,如果事件本来就是子线程中发布出来的,那么onEventBackground函数直接在该子线程中执行。
onEventAsync:使用这个函数作为订阅函数,那么无论事件在哪个线程发布,都会创建新的子线程在执行onEventAsync.