詳解Gradle自動實現Android組件化

前言;爲何咱們要用Gradle管理組件呢?

先來看看Android組件化須要實現的目標java

  1. 按照業務邏輯劃分模塊
  2. 項目模塊可以單獨啓動測試
  3. 可以根據需求引入或刪除某些業務模塊
  4. 經過不一樣模塊的組合,組成不一樣的App

對於第一點:須要根據技術架構和業務架構來劃分模塊,這裏須要根據實際狀況來考慮。咱們須要優化的是第2、3、四點。android

對於第二點:Android是經過應用com.android.application或com.android.library來決定該模塊是以App模式仍是以Library模式構建。App模式和Library模式的最大區別就是,App可以啓動,而Library不能夠。因此若是咱們的模塊能獨立啓動的話,咱們須要每次手動去改動模塊的build.gradle文件。好一點的作法定義一個布爾值來判斷是否處於debug模式,可是這裏有個問題是,不是每一個模塊都能獨立啓動的。因此不管採用何種方案,都須要咱們手動管理。git

對於第三點:當咱們開發好業務模塊後,可能咱們須要頻繁的新增或刪除某些業務模塊。若是是這樣的話,咱們也是須要頻繁手動修改App的build.gradle。github

對於第四點:有時候,咱們可能會在不一樣的App中引用相同的組件(例如:滴滴的普通版和企業版,普通版包含企業版的功能),這個時候,咱們也不但願要頻繁手動管理組件依賴,特別是在組件還能夠獨立運行的時候。面試

因此,在咱們實踐組件化的時候,最大的問題就是,咱們須要頻繁的手動build.gradle文件來管理組件應用的插件和App的依賴。數據庫

一.使用Gradle來管理組件

先安利下筆者寫的Gradle插件:Calces。若是以爲這個插件有用的話,能夠star下,若是你有更好的想法的話,能夠向我提交pull request。bash

廢話少說,一下是經過Calces快速實現Android組件化構建的流程。架構

Demo地址:SimpleCalcesapp

項目結構:框架

1.引入依賴庫
在Gradle 2.1及更高版本的插件構建腳本代碼:
在項目的build.gradle中

buildscript {
    ...
}
plugins {
  id "calces.modules" version "1.0.11"
}
複製代碼

在較舊版本的Gradle中或須要動態配置的狀況下的插件構建腳本代碼:

buildscript {
     repositories {
       maven {
         url "https://plugins.gradle.org/m2/"
       }
     }
     dependencies {
       classpath "gradle.plugin.com.tangpj.tools:calces:1.0.11"
     }
   }
   apply plugin: "calces.appConfig"

複製代碼

2.在項目build.gradle配置AppConfig

appConfig {
    debugEnable false

    apps {
        app{
            modules ':library1', ':library2'
        }
    }

    modules{
        library1{
            mainActivity ".Library1Activity"
            applicationId "com.tangpj.library1"
            isRunAlone true
        }
        library2{
            mainActivity ".Library2Activity"
            applicationId "com.tangpj.library2"
            isRunAlone true
        }
    }

}
複製代碼

3.在modules(子模塊)引入模塊自動化構建插件 (注意:不須要手動配置com.android.library或com.android.application)

apply plugin: 'calces.modules'
複製代碼

這樣咱們就完成了組件化的構建了,是的,咱們再也不須要再手動管理單個組件了與App的構建了,經過Calces,咱們能實現快速的組件化構建與多App同時構建。

那麼問題來了,咱們如何實現組件間的通訊呢?在簡單的項目中,推薦該Demo同樣,經過使用Android隱式Intent來實現組件間通訊。在中大型項目中,筆者推薦使用阿里的路由解決方案:ARouter。具體使用方法參考官方文檔就能夠了,使用方法十分簡單。

注意:在使用隱式Intent實現組件件通訊的時候須要注意找不到相應組件異常:java.lang.IllegalStateException: Could not execute method of the activity。致使這個異常的緣由是找不到目標組件致使的,因此在實際開發的時候,須要捕獲這一異常,而且根據項目實際狀況來進行實際的處理。使用ARouter框架則能經過設置降級策略來實現異常處理(查看ARouter文檔瞭解更多)。

若是隻是實現項目的簡單組件化,那麼看到這裏就能夠了,若是但願實現更加靈活的組件化架構的讀者能夠繼續看下去,下面筆者將全面分析組件化的優點與筆者總結的組件化構建思想。

二.組件化構建簡述

組件化構建與其說是一種技術,不如說是一種思想。組件化構建是經過對項目從新劃分紅一個個高內聚、低耦合的模塊來解決項目過於臃腫,代碼過於複雜的一種架構思想。

