AgeraBus簡介
AgeraBus 是基于谷歌開源的Agera實現(xiàn)的Android事件總線百拓,實現(xiàn)了EventBus基本常用的功能琴锭,下面將為你一一介紹,如果要了解Agera衙传,可以去看我文章后面推薦的兩個地址决帖。
添加依賴
在項目根目錄的build.gradle中添加:
dependencies {
compile 'xyz.zpayh:agerabus:1.0.4'
compile 'com.google.android.agera:agera:1.3.0'
}
基本用法
一個事件總線的使用總是少不了訂閱、取消蓖捶、發(fā)送事件地回,還有獲取數(shù)據(jù),下面我們來看下AgeraBus的基本用法俊鱼,首先我們定義一個普通的類充當一個事件類型:
public class User{
private String mName;
public User(String name){
this.mName = name;
}
public void setName(String name){
this.mName = name;
}
public String getName(){
return this.mName;
}
}
簡單的訂閱刻像,注銷事件以及獲取最新數(shù)據(jù):
public class BaseActivity extends Activity implements Updatable{
...
@Override
protected void onStart() {
super.onStart();
//register 同一個Updatable實例只能訂閱同一種事件類型一次,如需重新
//訂閱并闲,要先取消訂閱细睡,如果多次訂閱會拋出異常,這里Activity實現(xiàn)了Updatable接口
AgeraBus.getDefault()
.addUpdatable(this,User.class);
}
@Override
protected void onStop() {
super.onStop();
// unregister 取消訂閱時焙蚓,這個Updatable實例必須已經(jīng)訂閱了此事件纹冤,
// 如果取消沒有訂閱的Updatable洒宝,會拋出異常
AgeraBus.getDefault()
.removeUpdatable(this,User.class);
}
/**
* 接收到事件時調(diào)用的接口
*
*/
@Override
public void update() {
// accept
AgeraBus.getDefault()//獲取默認總線
.getSupplier(User.class)//拿到數(shù)據(jù)提供者
.get()//獲取封裝好的數(shù)據(jù)Result<User>
.ifSucceededSendTo(new Receiver<User>() {//數(shù)據(jù)成功接收到就發(fā)送給接收者
@Override
public void accept(@NonNull User value) {
//打印吐司
Toast.makeText(BaseActivity.this, value.getName(), Toast.LENGTH_SHORT).show();
}
});
}
}
上面就是最基本的訂閱购公、取消事件以及接收數(shù)據(jù)。至于發(fā)送事件的話雁歌,只有一個入口:
AgeraBus.getDefault().post(new User("Sherlock"));
上面就是AgeraBus最基本的用法宏浩,下面簡單講解一下,
Agera 使用 push event, pull data 模型(推送事件,拉取數(shù)據(jù))靠瞎。 push event:被觀察者只做事件通知比庄,不攜帶任何數(shù)據(jù); pull data:觀察者根據(jù)自己需要從數(shù)據(jù)倉庫(Repository.get())拉取數(shù)據(jù)求妹。
由于push event, pull data模型是數(shù)據(jù)和事件通知分離的,所以上面看到的Updatable接口設(shè)計上并沒有攜帶數(shù)據(jù)過來的佳窑,我們在update方法里制恍,如果要拉取數(shù)據(jù),可以從AgeraBus拿到訂閱事件的數(shù)據(jù)提供者:
Supplier,再從Supplier中獲取數(shù)據(jù)神凑。
進階用法
EventBus 提供了線程分發(fā)净神,訂閱優(yōu)先級,取消事件分發(fā)溉委,粘性事件鹃唯,而這些在AgeraBus也都一一實現(xiàn)了。
使用這些高級功能時瓣喊,我們的訂閱方法是使用另外一個接口坡慌。下面會介紹到。
線程分發(fā)與線程模型
ThreadMode有四種:
PostThread藻三,MainThread洪橘,BackgroundThread,Async.
- PostThread 訂閱者將會被調(diào)用在與發(fā)布線程同樣的線程中棵帽。上面基本用法就是采取這樣的線程分發(fā)的梨树,不涉及線程切換,通常是四種模式開銷最小的一個岖寞。對于簡單任務(wù)來說這是推薦用法抡四,但使用這個分發(fā)模型要小心不要在主線程執(zhí)行耗時長的任務(wù),避免阻塞主線程仗谆。
- MainThread 訂閱者將會被回調(diào)在Android的Main線程中指巡,適用于更新UI而又不無法確定事件來源于哪個線程的情況。
- BackgroundThread 訂閱者將在后臺線程被回調(diào)隶垮,如果發(fā)布線程本身不是主線程藻雪,那么行為就跟PostThread一致,如果是在主線程發(fā)布事件狸吞,會切換到后臺線程執(zhí)行勉耀。
- Async 訂閱者總是在一個單獨的線程被回調(diào)。
訂閱優(yōu)先級
你可以在注冊訂閱者的時候設(shè)置優(yōu)先級改變事件分發(fā)的順序蹋偏,按優(yōu)先級從高到低分發(fā)事件回調(diào)便斥。
取消事件分發(fā)
你可以在接收事件,拿到數(shù)據(jù)value之后中斷之后的事件分發(fā):
AgeraBus.getDefault().cancel(value);
value
是從Supplier拿到的事件的數(shù)據(jù)威始,在update中調(diào)用上面的取消分發(fā)枢纠,后續(xù)的訂閱者將不會接收到此次事件。
粘性事件
Agera 的 push event, pull data模型天然就是支持粘性事件黎棠,它總會保存最近(最新)的值晋渺,這樣訂閱粘性事件總是可以拿到最近(如果有)的數(shù)據(jù)镰绎。
使用方法
要使用上面這些高級功能,我們用AgeraBus另外一個接口方法訂閱事件:
AgeraBus.getDefault()
.compiler(User.class)//設(shè)置訂閱事件的類型
.priority(priority)//設(shè)置優(yōu)先級木西,或者調(diào)用.noPriority()不設(shè)置優(yōu)先級(即為默認0優(yōu)先級)
.sticky()//設(shè)置為接收粘性事件畴栖,或者調(diào)用.noSticky()設(shè)置為不接收粘性事件(默認不接收粘性事件)
.background()//設(shè)置分發(fā)線程,有background(),main(),posting(),async()對應(yīng)四個分發(fā)模式(默認為posting模式)
.compile(updatable);//設(shè)置訂閱者八千,完成訂閱
訂閱事件不要中斷鏈式調(diào)用驶臊,最后一定要調(diào)用compile(Updatable)完成調(diào)用
基本用法中的:
AgeraBus.getDefault()
.addUpdatable(this,User.class);
就是全部設(shè)置了默認的方式(0優(yōu)先級,不接收粘性事件叼丑,posting線程分發(fā))关翎。
注意
在不同線程分發(fā)時候拿到的數(shù)據(jù),不一定是引發(fā)這次事件的數(shù)據(jù)鸠信,拿到的數(shù)據(jù)有可能要比引發(fā)事件的數(shù)據(jù)要新纵寝,在Agera Wiki 中文版中有說到,這是因為:
由于 push event, pull data 模型和多線程情況下星立,觀察者可能看不到數(shù)據(jù)全部的更新記錄爽茴。 這是特意設(shè)計的: 因為大多數(shù)情況下(尤其更新app UI), 本來就只需要關(guān)心最新的數(shù)據(jù)。
上面的使用方法可以參考我的這個項目地址 AgeraBus,里面有使用Demo绰垂∈易啵可以看下AgeraBus的具體實現(xiàn),由于本人技術(shù)水平有限劲装,如有Bug胧沫,歡迎討論。