EventBus使用分为四个步骤:
- (EventBusIndex)项目编译期可以利用APT预解析带@Subscribe的类,减少运行时分发事件的时间,但这步也是可以选择不做的。
- (Register)注册需要监听的类到EventBus里面
- (post/postSticky)任何地方都可以发布事件,事件分为两种,普通事件和sticky事件,后者主要的作用是事件发送之后新订阅这个事件的类会拿到上一个同类型的事件
- (unregister)Register的类记得要在销毁的地方做unregister,不然会造成内存泄漏
EventBus的核心原理:
1.通过注解的方式注册监听回调方法
2.监听者可以设置优先级
3.维护类许多Cache缓存解析过的数据,不用重复查找
4.添加sticky功能,使刚注册的对象能拿到监听类型前面发布过的事件
5.事件也可以通知到监听事件父类事件的方法
6.监听回调可以设置在不同线程响应
eventBus四种线程模型:
- POSTING (默认) 表示事件处理函数的线程跟发布事件的线程在同一个线程。
- MAIN 表示事件处理函数的线程在主线程(UI)线程,因此在这里不能进行耗时操作。
- BACKGROUND 表示事件处理函数的线程在后台线程,因此不能进行UI操作。如果发布事件的线程是主线程(UI线程),那么事件处理函数将会开启一个后台线程,如果果发布事件的线程是在后台线程,那么事件处理函数就使用该线程。
- ASYNC 表示无论事件发布的线程是哪一个,事件处理函数始终会新建一个子线程运行,同样不能进行UI操作
EventBus的优点:
基于观察者的模式设计的库,能够实现对事件的分发处理,也解耦了代码
EventBus的缺点:
- 操作麻烦,每一个事件,都要定义一个类;
- 增加方法数;
- 导致事件发送者和接收者都依赖耦合事件类;
- 如果忘记做注销操作,就会造成内存泄漏
Post和postSticky的原理:
通过post或者postSticky发布事件,如果postSticky则会把事件放到stickyEvents里面,后面注册的对象如果有sticky方法会从这里拿。
- 事件会被放到对应线程的PostingThreadState里面的eventQueue里面,如果PostingThreadState之前没在消费事件,则调用PostingThreadState开始消费事件。
- 如果设置支持事件父类也能监听到这个事件,则找到所有的事件列表
- 逐一发送事件,根据事件类型从subscriptionsByEventType找到所有的监听者Subscription
- 根据Subscription里面的响应线程分发事件
粘性事件:当事件还没有注册的时候,此时发送普通事件是无法接收到的,需要发送粘性事件
package com.example.androidinterviewjxd.eventbus;
import androidx.appcompat.app.AppCompatActivity;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import com.example.androidinterviewjxd.R;
import org.greenrobot.eventbus.EventBus;
public class EventBusFirstActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_event_bus_first);
EventBus.getDefault().post(new EventOne());
EventTwo eventTwo = new EventTwo();
EventBus.getDefault().postSticky(eventTwo);
//移除粘性事件 方法1
// boolean b = EventBus.getDefault().removeStickyEvent(eventTwo);
// Log.d("eventbustest","removeStickyEvent============="+b);
//移除粘性事件 方法2
// EventTwo stickyEventData = EventBus.getDefault().getStickyEvent(EventTwo.class);
// if(stickyEventData != null) {
// EventBus.getDefault().removeStickyEvent(stickyEventData);
// }
//移除粘性事件 方法3
// EventBus.getDefault().removeAllStickyEvents();
}
public void enterSecond(View view){
startActivity(new Intent(EventBusFirstActivity.this,EventBusSecondActivity.class));
}
}
package com.example.androidinterviewjxd.eventbus;
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.widget.Toast;
import com.example.androidinterviewjxd.R;
import org.greenrobot.eventbus.EventBus;
import org.greenrobot.eventbus.Subscribe;
import org.greenrobot.eventbus.ThreadMode;
public class EventBusSecondActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_event_bus_second);
EventBus.getDefault().register(this);
}
@Subscribe
public void receiveNormal(EventOne eventOne){
Log.d("eventbustest","receiveNormal=============");
}
// UI updates must run on MainThread
@Subscribe(sticky = true, threadMode = ThreadMode.MAIN)
public void receiveSticky(EventTwo eventData) {
Log.d("eventbustest","receiveSticky=============");
}
@Override
protected void onDestroy() {
super.onDestroy();
EventBus.getDefault().unregister(this);
}
}