咱們經過對Google官方的架構演示Demo todo-mvp進行拆分來對Android組件化進行深刻的分析。

Demo地址:TodoCalces

todo系列app是Google android-architecture項目中爲了演示Android架構的最佳實現而編寫的一系列演示Demo。todo app的特色是,它足夠簡單,代碼量少,易於理解。可是又不會過於簡單,由於它是一個包含完成功能的App。它實現了任務列表、任務詳情、新建任務、編輯任務、統計任務的功能。

todo-mvp實現的功能:

  • 任務列表
  • 任務詳情
  • 新增/編輯任務
  • 統計任務

咱們將以todo-mvp的功能來劃分爲4個業務模塊,將底層劃分爲2個模塊,分別是superLib(提供mvp架構支持與其它的一些支持庫功能)與dataLib(數據支持模塊,Room提供底層數據庫支持功能)。對於大型項目還能夠加入resLib支持模塊,用來存放公共圖片資源、字符穿資源、樣式等。

架構劃分圖以下:

從架構圖能夠看出,全部的業務組件都依賴底層庫,而APP又依賴於業務組件,APP組件在這裏是做爲一個獨立組件存在的。在通常的組件化實踐中,都不包含APP這個組件的,APP組件的存在是有其意義的。

首先,咱們的組件化除了實現組件的獨立管理和動態配置APP所依賴的組件外,還有一個十分重要的目的就是,經過組合不一樣的組件,打包多個不一樣的APP。例如,QQ有分普通版和輕聊版,輕聊版是功能簡化版的QQ。若是咱們使用組件化來管理工程的話,咱們只須要把不須要的模塊移除掉就能夠了。而APP組件在這裏的做用是充當一個包裝盒,把須要的組件包裝進來。而且咱們能夠經過控制包裝盒的樣式來配置不一樣的APP風格。在這裏咱們能夠經過Application中的Style來實現。

這裏咱們仍是以todo-mvp爲例,例如咱們須要實現一個不包含統計功能的todo APP,按照咱們的原理,咱們只須要去掉statistics的依賴就能夠了。

架構劃分圖以下:

若是nostatsitcs須要不一樣的配色的方案的話,只須要在AndroidManifest的application標籤中配置對應的theme就能夠了。

使用Calces實現todo-mvp的組件化

經過上面的分析,咱們來試下對todo-mvp項目按照業務功能來劃分組件。咱們先來看看劃分後的目錄:

好了,咱們已經對todo-mvp項目進行初步的劃分了。根據上面分析的理論得知,咱們的業務模塊是能夠單獨運行的,而且咱們可以快速構建一個不包含statistics模塊的APP。

咱們只須要使用Calces就能快速實現咱們須要的功能。

按照Calces的教程,咱們得知,實現Calces只須要三個步驟:

  1. 引入依賴庫
  2. 在項目的build.gradle中配置AppConfig
  3. 在業務模塊中引入模塊自動化構c持續

第一點和第三點在其它全部項目中的配置都是同樣的,在這裏不做論述,下面咱們看看對於TodoCalces項目,咱們要如何配置AppConfig 。

appConfig {

    debugEnable false

    apps {
        app {
            mainActivity "com.tangpj.tasks.TasksActivity"
            modules ':modules:addtask',
                    ':modules:taskdetail',
                    ':modules:tasks',
                    ':modules:statistics'
        }

        app2 {
            name 'nostatistic'
            applicationId 'com.tangpj.nostatistic'
            modules ':modules:addtask',
                    ':modules:taskdetail',
                    ':modules:tasks'
        }

    }

    modules {
        addtask {
            name ":modules:addtask"
            applicationId "com.tangpj.addtask"
            mainActivity ".AddEditTaskActivity"
            isRunAlone false
        }

        taskdetail {
            name ":modules:taskdetail"
            applicationId "com.tangpj.taskdetail"
            mainActivity ".TaskDetailActivity"
            isRunAlone true
        }

        task {
            name ":modules:tasks"
            applicationId "com.tangpj.tasks"
            mainActivity ".TasksActivity"
            isRunAlone true
        }

        statistics {
            name ":modules:statistics"
            applicationId "com.tangpj.statistics"
            mainActivity ".StatisticsActivity"
            isRunAlone true
        }

    }
}

複製代碼

根據AppConfig能夠得出,咱們分別配置了2個APP,分別是app1和app2。而且app2中是沒有依賴statistics的。如今咱們兩個APP運行的對比圖。

