項目組件化實踐

一、項目演進

混沌項目 -> 模塊化 -> 組件化

  • 混沌項目:所有代碼在一個主工程中,僅僅做了分包。
  • 模塊化:項目按業(yè)務拆分多個module,但是各module之間耦合嚴重。
  • 組件化:對模塊化的module進一步分層,根據分層確定依賴規(guī)則,優(yōu)化模塊化混亂耦合的局面,使各模塊間相對獨立。

二、組件化描述

2.1 組件形式:
  • module 工程模塊
  • project 獨立項目
2.2 分層:
  • business 具體業(yè)務
  • sdk 通用業(yè)務能力
  • lib 通用庫能力
  • base 基礎庫能力

視業(yè)務復雜度看是否在business和sdk之間抽個loft層,作為通用業(yè)務封裝和通信輔助層。

2.3 組件化優(yōu)勢:
  • 模塊獨立:提升編譯速度、提高開發(fā)效率、降低維護成本、提升測試效率。
  • 拓展性好:方便組件的新增和刪除,也為項目內部組件的插件化提供環(huán)境。
2.4 組件化要解決的問題:
  • 獨立調試
  • 解耦
  • 解耦之后組件間的跳轉與通信

三、組件化實踐

結合自己的工作,來簡單整理下項目組件化實踐。

3.1 獨立調試

獨立project肯定不需要考慮調試問題,這里主要是指module的組件形式。需要獨立編譯的module:gradle中 apply plugin: ‘com.android.library’ 改為apply plugin: ‘com.android.application',另外需要配置一個能啟動系統(tǒng)組件的AndroidMainfest.xml。為了方便修改,可以在gradle.properties配置開關來切換調試模式。

示例:
動態(tài)配置組件類型、ApplicationId和AndroidManifest

//gradle.properties 配置統(tǒng)一調試開關
isModule = false
//build.gradle
if (isModule.toBoolean()){
    apply plugin: 'com.android.application'
}else {
    apply plugin: 'com.android.library'
}
//build.gradle (XX module)
android {
...
    defaultConfig {
...
        if (isModule.toBoolean()) {
            // 獨立調試時添加 applicationId ,集成調試時移除
            applicationId "包名"
        }
...
    }
    sourceSets {
        main {
            // 獨立調試與集成調試時使用不同的 AndroidManifest.xml 文件
            if (isModule.toBoolean()) {
                manifest.srcFile 'src/main/moduleManifest/AndroidManifest.xml'
            } else {
                manifest.srcFile 'src/main/AndroidManifest.xml'
            }
        }
    }
...
}
3.2 解耦

解耦主要就是組件分層,上級可以依賴下級但不跨級依賴,平級之間不互相依賴, 通用功能需要提取則在兩層之間抽取loft層,一般來說business可能會抽取通用業(yè)務組件作為loft。

基礎組件分層改造

1)基礎能力庫
主要提供整個項目通用的工具、Base頁面等等,它自身無任何依賴,因此放在base層。通用型sdk和lib不依賴于Base-Core,方便托管maven成為獨立庫。

2)網絡庫(Okhttp)
多個終端項目,下沉一個通用的Base-Network,滿足基礎網絡請求能力,包括:通用請求配置設置、通用請求參數封裝、通用響應數據解析等的支持。Lib層梳理出差異化的Lib-Network,主要包括通用業(yè)務請求類型封裝、網絡請求加密策略(不同終端有差異因此放到lib層)等。Base-Network自身可以托管maven。

3)圖片庫(Glide)、插件化庫(RePlugin)、熱修復庫(Tinker)
這仨算一個類型,放一塊說。Glide自身默認使用HttpURLConnection作為網絡獲取圖片方案,這里直接可以使用Base-Network來統(tǒng)一提供網絡請求能力。而插件化庫、熱修復庫這兩個框架因為都需要下發(fā)插件,所以也可以統(tǒng)一依賴Base-Network。真實場景是:圖片庫、插件化庫、熱修復庫都會作為maven托管,提供終端通用能力,如果各自維護一套網絡請求方案顯然還是不合理。

4)播放框架
播放框架做了一次大的重構,將之前冗雜的播控功能進行組件化拆分:

  • Lib-CorePlayer:支持播放的系統(tǒng)庫和三方庫。向上統(tǒng)一提供基礎播放能力。
  • Sdk-PlayerFramework: 播控中心,封裝view的基礎控制功能以及封裝player的基礎播放功能
  • Loft-Live 、Loft-Vod:分別封裝直播和點播兩大通用業(yè)務。分別實現對應的播控,以及個性化能力。因為是通用型業(yè)務,因此這里增加了個Loft層,理解為common business。
3.3 跳轉

通過組件分層與依賴限制最大程度已經實現了組件解耦,那接下的問題是,不相互依賴的組件間如何進行跳轉和通信 ?
1)Intent隱式跳轉

  • action跳轉
<intent-filter>
   <action android:name=“XXX" />
   <category android:name="android.intent.category.DEFAULT" />
</intent-filter>

intent.setAction(action);
startActivity(intent);
  • uri跳轉
<intent-filter>
   <action android:name=“XXX" />
   <category android:name="android.intent.category.DEFAULT" />
   <data
       android:host="channel"
       android:path="/channel_page"
       android:scheme=“XXX"></data>
</intent-filter>

intent.setData(Uri.parse(scheme + "://" + host + path));
startActivity(intent);

2)路由 Arouter

3.4 通信

如果組件化分層足夠合理的話,需要互相通信的組件大部分都處于上面的業(yè)務層,通信方式:或通過Loft層建立依賴關系來注冊觀察者,或實在不行就發(fā)本地廣播。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

友情鏈接更多精彩內容