前言
大家好羊精,我是小彭。2 年前浪蹂,我們在 為了組件化改造學習十幾家大廠的技術博客 這篇文章里收集過各大廠的組件化方案吼拥。其中蕾管,有美團收銀團隊分享的組件化總線框架 modular-event
讓我們印象深刻。然而啡氢,美團并未將該框架開源状囱,我們只能望梅止渴。
在學習和借鑒美團 modular-event
方案中很多優(yōu)秀的設計思想后倘是,我亦發(fā)現(xiàn)方案中依然存在不一致風險和不足亭枷,故我決定對方案進行改進并向社區(qū)開源。項目主頁為 Github · ModularEventBus搀崭,演示 Demo 可直接下載:
Demo apk叨粘。
歡迎提 Issue 幫助修復缺陷,歡迎提 Pull Request 增加新的 Feature,有用請點贊給 Star升敲,給小彭一點創(chuàng)作的動力答倡,謝謝。
這篇文章是 組件化系列文章第 5 篇驴党,相關 Android 工程化專欄完整文章列表:
一瘪撇、Gradle 基礎:
- 1、Gradle 基礎 :Wrapper鼻弧、Groovy设江、生命周期、Project攘轩、Task叉存、增量
- 2、Gradle 插件:Plugin度帮、Extension 擴展歼捏、NamedDomainObjectContainer、調(diào)試
- 3笨篷、Gradle 依賴管理
- 4瞳秽、Maven 發(fā)布:SHAPSHOT 快照、uploadArchives率翅、Nexus练俐、AAR
- 5、Gradle 插件案例:EasyPrivacy冕臭、so 文件適配 64 位架構腺晾、ABI
二、AGP 插件:
- 1辜贵、AGP 構建過程
- 2悯蝉、AGP 常用配置項:Manifest、BuildConfig托慨、buildTypes鼻由、殼工程、環(huán)境切換
- 3厚棵、APG Transform:AOP蕉世、TransformTask、增量婆硬、字節(jié)碼讨彼、Dex
- 4、AGP 代碼混淆:ProGuard柿祈、R8哈误、Optimize哩至、Keep、組件化
- 5蜜自、APK 簽名:認證菩貌、完整性、v1重荠、v2箭阶、v3、Zip戈鲁、Wallet
- 6仇参、AGP 案例:多渠道打包
三、組件化開發(fā):
- 1婆殿、方案積累:有贊诈乒、蘑菇街、得到婆芦、攜程怕磨、支付寶翅阵、手淘紧帕、愛奇藝导披、微信兆览、美團
- 2、組件化架構基礎
- 3溺拱、ARouter 源碼分析
- 4讯嫂、組件化案例:通用方案
- 5谬盐、組件化案例:組件化事件總線框架(本文)
- 6氯材、組件化案例:組件化 Key-Value 框架
四渣锦、AOP 面向切面編程:
- 1、AOP 基礎
- 2浓体、Java 注解
- 3泡挺、Java 注解處理器:APT辈讶、javac
- 4命浴、Java 動態(tài)代理:代理模式、Proxy贱除、字節(jié)碼
- 5生闲、Java ServiceLoader:服務發(fā)現(xiàn)、SPI月幌、META-INF
- 6碍讯、AspectJ 框架:Transform
- 7、Javassist 框架
- 8扯躺、ASM 框架
- 9捉兴、AspectJ 案例:限制按鈕點擊抖動
五蝎困、相關計算機基礎
1. 認識事件總線
1.1 事件總線的優(yōu)點
事件總線框架最大的優(yōu)點是 ”解耦“伍派,即事件發(fā)布者與事件訂閱者的解耦,事件的發(fā)布者不需要關心是否有人訂閱該事件剩胁,也不需要關心是誰訂閱該事件诉植,代碼耦合度較低。因此摧冀,事件總線框架更適合作為全局的事件通信方案倍踪,或者組件間通信的輔助方案。
1.2 事件總線的缺點
然而索昂,成也蕭何敗蕭何建车。有人覺得事件總線好用,亦有人覺得事件總線不好用椒惨,歸根結底還是因為事件總線太容易被濫用了缤至,用時一時爽,維護火葬場康谆。我將事件總線框架存在的問題概括為以下 5 種常見問題:
1领斥、消息難溯源: 在閱讀源碼的過程中,如果需要查找發(fā)布事件或訂閱事件的地方沃暗,只能通過查找事件引用的方式進行溯源月洛,增大了理解代碼邏輯的難度。特別是當項目中到處是臨時事件時孽锥,難度會大大增加嚼黔;
2、臨時事件濫用: 由于框架對事件定義沒有強制約束惜辑,開發(fā)者可以隨意地在項目的各個角落定義事件唬涧。導致整個項目都是臨時事件飛來飛去,增大后期維護的難度盛撑;
3碎节、數(shù)據(jù)類型轉換錯誤: LiveDataBus 等事件總線框架需要開發(fā)者手動輸入事件數(shù)據(jù)類型,當訂閱方與發(fā)送方使用不同的數(shù)據(jù)類型時抵卫,會發(fā)生類型轉換錯誤狮荔。在發(fā)生事件命名沖突時胎撇,出錯的概率會大大增加,存在隱患殖氏;
4创坞、事件命名重復: 由于框架對事件命名沒有強制約束,不同組件有可能定義重名的事件受葛,產(chǎn)生邏輯錯誤题涨。如果重名的事件還使用了不同的數(shù)據(jù)類型,還會出現(xiàn)類型轉換錯誤总滩,存在隱患纲堵;
5、事件命名疏忽: 與 ”事件命名重復“ 類似闰渔,由于框架對事件命名沒有檢查席函,有可能出現(xiàn)開發(fā)者復制粘貼后忘記修改事件變量值的問題,或者變量值拼寫錯誤(例如
login_success
拼寫為login_succese
)冈涧,那么訂閱方將永遠收不到事件茂附。
1.3 ModularEventBus 的解決方案
ModularEventBus 組件化事件總線框架的優(yōu)點是: 在保持發(fā)布者與訂閱者的解耦的優(yōu)勢下,解決上述事件總線框架中存在的通病督弓。 具體通過以下 5 個手段實現(xiàn):
1营曼、事件聲明聚合: 發(fā)布者和訂閱者只能使用預定義的事件,嚴格禁止使用臨時事件愚隧,事件需要按照約定聚合定義在一個文件中(解決臨時事件濫用問題)蒂阱;
2、區(qū)分不同組件的同名事件: 在定義事件時需要指定事件所屬
moduleName
狂塘,框架自動使用"[moduleName]$$[eventName]"
作為最終的事件名(解決事件命名重復問題)录煤;3、事件數(shù)據(jù)類型聲明: 在定義事件時需要指定事件的數(shù)據(jù)類型荞胡,框架自動使用該數(shù)據(jù)類型發(fā)送和訂閱事件(解決數(shù)據(jù)類型轉換錯誤問題)妈踊;
4、接口強約束: 運行時使用事件類發(fā)布和訂閱事件泪漂,框架自動使用事件定義的事件名和數(shù)據(jù)類型廊营,而不需要手動輸入事件名和數(shù)據(jù)類型(解決事件命名命名錯誤);
5窖梁、APT 生成接口類: 框架在編譯時使用 APT 注解處理器自動生成事件接口類赘风。
1.4 與美團 modular-event 對比有哪些什么不同夹囚?
-
modular-event 使用靜態(tài)常量定義事件纵刘,為什么 ModularEventBus 用接口定義事件?
美團 modular-event 使用常量引入了重復信息荸哟,存在不一致風險假哎。例如開發(fā)者復制一行常量后瞬捕,只修改常量名但忘記修改值,這種錯誤往往很難被發(fā)現(xiàn)舵抹。而 ModularEventBus 使用方法名作為事件名肪虎,方法返回值作為事件數(shù)據(jù)類型,不會引入重復信息且更加簡潔惧蛹。
-
modular-event 使用動態(tài)代理扇救,為什么 ModularEventBus 不需要?
美團 modular-event 使用動態(tài)代理 API 統(tǒng)一接管了事件的發(fā)布和訂閱香嗓,但考慮到這部分代理邏輯非常簡單(獲取事件名并交給 LiveDataBus 完成后續(xù)的發(fā)布和訂閱邏輯)迅腔,且框架本身已經(jīng)引入了編譯時 APT 技術,完全可以在編譯時生成這部分代理邏輯靠娱,沒必要使用動態(tài)代理 API沧烈。
-
更多特性支持:
此外 ModularEventBus 還支持生成事件文檔、空數(shù)據(jù)攔截像云、泛型事件锌雀、自動清除空閑事件等特性。
2. ModularEventBus 能做什么迅诬?
ModularEventBus 是一款幫助 Android App 解決事件總線濫用問題的框架腋逆,亦可作為組件化基礎設施。 其解決方案是通過注解定義事件侈贷,由編譯時 APT 注解處理器進行合法性檢查和自動生成事件接口闲礼,以實現(xiàn)對事件定義、發(fā)布和訂閱的強約束铐维。
2.1 常見事件總線框架對比
以下從多個維度對比常見的事件總線框架( ? 良好支持柬泽、?? 支持、? 不支持):
事件總線 | ModularEventBus | modular-event | SmartEventBus | LiveEventBus | LiveDataBus | EventBus | RxBus |
---|---|---|---|---|---|---|---|
開發(fā)者 | @彭旭銳 | @美團 | @JeremyLiao | @JeremyLiao | / | @greenrobot | / |
Github Star | 0 | 未開源 | 146 | 3.4k | / | 24.1k | / |
生成事件文檔 | ? | ? | ? | ? | ? | ? | ? |
空數(shù)據(jù)攔截 | ? | ? | ? | ? | ? | ? | ? |
無數(shù)據(jù)事件 | ?? | ? | ? | ? | ? | ? | ? |
泛型事件 | ? | ? | ?? | ?? | ? | ? | ? |
自動清除空閑事件 | ? | ? | ? | ? | ? | ? | ? |
事件強約束 | ? | ?? | ?? | ? | ? | ? | ? |
生命周期感知 | ? | ? | ? | ? | ? | ? | ? |
延遲發(fā)送事件 | ? | ? | ? | ? | ? | ? | ? |
有序接收事件 | ? | ? | ? | ? | ? | ? | ? |
訂閱 Sticky 事件 | ? | ? | ? | ? | ? | ? | ? |
清除 Sticky 事件 | ? | ? | ? | ? | ? | ? | ? |
移除事件 | ? | ? | ? | ? | ? | ? | ? |
線程調(diào)度 | ? | ? | ? | ? | ? | ? | ? |
跨進程 / 跨 App | ?(可支持) | ? | ? | ? | ? | ? | ? |
關鍵原理 | APT+靜態(tài)代理 | APT+動態(tài)代理 | APT+靜態(tài)代理 | LiveData | LiveData | APT | RxJava |
2.2 ModularEventBus 特性一覽
1嫁蛇、事件強約束
? 支持零配置快速使用锨并;
? 支持 APT 注解處理器自動生成事件接口類;
? 支持編譯時合法性校驗和警告提示睬棚;
? 支持生成事件文檔第煮;
? 支持增量編譯;
2抑党、Lifecycle 生命周期感知
? 內(nèi)置基于 LiveData
的 LiveDataBus包警;
? 支持自動取消訂閱,避免內(nèi)存泄漏底靠;
? 支持安全地發(fā)送事件與接收事件害晦,避免產(chǎn)生空指針異常或不必要的性能損耗暑中;
? 支持永久訂閱事件壹瘟;
? 支持自動清除沒有關聯(lián)訂閱者的空閑 LiveData
以釋放內(nèi)存鲫剿;
3、更多特性支持
? 支持 Java / Kotlin稻轨;
? 支持 AndroidX灵莲;
? 支持訂閱 Sticky 粘性事件,支持移除事件殴俱;
? 支持 Generic 泛型事件政冻,如 List<String>
事件;
? 支持攔截空數(shù)據(jù)线欲;
? 支持只發(fā)布事件不攜帶數(shù)據(jù)的無數(shù)據(jù)事件赠幕;
? 支持延遲發(fā)送事件;
? 支持有序接收事件询筏。
3. ModularEventBus 快速使用
- 1榕堰、添加依賴
模塊級 build.gradle
plugins {
id 'com.android.application' // 或 id 'com.android.library'
id 'org.jetbrains.kotlin.android'
id 'kotlin-kapt'
}
dependencies {
// 替換成最新版本
implementation 'io.github.pengxurui:modular-eventbus-api:1.0.4'
kapt 'io.github.pengxurui:modular-eventbus-compiler:1.0.4'
...
}
- 2、定義事件數(shù)據(jù)類型(可選): 定義事件關聯(lián)的數(shù)據(jù)類型嫌套,對于只發(fā)布事件而不需要攜帶數(shù)據(jù)的場景逆屡,可以不定義事件類型。
UserInfo.kt
data class UserInfo(val userName: String)
-
3踱讨、定義事件: 使用接口定義事件名和事件數(shù)據(jù)類型魏蔗,并使用
@EventGroup
注解修飾該接口:
LoginEvents.kt
@EventGroup
interface LoginEvents {
// 事件名:login
// 事件數(shù)據(jù)類型:UserInfo
fun login(): UserInfo
// 事件名:logout
fun logout()
}
-
4、執(zhí)行注解處理器: 執(zhí)行
Make Project
或Rebuild Project
等多種方式都可以觸發(fā)注解處理器痹筛,處理器將根據(jù)事件定義自動生成相應的事件接口莺治。例如,LoginEvents
對應的事件類為:
EventDefineOfLoginEvents.java
/**
* Auto generate code, do not modify!!!
* @see com.pengxr.sampleloginlib.events.LoginEvents
*/
@SuppressWarnings("unchecked")
public class EventDefineOfLoginEvents implements IEventGroup {
private EventDefineOfLoginEvents() {
}
public static IEvent<UserInfo> login() {
return (IEvent<UserInfo>) (ModularEventBus.INSTANCE.createObservable("com.pengxr.sampleloginlib.events.LoginEvents$$login", UserInfo.class, false, true));
}
public static IEvent<Void> logout() {
return (IEvent<Void>) (ModularEventBus.INSTANCE.createObservable("com.pengxr.sampleloginlib.events.LoginEvents$$logout", Void.class, true, false));
}
}
-
5帚稠、訂閱事件: 使用
EventDefineOfLoginEvents
事件類提供的靜態(tài)方法訂閱事件:
訂閱者示例
// 以生命周期感知模式訂閱事件(不需要手動注銷訂閱)
EventDefineOfLoginEvents.login().observe(this) { value: UserInfo? ->
// Do something.
}
// 以永久模式訂閱事件(需要手動注銷訂閱)
EventDefineOfLoginEvents.logout().observeForever { _: Void? ->
// Do something.
}
-
6谣旁、發(fā)布事件: 使用
EventDefineOfLoginEvents
提供的靜態(tài)方法發(fā)布事件:
發(fā)布者示例
EventDefineOfLoginEvents.login().post(UserInfo("XIAOPENG"))
EventDefineOfLoginEvents.logout().post(null)
- 7、添加混淆規(guī)則(如果使用了 minifyEnabled true):
-dontwarn com.pengxr.modular.eventbus.generated.**
-keep class com.pengxr.modular.eventbus.generated.** { *; }
-keep @com.pengxr.modular.eventbus.facade.annotation.EventGroup class * {*;} # 可選
4. 完整使用文檔
4.1 定義事件
-
使用注解定義事件:
@EventGroup
注解:@EventGroup
注解用于定義事件組滋早,修飾于 interface 接口上榄审,在該類中定義的每個方法均視為一個事件定義;@Event
注解:@Event
注解用于事件組中的事件定義杆麸,亦可省略搁进。
模板程序如下:
com.pengxr.sample.events.MainEvents.kt
// 事件組
@EventGroup
interface MainEvents {
// 事件
// @Event 可以省略
@Event
fun open(): String
}
提示: 以上即定義了一個
MainEvents
事件組,其中包含一個com.pengxr.sample.events.MainEvents$$open
事件且數(shù)據(jù)類型為String
類型昔头。
亦兼容將 @EventGroup
修飾于 class 類而非 interface 接口饼问,但會有編譯時警告: Annotated @EventGroup on a class type [IllegalEvent], expected a interface. Is that really what you want?
錯誤示例
@EventGroup
class IllegalEvent {
fun illegalEvent() {
}
}
-
使用
@Ignore
注解忽略定義: 使用@Ignore
注解可以排除事件類或事件方法揭斧,使其不被視為事件定義莱革。
示例程序
// 可以修飾于事件組
@Ignore
@EventGroup
interface IgnoreEvent {
// 亦可修飾于事件
@Ignore
fun ignoredMethod()
fun method()
}
-
使用
@Deprecated
注解提示過時: 使用@Deprecated
注解可以標記事件為過時。與@Ignore
不同是,@Deprecated
修飾的類或方法依然是有效的事件定義驮吱。
示例程序
// 雖然過時,但依然是有效的事件定義
@Deprecated("Don't use it.")
@EventGroup
interface DeprecatedEvent {
@Deprecated("Don't use it.")
fun deprecatedMethod()
}
-
定義事件數(shù)據(jù)類型: 事件方法返回值即表示事件數(shù)據(jù)類型萧吠,支持泛型(如
List<String>
)左冬,支持不攜帶數(shù)據(jù)的無數(shù)據(jù)事件。以下均為合法定義:
Java 示例程序
// 事件數(shù)據(jù)類型為 String
String stringEventInJava();
// 事件數(shù)據(jù)類型為 List<String>
List<String> listEventInJava();
// 以下均視為無數(shù)據(jù)事件
void voidEventInJava1();
Void voidEventInJava2();
Kotlin 示例程序
// 事件數(shù)據(jù)類型為 String
fun stringEventInKotlin(): String
// 事件數(shù)據(jù)類型為 List<String>
fun listEventInKotlin(): List<String>
// 以下均視為無數(shù)據(jù)事件
fun voidEventInKotlin1()
fun voidEventInKotlin2(): Unit
fun voidEventInKotlin3(): Unit?
-
定義事件數(shù)據(jù)可空性: 使用
@Nullable
或@NonNull
注解表示事件數(shù)據(jù)可空性纸型,默認為可空類型拇砰。以下均為合法定義:
Java 示例程序
@NonNull
String nonNullEventInJava();
@Nullable
String nullableEventInJava();
// 默認視為 @Nullable
String eventInJava();
Kotlin 示例程序
fun nonNullEventInKotlin(): String
// 提示:Kotlin 編譯器將返回類型上的 ? 號視為 @org.jetbrains.annotations.Nullable
fun nullableEventInKotlin(): String?
以下為支持的可空性注解:
org.jetbrains.annotations.Nullable
android.annotation.Nullable
androidx.annotation.Nullable
org.jetbrains.annotations.NotNull
android.annotation.NonNull
androidx.annotation.NonNull
-
定義自動清除事件: 支持配置在事件沒有關聯(lián)的訂閱者時自動被清除(以釋放內(nèi)存),默認值為 false狰腌〕疲可以使用
@EventGroup
注解或@Event
注解進行修改,以@Event
的取值優(yōu)先琼腔。
示例程序
@EventGroup(autoClear = true)
interface MainEvents {
@Event(autoClear = false)
fun normalEvent(): String
// 繼承 @EventGroup 中的 autoClear 取值
fun autoClearEvent(): String
}
-
定義事件所屬組件名: 為避免不同組件中的事件名重復瑰枫,框架自動使用
"[moduleName]$$[eventName]"
作為最終的事件名。默認使用事件組的[全限定類名]
作為moduleName
丹莲,可以使用@EventGroup
注解進行修改光坝。
示例程序
com.pengxr.sample.events.MainEvents.kt
@EventGroup(moduleName = "main")
interface MainEvents {
fun open(): String
}
提示: 以上即定義了一個
MainEvents
事件組,其中包含一個main$$open
事件且數(shù)據(jù)類型為String
類型甥材。
4.2 執(zhí)行注解處理器
在完成事件定義后盯另,執(zhí)行 Make Project
或 Rebuild Project
等多種方式都可以觸發(fā)注解處理器,處理器將根據(jù)事件定義自動生成相應的事件接口洲赵。例如鸳惯, MainEvents
對應的事件接口為:
com.pengxr.modular.eventbus.generated.events.com.pengxr.sample.events.EventDefineOfMainEvents.java
/**
* Auto generate code, do not modify!!!
* @see com.pengxr.sample.events.MainEvents
*/
@SuppressWarnings("unchecked")
public class EventDefineOfMainEvents implements IEventGroup {
private EventDefineOfMainEvents() {
}
public static IEvent<String> open() {
return (IEvent<String>) (ModularEventBus.INSTANCE.createObservable("main$$open", String.class, false, false));
}
}
EventDefineOfMainEvents
中的靜態(tài)方法與 MainEvent
事件組中的每個事件一一對應,直接通過靜態(tài)方法即可獲取事件實例叠萍,而不再通過手動輸入事件名字符串或事件數(shù)據(jù)類型芝发,故可避免事件名錯誤或數(shù)據(jù)類型錯誤等問題。
所有的事件實例均是 IEvent
泛型接口的實現(xiàn)類苛谷,例如 open
事件屬于 IEvent<String>
類型的事件實例后德。發(fā)布事件和訂閱事件需要用到 IEvent
接口中定義的一系列 post 方法和 observe 方法,IEvent
接口的完整定義如下:
IEvent.kt
interface IEvent<T> {
/**
* 發(fā)布事件抄腔,允許在子線程發(fā)布
*/
@AnyThread
fun post(value: T?)
/**
* 延遲發(fā)布事件瓢湃,允許在子線程發(fā)布
*/
@AnyThread
fun postDelay(value: T?, delay: Long)
/**
* 延遲發(fā)布事件,在準備發(fā)布前會檢查 producer 處于活躍狀態(tài)赫蛇,允許在子線程發(fā)布
*
* @param producer 發(fā)布者的 LifecycleOwner
*/
@AnyThread
fun postDelay(value: T?, delay: Long, producer: LifecycleOwner)
/**
* 發(fā)布事件绵患,允許在子線程發(fā)布,確保訂閱者按照發(fā)布順序接收事件
*/
@AnyThread
fun postOrderly(value: T?)
/**
* 以生命周期感知模式訂閱事件(不需要手動注銷訂閱)
*/
@AnyThread
fun observe(consumer: LifecycleOwner, observer: Observer<T?>)
/**
* 以生命周期感知模式粘性訂閱事件(不需要手動注銷訂閱)
*/
@AnyThread
fun observeSticky(consumer: LifecycleOwner, observer: Observer<T?>)
/**
* 以永久模式訂閱事件(需要手動注銷訂閱)
*/
fun observeForever(observer: Observer<T?>)
/**
* 以永久模式粘性訂閱事件(需要手動注銷訂閱)
*
* @param observer Event observer.
*/
@AnyThread
fun observeStickyForever(observer: Observer<T?>)
/**
* 注銷訂閱者
*/
@AnyThread
fun removeObserver(observer: Observer<T?>)
/**
* 移除事件悟耘,關聯(lián)的訂閱者關系也會被解除
*/
@AnyThread
fun removeEvent()
}
4.3 訂閱事件
使用 IEvent
接口定義的一系列 observe()
接口訂閱事件落蝙,使用示例:
示例程序
// 以生命周期感知模式訂閱(不需要手動注銷訂閱)
EventDefineOfMainEvents.open().observe(this) {
// do something.
}
// 以生命周期感知模式、且粘性模式訂閱(不需要手動注銷訂閱)
EventDefineOfMainEvents.open().observeSticky(this) {
// do something.
}
val foreverObserver = Observer<String?> {
// do something.
}
// 以永久模式訂閱(需要手動注銷訂閱)
EventDefineOfMainEvents.open().observeForever(foreverObserver)
// 以永久模式,且粘性模式訂閱(需要手動注銷訂閱)
EventDefineOfMainEvents.open().observeStickyForever(foreverObserver)
// 移除觀察者
EventDefineOfMainEvents.open().removeObserver(foreverObserver)
4.4 發(fā)布事件
使用 IEvent
接口定義的一系列 post()
接口發(fā)布事件筏勒,使用示例:
示例程序
// 發(fā)布事件移迫,允許在子線程發(fā)布
EventDefineOfMainEvents.open().post("XIAO PENG")
// 延遲發(fā)布事件,允許在子線程發(fā)布
EventDefineOfMainEvents.open().postDelay("XIAO PENG", 5000)
// 延遲發(fā)布事件管行,在準備發(fā)布前會檢查 producer 處于活躍狀態(tài)厨埋,允許在子線程發(fā)布。
EventDefineOfMainEvents.open().postDelay("XIAO PENG", 5000, this)
// 發(fā)布事件捐顷,允許在子線程發(fā)布荡陷,確保訂閱者按照發(fā)布順序接收事件
EventDefineOfMainEvents.open().postOrderly("XIAO PENG")
// 移除事件
EventDefineOfMainEvents.open().removeEvent()
4.5 更多功能
- 生成事件文檔(可選): 支持生成事件文檔,需要在 Gradle 配置中開啟:
模塊級 build.gradle
// 需要生成事件文檔的模塊就增加配置:
android {
defaultConfig {
javaCompileOptions {
annotationProcessorOptions {
arguments = [
MODULAR_EVENTBUS_GENERATE_DOC: "enable",
MODULAR_EVENTBUS_MODULE_NAME : project.getName()
]
}
}
}
}
文檔生成路徑: build/generated/source/kapt/[buildType]/com/pengxr/modular/eventbus/generated/docs/eventgroup-of-[MODULAR_EVENTBUS_MODULE_NAME].json
-
配置(可選):
- debug(Boolean): 調(diào)試模式開關迅涮;
-
throwNullEventException(Boolean): 非空事件發(fā)布空數(shù)據(jù)時是否拋出
NullEventException
異常废赞,在release
模式默認為只攔截不拋出異常,在debug
模式默認為攔截且拋出異常叮姑; - setEventListener(IEventListener): 全局監(jiān)聽接口唉地。
示例程序
ModularEventBus.debug(true)
.throwNullEventException(true)
.setEventListener(object : IEventListener {
override fun <T> onEventPost(eventName: String, event: BaseEvent<T>, data: T?) {
Log.i(TAG, "onEventPost: $eventName, event = $event, data = $data")
}
})
5. 未來功能規(guī)劃
- 支持跨進程 / 跨 App:LiveEventBus 框架支持跨進程 / 跨 App,未來根據(jù)使用反饋考慮實現(xiàn)該 Feature传透;
- 支持替換內(nèi)部 EventBus 工廠:ModularEventBus 已預設計事件總線工廠
IEventFactory
渣蜗,未來根據(jù)使用反饋考慮公開該 API; - 支持基于 Kotlin Flow 的 IEventFactory 工廠旷祸;
- 編譯時檢查在不同
@EventGroup
中設置相同 modulaName 且相同eventName
耕拷,但事件數(shù)據(jù)類型不同的異常。
6. 共同成長
- 歡迎提 Issue 幫助修復缺陷托享;
- 歡迎提 Pull Request 增加新的 Feature骚烧,讓 ModularEventBus 變得更加強大,你的 ID 會出現(xiàn)在 Contributors 中闰围;
- 歡迎加 作者微信 與作者交流赃绊,歡迎加入交流群找到志同道合的伙伴
參考資料
- Android 消息總線的演進之路:用 LiveDataBus 替代 RxBus、EventBus —— 海亮(美團)著
- Android 組件化方案及組件消息總線 modular-event 實戰(zhàn) —— 海亮(美團)著