app1(帶statistics模塊):

app2(不帶statistics模塊):

從運行圖能夠看出,app1和app2的配色方案是不同的,而且app2中不帶statistics模塊,經過對項目實行合理的劃分和引入Calces就可以快速實現組件化構建了。

結論:經過Calces能輕鬆實現業務組件的管理,多APP的快速構建。當咱們的業務組件只有4個的時候,可能沒法體現Calces的優點,可是若是咱們的業務組件有40個的時候,Calces給咱們帶來的優點就很是明顯了。咱們能夠經過靈活依賴不一樣的組件,實現快速構建多個APP的目的。就像Calces的介紹圖案同樣,把組件當成積木來使用。

三.如何測試

Android自動化測試展開來講是一個很是大而且不算簡單的工程,在這裏筆者不打算展開來講。只是簡單的介紹組件化構建如何讓咱們更方便地去測試。

並非全部的自動化測試都同樣,它們一般在使用範圍、實現難度和執行時間上存在不一樣。咱們通常把自動化測試劃分爲三種分別是:

  1. 單元測試:目的是測試代碼的最小單元。在基於Java的項目中,這個單元是一個方法。單元測試容易編寫,快速執行,並在開發過程當中針對代碼的正確性提供寶貴的反饋。
  2. 集成測試:用來測試一個完成的組件或子系統,確保多個類之間的交互是否按預期運行。集成測試須要比單元測試須要更長的執行時間,並且更加難以維護,失敗的緣由難以診斷。
  3. 功能測試:一般用於測試應用程序端到端的功能,包括從用戶的角度與全部外部系統的交互。當咱們討論用戶角度時,一般是指用戶界面。由於用戶界面會隨着時間的推移發生變更,維護功能測試代碼會變得乏味而耗時。

爲了優化投資回報率,代碼庫應該包含大量的單元測試、少許集成測試以及更少的功能測試。

佔好比下圖所示:

從上文知道,在咱們的組件化分的時候,會劃分一個基礎依賴庫(superLib)。基礎依賴庫爲咱們的項目提供了基本的支持,而且該庫在項目中是比較穩定、而且不包含業務邏輯的,因此在基礎依賴庫中,咱們應該大量應用單元測試。

而集成測試則適用於咱們的數據依賴庫(dataLib)中,咱們能夠經過集成測試來驗證產品代碼與數據模塊的交互。而咱們的業務模塊中包含了大量的業務邏輯,這部分是常常變更的部分,咱們能夠爲咱們的業務模塊編寫一些UI自動化測試代碼,可是由於業務(界面)常常變更的緣由,因此這部分測試代碼是難以維護,而且複用性十分低的。。

最後,咱們得出的結論是:應該把主要精力放在單元測試上,因此若是當你的精力不足以編寫全部測試代碼的時候,你應該把主要的精力放在單元測試上,而不是放在收益最小的功能測試上。

關於自動化測試,筆者給的建議就到這裏了,若是須要深刻理解測試的話,能夠自行查找資料,或者關注筆者。後續的文章中,有可能會寫關於自動化測試相關的知識。

小結

經過Calces插件,咱們在實現Android組件化時只須要關注如何合理劃分組件的架構與如何實現組件間的通訊就能夠了。對於Android組件化來講,最主要問題有兩個:

  1. 大型項目如何合理劃分組件模塊
  2. 當項目的組件數量很是多的時候如何管理

第二個問題,能夠經過Calces快速解決,至於第一個問題,筆者給出的指導就是,業務模塊在合理的狀況下要儘量的小,由於越小的模塊,越容易達到高內聚低耦合的目的。讀者不須要擔憂項目模塊劃分得過於細不便於管理的問題,由於Calces可以輕鬆幫你管理好各個模塊。

最後關於做者

做者目前在深圳,13年java轉Android開發,在小廠待過,也去過華爲,OPPO等,去年四月份進了騰訊一直到如今。等大廠待過也面試過不少人。深知大多數初中級Android工程師,想要提高技能,每每是本身摸索成長,不成體系的學習效果低效漫長且無助。 

我花了一年時間整理出一份騰訊T4級別的Android架構師全套學習資料,免費分享在個人博客,誠意滿滿,特別適合有3-5年以上經驗的小夥伴深刻學習提高。主要包括騰訊,以及字節跳動,華爲,小米,等一線互聯網公司主流架構技術。若是你有須要,儘管拿走好了。若是有補充和完善,我會特別感激

點擊獲取資料文檔;《騰訊T4級別Android架構師技術腦圖+全套視頻》

相關文章
相關標籤/搜索