Android中Activity、Service、Fragment之间的相互通信比较麻烦,主要有以下几种方式:
(1)使用广播,发送者发出广播,接收者接收广播后进行处理;
(2)使用Handler和Message,如下载线程完成下载任务后,给UI发送Message,UI收到Message后更新界面。
以上两种比较繁琐,接下来给大家介绍一种比较简单有效的方法事件总线(定义:针对事件提供统一订阅,发布以达到组件间通信的解决方案。 原理:观察者模式。发送者把消息发送到事件总线,然后事件总线在接收者中查找哪些方法注册了这个事件,如果某个方法注册了这个事件,就触发该方法。)。事件总线框架提供了一种更灵活更强大而又更加完美解耦的解决方案,在很多场合,从开发效率,执行性能和设计思路上都要优于BroadcastReceiver。
EventBus使用起来很简单,分为以下五个步骤:
自定义一个事件类
在需要订阅事件的地方注册事件
发送事件
处理事件(前面说过,消息处理的方法可以随便取名,但是需要添加一个注解@Subscribe,并且要指定线程模型,默认为POSTING。)
取消事件订阅
android Studio 配置gradle:
compile 'org.greenrobot:eventbus:3.0.0'
package com.xiaolajiao.technologyset;
public class MessageEvent {
private String message;
public MessageEvent(String message) {
this.message = message;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
}
package com.xiaolajiao.technologyset;
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 org.greenrobot.eventbus.EventBus;
import org.greenrobot.eventbus.Subscribe;
import org.greenrobot.eventbus.ThreadMode;
public class MainActivity extends AppCompatActivity {private TextView tv_message;
private Button bt_message,bt_subscription;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
tv_message = (TextView) this.findViewById(R.id.tv_message);
tv_message.setText("MainActivity");
bt_message=(Button)this.findViewById(R.id.bt_message);
bt_message.setText("跳转到SecondActivity");
bt_message.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
startActivity(new Intent(MainActivity.this, SecondActivity.class));
}
});
//注册事件
EventBus.getDefault().register(this);
}
@Override
protected void onDestroy() {
super.onDestroy();
//取消注册事件
EventBus.getDefault().unregister(this);
}
}
这里我们的ThreadMode设置为MAIN,事件的处理会在UI线程中执行,用TextView来展示收到的事件消息
@Subscribe(threadMode = ThreadMode.MAIN)
public void onMoonEvent(MessageEvent messageEvent){
tv_message.setText(messageEvent.getMessage());
}
package com.xiaolajiao.technologyset;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import org.greenrobot.eventbus.EventBus;
public class SecondActivity extends AppCompatActivity {
private Button bt_message;
private TextView tv_message,bt_subscription;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
tv_message = (TextView) this.findViewById(R.id.tv_message);
tv_message.setText("SecondActivity");
bt_message=(Button)this.findViewById(R.id.bt_message);
bt_message.setText("发送事件");
bt_message.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
EventBus.getDefault().post(new MessageEvent("欢迎关注siwen的博客"));
finish();
}
});
}
}
在MainActivity中我们将注册事件添加到button的点击事件中:
bt_subscription.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//注册事件
EventBus.getDefault().register(MainActivity.this);
}
});
在MainActivity中新写一个方法用来处理粘性事件:
@Subscribe(threadMode = ThreadMode.POSTING,sticky = true)
public void ononMoonStickyEvent(MessageEvent messageEvent){
tv_message.setText(messageEvent.getMessage());
}
在SecondActivity中我们定义一个Button来发送粘性事件:
bt_subscription.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
EventBus.getDefault().postSticky(new MessageEvent("粘性事件"));
finish();
}
});
运行效果,首先我们在MainActivity中并没有订阅事件,而是直接跳到SecondActivity中点击发送粘性事件按钮,这时界面回到MainActivity,我们看到TextView仍旧显示着MainActivity的字段,这是因为我们现在还没有订阅事件。
接下来我们点击订阅事件,TextView发生改变显示“粘性事件”。
-keepattributes *Annotation*
-keepclassmembers class ** {
@org.greenrobot.eventbus.Subscribe <methods>;
}
-keep enum org.greenrobot.eventbus.ThreadMode { *; }
# Only required if you use AsyncExecutor
-keepclassmembers class * extends org.greenrobot.eventbus.util.ThrowableFailureEvent {
<init>(java.lang.Throwable);
}
参考资料
快速Android开发系列通信篇之EventBus
Android事件总线(一)EventBus3.0用法全解析
Android事件总线(二)EventBus3.0源码解析
android Studio 配置gradle:
compile 'com.squareup:otto:1.3.8'
public class BusData {
public String message;
public BusData(String message){
this.message=message;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
}
public class OttoBus extends Bus{
private volatile static OttoBus bus;
private OttoBus (){
}
public static OttoBus getInstance() {
if (bus == null) {
synchronized (OttoBus.class){
if(bus==null){
bus = new OttoBus();
}
}
}
return bus;
}
}
public class MainActivity extends AppCompatActivity {
private Button bt_jump;
private TextView tv_message;
private Bus bus;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
tv_message= (TextView) this.findViewById(R.id.tv_message);
bt_jump= (Button) this.findViewById(R.id.bt_jump);
bt_jump.setText("跳转到SecondActivity");
bt_jump.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
startActivity(new Intent(MainActivity.this,SecondActivity.class));
}
});
bus=OttoBus.getInstance();
bus.register(this);
}
@Override
protected void onDestroy() {
super.onDestroy();
//取消注册订阅事件
bus.unregister(this);
}
otto同样需要注册和取消注册订阅事件,通过OttoBus得到Bus对象,调用Bus的register和unregister方法来注册和取消注册。
2.5 事件订阅者处理事件
@Subscribe
public void setContent(BusData data) {
tv_message.setText(data.getMessage());
}
和EventBus一样用@Subscribe来订阅事件,同样的用textView来显示接收到的消息。
2.6 使用post发送事件
public class SecondActivity extends AppCompatActivity {
private Button bt_jump;
private OttoBus bus;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
bt_jump= (Button) this.findViewById(R.id.bt_jump);
bt_jump.setText("发送事件");
bt_jump.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
OttoBus.getInstance().post(new BusData("siwen的博客更新了"));
finish();
}
});
}
}
public class SecondActivity extends AppCompatActivity {
private Button bt_jump;
private OttoBus bus;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
bt_jump= (Button) this.findViewById(R.id.bt_jump);
bt_jump.setText("发送事件");
bt_jump.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
finish();
}
});
bus=OttoBus.getInstance();
bus.register(this);
}
@Produce
public BusData setInitialContent() {
return new BusData("siwen的博客更新了");
}
@Override
protected void onDestroy() {
super.onDestroy();
bus.unregister(this);
}
}
它指定这个事件接收函数执行在哪个线程中,具体有如下三个选项:
public class MainActivity extends Activity {
// 代码省略
@Subcriber(tag = "csuicide")
private void csuicideMyself(String msg) {
// do sth
finish();
}
@Subcriber(mode = ThreadMode.MAIN)
private void toastMsgFromEvent(String msg) {
// do sth
}
@Subcriber(tag = "async", mode = ThreadMode.ASYNC)
private void executeAsync(final String msg) {
// do sth
}
// 代码省略
}
为MainActivity添加了以下三个订阅函数: