最簡單有效的Android元件化方案 之 元件化需要考慮的幾個問題
最簡單有效的Android元件化方案,github開源地址 ofollow,noindex">https://github.com/beyondxia/modules
上一篇文章,我們討論了目前傳統的解耦方案和通訊機制。其實解耦只是我們實施元件化的第一步,要做到真正的元件化,還需要針對業務模組做程式碼的獨立分倉,lib話(aar化),模組能夠以aar庫的形式整合到主APP,進一步提供模組的獨立性,甚至可以及其方便的進行元件的安裝和解除安裝。
- 如何確保模組之間絕對的解耦完成
- 如何進行程式碼的分倉,中間可能會涉及到哪些問題
- 如何極簡的做到模組的接入和下線需求。
我們先從第二個問題開始討論,就是【如何進行程式碼的分倉,中間可能會涉及到哪些問題】。
在我所開發的幾個大型專案當中,涉及到元件化的需求,都是在專案有小到大發展到一定程度,業務模組越來越多,開發人員數量達到一定數量時,才開始對專案進行元件化的規劃。這就意味著,專案剛開始時,我們所有的模組都是在一個程式碼倉內進行開發的,開發人員也都是在一起開發,模組界限不是很明確。這種情況下,我們再對模組進行元件化拆分,會涉及哪些問題呢:
- 比如A模組希望獲取B模組的model資料、自定義view、fragment等,但是這些結構的定義是在B中定義的,A中無法找到定義;
- 再比如幾個模組需要共享一些資源 檔案(如圖片,layout,value等)等,我們不可能把相同的資源每個模組中都保留一份。
我們知道,模組功能暴露以介面方式暴露,介面是需要放中間服務層的,如下圖:

image.png
針對上面的問題,我們也可以和服務介面一樣,把相應的共享資料放在服務層。只不過共享的資原始檔,我們建議以獨立的module庫放在服務層,各個業務模組根據需求可以選擇是否依賴該module庫。
接下來,我們再來討論第一個問題【何確保模組之間絕對的解耦完成】這兒又分為兩種情況:
- 如何保證子模組之間沒有任何依賴
- 如何保證主app對子模組是沒有依賴的。
對於第一個問題,只要子模組的依賴依賴列表(gradle- dependencies)中沒有對其他模組的依賴,就可以絕對保證本模組和其他模組之間是絕對解耦的。
第二個問題,如何保證主APP對子模組沒有絕對的依賴呢,我們知道,主APP如果希望整合子模組,就必須依賴子模組。我們可以使用新版gradle外掛依賴選項runtimeOnly,只在執行時可以使用,編譯時依賴直接報錯。
通過這種方式,可以保證各個模組和主App之間達到絕對的解耦。
下面我們接著討論第三個問題【如何極簡的做到模組的接入和下線需求】:
對一個新的業務模組,我們要能夠一個極簡的方式接入我們的主APP,這很重要,這決定這業務方的接入成本和接入意願。這就要求我們的框架(特別是解耦框架)能夠在極小的程式碼改動量的情況下,能夠快速接入主APP,這部分內容,我們會在後續的文章中詳細說明: 最簡單有效的Android元件化方案 之 傳統元件化方案的問題
那如果我們希望在某些特定的場景或版本中,下線某些業務模組,那該怎麼辦呢?這裡我們需要考慮兩個問題:
- 程式碼打包中,可以選擇性的打包某些業務模組
- 下線後,對於正常的模組間的呼叫,app的穩定性要能得到保證,不能因為呼叫了一個不存在的模組而導致APP編譯不通過或應用執行crash。針對問題1,很好解決,主APP中選擇性的依賴某些模組即可。第二個問題,就對我們的框架有一定的要求了,我們的解耦,匯流排,路由框架要能夠有一定的異常處理機制,比如:對於某些可能要下線的模組,其他模組在呼叫的之後,框架可以丟擲一個模組不存在的異常,呼叫方必須捕獲該異常。
服務提供:
public abstract class LoginService extends PAService implements ILogin { public static ILogin get() throws NoServiceException { return getService(SERVICE_NAME); } }
呼叫方:
String username = null; try { username = LoginService.get().getUserName(); } catch (NoServiceException e) { e.printStackTrace(); }