最近在做SDK的升級(jí),因?yàn)槭窃诶习姹旧侠种нM(jìn)行了很多定制的改動(dòng),而且同時(shí)在維護(hù)多條業(yè)務(wù)線不同的定制需求,現(xiàn)在多條業(yè)務(wù)線需要跨多個(gè)版本升級(jí),拉分支的這種方式凸顯了他的不友好。
前期為了讓SDK里各自的部分方便開發(fā)和使用,內(nèi)部進(jìn)行了細(xì)粒度的拆分,將項(xiàng)目拆分成多個(gè)倉庫,使用 repo 組織完整的項(xiàng)目。
然后整體項(xiàng)目使用 fat-aar 打包成一個(gè)完整aar的解決方案。
注意:包含多個(gè)module,module中存在lib庫的時(shí)候,防止aar打包丟失lib庫,可以每個(gè)module都添加fat-aar配置,并添加embed
各條業(yè)務(wù)線的需求在必須定制修改使用SDK的時(shí)候,采用了輕量級(jí)Android AOP框架 Lancet 進(jìn)行定制開發(fā)。
在SDK的基礎(chǔ)上,除了定制的改動(dòng),還有各自業(yè)務(wù)線的獨(dú)立需求增加,最終混淆處理后,也打fat-aar完整包提供業(yè)務(wù)SDK。
注意:因?yàn)閒at-aar是通過復(fù)制各module編譯后的資源合并的,所以混淆規(guī)則需寫到主module中
整個(gè)過程,因SDK細(xì)粒度的拆分在前,定制內(nèi)容梳理在后,而且是跨越多個(gè)版本,升級(jí)變的很麻煩,需要一條條對(duì)比,確認(rèn)哪些是可以合入SDK的,哪些是需要業(yè)務(wù)線自己通過lancet修改的,哪些是業(yè)務(wù)新增的獨(dú)立部分。
SPI機(jī)制
在SDK里一些數(shù)據(jù)處理的組件使用的是Java中的SPI機(jī)制。
整體機(jī)制圖如下:

Java SPI 實(shí)際上是“基于接口的編程+策略模式+配置文件”組合實(shí)現(xiàn)的動(dòng)態(tài)加載機(jī)制。
該機(jī)制需要指定在 /META-INF/文件夾 目錄,包含所有接口命名的文件,內(nèi)容是要應(yīng)用的實(shí)現(xiàn)類。然后通過使用 ServiceLoader 來加載配置文件中指定的實(shí)現(xiàn)。
注解處理器
這個(gè)過程我們使用了注解處理器,不再手動(dòng)去維護(hù)配置。
編譯過程:

- 將源文件解析為抽象語法樹
- 調(diào)用已注冊(cè)的注解處理器 - 如果該過程生成了新的源文件,編譯器將重復(fù)第1、2步 - 每次重復(fù)成為一輪 - 第一輪解析處理的是輸入至編譯器中的已有源文件 - 當(dāng)注解處理器不再生成新的源文件,將進(jìn)入最后一輪
- 生成字節(jié)碼
這里相對(duì)于 ARouter 的APT使用,我們沒有通過 JavaPoet 生成新的Java文件。
同樣類似ARouter的還有 ButterKnife 的使用。
相對(duì)于AutoRegister,它是通過Gradle Transform API基于字節(jié)碼插樁,在Android中實(shí)現(xiàn)跨module自動(dòng)注冊(cè)功能。
Transform的執(zhí)行流程圖:

更多細(xì)節(jié)注意項(xiàng)和藍(lán)色文檔,后續(xù)整理補(bǔ)充……
參考文檔: