EventBus 原来接触过,也使用过,不过感觉效果不太好,就没有仔细看过,今天认真看了下官方文档(源码看完了,没看太懂,好多细节没注意到),自己写个demo测试了下,顺便记录下
GIthub链接
官方使用说明文档
一**.方法介绍**
@Subscribe(threadMode = ThreadMode.MAIN, sticky = true, priority = 0)
注册方法有三个参数:
threadMode :指定消息接收类型,默认为POSTING加粗样式
sticky :是否粘性 默认为false
priority :优先级 默认为0
1.ThreadMode有四种模式,其中下面是个人的理解
/**
* 当threadMode模式为ThreadMode.POSTING 时,发送eventBus的消息不管是否是粘性接收方法都能接收到
* 1.与sticky是否为true无关
* 2.与发送消息是否为粘性无关
* 3.消息的接收顺序与priority值的大小有关,值越大优先级越高
*
* @param event ThreadMode.POSTING:事件处理与发送在同一个线程中,因此线程不能被阻塞
*
* ThreadMode.MAIN:事件处理在UI线程中,因此不能进行耗时操作
*
* ThreadMode.MAIN_ORDERED 事件处理始终排队进行处理
*
* ThreadMode.BACKGROUND 在Android上,将在后台线程中调用订阅者。如果发布线程不是主线程,则将在发布线程中直接调用订阅者方法*。
* 如果发布线程是主线程,则EventBus使用单个后台线程,
* 该线程将按顺序传递其所有事件。使用此模式的订阅者应尝试快速返回以避免阻止后台线程。如果不在Android上,则始终使用后台线程
*
* ThreadMode.ASYNC 始终调用单独的线程,处理耗时操作,网络操作,如果任务过多会启用线程池进行线程的复用
*/
2.sticky 设置是否为粘性,
粘性:会保存在内存中
非粘性:不会保存在内存中
3.priority 优先级
int类型 ,数值越大,接收消息的优先级越大,
4.EventBus.getDefault().register(this); 注册eventBus事件,可以在activity,fragment,service中使用
5.EventBus.getDefault().unregister(this); 取消注册eventBus事件,可以在activity,fragment,service中使用
6.EventBus.getDefault().isRegistered(this) 判断是否已经注册
7.EventBus.getDefault().postSticky(); 发送粘性消息
8.EventBus.getDefault().post();; 发送非粘性消息
9.EventBus.getDefault().removeStickyEvent() 移除粘性消息
10.EventBus.getDefault().removeAllStickyEvents(); 移除所有的粘性消息
11.EventBus.getDefault().cancelEventDelivery(); //阻止其它注册的事件接收该消息 ,其中threadmode 必须为POSTING才能使用,否则会报错;
二,使用
在app.build中引入
dependencies {
implementation 'org.greenrobot:eventbus:3.1.1'
}
1.activity中分两种情况
public class MainActivity extends AppCompatActivity {
private static final String TAG = "MainActivity";
private TextView textSend;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
textSend = findViewById(R.id.textSend);
textSend.setOnClickListener(v -> {
startActivity(new Intent(MainActivity.this, ReceiverActivity.class));
});
}
@Subscribe(threadMode = ThreadMode.MAIN, sticky = true, priority = 0)
public void defaultMessageText(MessageEvent event) {
try {
if (event == null) {
Log.d(TAG, "defaultMessageText: ------event:null");
return;
}
JSONObject jsonObject = new JSONObject(event.getMessage());
Log.d(TAG, "defaultMessageText: -------event:" + event + "\n" + "name:" + jsonObject.optString("name"));
} catch (JSONException e) {
e.printStackTrace();
Log.d(TAG, "defaultMessageText: -------event:" + event.getMessage());
}
}
@Override
protected void onStart() {
super.onStart();
if (!EventBus.getDefault().isRegistered(this)) {
EventBus.getDefault().register(this);
}
}
@Override
protected void onStop() {
super.onStop();
if (EventBus.getDefault().isRegistered(this)) {
EventBus.getDefault().unregister(this);
}
}
}
ReceiverActivity代码
public class ReceiverActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_receiver);
Button sendText = findViewById(R.id.sendMes);
sendText.setOnClickListener(v -> {
sendText();
});
}
void sendText() {
String mesJson = "{\"name\":\"张三\",\"age\":\"24\",\"address\":{\"province\":\"江苏\",\"city\":\"苏州\",\"street\":\"元和\"}}";
MessageEvent messageEvent = MessageEvent.ceratMesEvent(mesJson);
EventBus.getDefault().postSticky(messageEvent);
finish();
}
}
MessageEvent代码
public class MessageEvent {
public String Message;
//json;string
public String type;
public static MessageEvent ceratMesEvent(String message) {
return new MessageEvent(message);
}
public MessageEvent(String message) {
Message = message;
}
public String getMessage() {
return Message;
}
public void setMessage(String message) {
Message = message;
}
}
分别在activity1的onstart()和onstop()注册和取消注册,当点击按钮跳转到activity2,在activity2中点击按钮发送消息,并且结束activity2,这时,使用非粘性发送消息,activity1是接收不到消息的,必须使用粘性发送才能接收到消息
如果activity1中的注册和取消注册分别在oncreat或者是ondestory中,在activity2中使用非粘性就能接收到消息了,代码如下
MainActivity
public class MainActivity extends AppCompatActivity {
private static final String TAG = "MainActivity";
private TextView textSend;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
if (!EventBus.getDefault().isRegistered(this)) {
EventBus.getDefault().register(this);
}
textSend = findViewById(R.id.textSend);
textSend.setOnClickListener(v -> {
startActivity(new Intent(MainActivity.this, ReceiverActivity.class));
});
}
@Subscribe(threadMode = ThreadMode.MAIN, sticky = false, priority = 0)
public void defaultMessageText(MessageEvent event) {
try {
if (event == null) {
Log.d(TAG, "defaultMessageText: ------event:null");
return;
}
JSONObject jsonObject = new JSONObject(event.getMessage());
Log.d(TAG, "defaultMessageText: -------event:" + event + "\n" + "name:" + jsonObject.optString("name"));
} catch (JSONException e) {
e.printStackTrace();
Log.d(TAG, "defaultMessageText: -------event:" + event.getMessage());
}
}
@Override
protected void onDestroy() {
super.onDestroy();
if (EventBus.getDefault().isRegistered(this)) {
EventBus.getDefault().unregister(this);
}
}
}
ReceiverActivity
public class ReceiverActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_receiver);
Button sendText = findViewById(R.id.sendMes);
sendText.setOnClickListener(v -> {
sendText();
});
}
void sendText() {
String mesJson = "{\"name\":\"张三\",\"age\":\"24\",\"address\":{\"province\":\"江苏\",\"city\":\"苏州\",\"street\":\"元和\"}}";
MessageEvent messageEvent = MessageEvent.ceratMesEvent(mesJson);
EventBus.getDefault().post(messageEvent);
finish();
}
}
2.service,activity之间的消息传递
MyService 代码中启动一个定时的线程,定时发送数据,然后在activity中接收
package com.ytlz.myeventbus;
import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import com.ytlz.myeventbus.evbusObject.MessageEvent;
import org.greenrobot.eventbus.EventBus;
import java.util.Date;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
public class MyService extends Service {
ScheduledExecutorService service = Executors.newSingleThreadScheduledExecutor();
public MyService() {
}
Runnable runnable = new Runnable() {
@Override
public void run() {
Date date = new Date();
EventBus.getDefault().post(new MessageEvent("我是Service发来的消息:时间是"+date.getHours()+"h"+date.getMinutes()+"m"+date.getSeconds()+"s"));
}
};
@Override
public void onCreate() {
super.onCreate();
sendMesTiming();
}
@Override
public IBinder onBind(Intent intent) {
// TODO: Return the communication channel to the service.
throw new UnsupportedOperationException("Not yet implemented");
}
void sendMesTiming(){
service.scheduleWithFixedDelay(runnable, 200, 3000, TimeUnit.MILLISECONDS);
}
}
MainActivity代码和上面一致,在使用service与activity发送消息时,一定要注意activity的生命周期,当activity不可见时,接收到service信息时,是不能更新ui的
3.fragment,activity之间的消息传递
fragment代码就一个按钮,点击发送消息给activity
package com.ytlz.myeventbus.fragment;
import android.content.Intent;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import com.ytlz.myeventbus.MainActivity;
import com.ytlz.myeventbus.R;
import com.ytlz.myeventbus.evbusObject.MessageEvent;
import org.greenrobot.eventbus.EventBus;
import org.greenrobot.eventbus.Subscribe;
import org.greenrobot.eventbus.ThreadMode;
/**
* Created by wyb on 2019-09-17.
*/
public class SendMesFragment extends Fragment {
private static final String TAG = "SendMesFragment";
Button button;
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View view = (View) inflater.inflate(R.layout.fragment_sendmes, container, false);
initViews(view);
return view;
}
void initViews(View view) {
button = view.findViewById(R.id.fSend1);
button.setOnClickListener(v -> {
EventBus.getDefault().post(MessageEvent.ceratMesEvent("我是fragment"));
});
}
}
FragmentTestActivity 代码 其中 SendMesFragment 是依附在FragmentTestActivity 中的
public class FragmentTestActivity extends AppCompatActivity {
private static final String TAG = "FragmentTestActivity";
TextView receiveText;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
EventBus.getDefault().register(this);
setContentView(R.layout.activity_fragment_test);
receiveText = findViewById(R.id.receiveText);
}
@Subscribe(threadMode = ThreadMode.MAIN)
public void activityMesReceiver(MessageEvent event) {
if (receiveText == null) {
Log.d(TAG, "activityMesReceiver: receiveText can not be null");
return;
}
if (event==null || TextUtils.isEmpty(event.getMessage())){
Log.d(TAG, "activityMesReceiver: event is null");
return;
}
receiveText.setText(event.getMessage());
}
@Override
protected void onDestroy() {
super.onDestroy();
EventBus.getDefault().unregister(this);
}
}
SendMesFragment 与其它非宿主activity进行信息传递
public class SendMesFragment extends Fragment {
private static final String TAG = "SendMesFragment";
Button button;
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View view = (View) inflater.inflate(R.layout.fragment_sendmes, container, false);
initViews(view);
return view;
}
void initViews(View view) {
button = view.findViewById(R.id.fSend1);
button.setOnClickListener(v -> {
//这里要使用粘性发送消息,否则接收不到
EventBus.getDefault().postSticky(MessageEvent.ceratMesEvent("我是fragment"));
//跳转到mainActivity,并且传递消息给Mainactivity
startActivity(new Intent(getActivity(), MainActivity.class));
});
}
@Subscribe(threadMode = ThreadMode.POSTING, sticky = false, priority = 0)
public void defaultMessageText(MessageEvent event) {
Log.d(TAG, "defaultMessageText: -------event:" + event.getMessage());
EventBus.getDefault().cancelEventDelivery(event);
button.setText(event.getMessage());
}
}
MainActivity 代码
public class MainActivity extends AppCompatActivity {
private static final String TAG = "MainActivity";
private TextView textSend;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//startService(new Intent(this, MyService.class));
textSend = findViewById(R.id.textSend);
textSend.setOnClickListener(v -> {
//startActivity(new Intent(MainActivity.this, ReceiverActivity.class));
EventBus.getDefault().post(MessageEvent.ceratMesEvent("我是Mainactivity返回的消息"));
finish();
});
}
总结:eventBus的灵活使用可以使我们的代码简洁不少,各种界面之间的通信,传值变得非常方便,我们可以把eventBus进行二次封装,其中吧eventMes进行封装成公共类,这样我们只需要根据eventMes其中一个参数的类型来进行消息的处理就行了