Android 元件化架構概要

bluetooth發表於2021-09-09

相信大家都很清楚他是什麼,Android的一種開發架構,並且備受團隊推崇,確實元件化在我看來對團隊協作方面是幫助巨大的,隨著應用開發的業務不斷累積,我覺得我們更加應該關注架構的搭建,而不是一味的實現程式碼,這種重複工作以及無效時間就太多了,最近也閱讀了很多關於架構的書籍,收穫良多,所以今天的文章,就帶領大家來領略一下元件化架構的美妙。

我在慕課網的核心知識點如下:
Android X/音影片開發/社交匹配演算法/即時通訊/語音識別/App最佳化/安全加固

相對於Mvp來講,元件化更多的是面向Module,而不是為了解耦而解耦,在我看來,元件化更多的是團隊協作分工清晰,且劃分明確,每個人都有自己負責的模組,避免無意義的穿插以及Git的程式碼衝突。

我們常見的架構分層,包括MVC,MVP,都是以如下的架構形式出現:

圖片描述

主流的一個App和一個,或者多個BaseModule,不管你是MVC,還是MVP都是如此,針對的是程式碼的解耦,而不是真正意義上的業務解耦,如果專案十分的龐大,你可能還會有BaseLibrary等存在,隨著時間的推移,互相呼叫程式碼的揉合,你會發現框架會變得越來越糟糕,哪怕你使用MVP去解耦,也如下圖中所示,純屬針對程式碼層的解耦,而不是真正意義上的架構解耦。

圖片描述

這個時候就要反思以及思考如何解決這個問題了,元件化就誕生了,元件化面對的是元件

“多Module劃分業務和基礎功能”

這就是元件化的核心思想了,我們一定要分清楚,元件,模組,以及庫,是不一樣的。

元件 :指單一職責的功能模組,如影片元件,支付元件,資料庫元件。

模組 :指具體的業務邏輯模組,比如微信主頁的四個頁面,我們就可以定義為四個模組,由於模組的物件是業務,所以比元件的廣度來講要大許多,因為隨著他的業務進展,他會包含越來越多的元件。

:單一職責的提供某個或者某些功能。

有了這些概念,就會誕生出很多的抽象名稱,比如元件化,模組化,外掛化等,追源溯本你會發現,其實他們的出發點,都是為了架構的不斷演進而努力,只是趨向於目標不一致,所以文章開頭我才說MVC,MVP之類的是針對程式碼的解耦,也就是讓程式碼看得更加的清晰,一個View中實現一個Presenter後單一職責即可,但是元件化就不一樣,他是針對業務模組進行區分,並且它也算是海納百川,你具體程式碼怎麼寫,他也不負責,他維護好更大的框架即可。

其實說白了,就是將業務多Module的分層,比如大家常常用微信來舉例子,微信有四個Tab,分別是:微信,通訊錄,發現,我,那麼我們是不是可以將其分成四個Module呢?

的確是的,如圖:

圖片描述

從圖中可以看到,App作為一個UI的基礎空殼,他將主頁的邏輯實現即可,然後則是引入四個Module,他們都將依賴BaseModule,而BaseModule純粹就是一個Library,主要封裝一些工具類,管理類,和幫助類,我們的元件化歷程則是從四個Module開始,他們既可以作為Module存在讓App互相呼叫,又可以作為App單獨存在除錯,假設組內五個人開發,剛好可以讓組長負責App和BaseModule,而其餘四人分別負責微信,聯絡人,發現,我,即可,分工明確。

那麼我們現在分工是明確了,如何在Android Studio中搭建元件化,則又是另外一回事兒了,既要考慮到App作為單獨存在時的配置,也要考慮合併時主程式的執行。所以困難的一點在於如何初始化這個元件化專案的基礎上,那麼我們來開始搭建吧。

1.開發思路

我們既然要建立一個元件化的專案,那麼首先就必須理清楚開發思路,首當其衝就是元件間的跳轉,由於元件之間並沒有直接的依賴關係,那麼startActivity顯然是無法使用了,這個時候我們可以使用阿里的Arouter來實現跳轉:

緊接著就是合併問題了,我們可以定義一個自定義的Gradle檔案來控制是否Module單獨編譯。

其次就是註解了,說實話,註解的幫助還是很大的,至少我們少了很多的findViewById,我們可以使用Butterknife黃油刀來實現初始化,不過這個是選學,可以選擇性新增,不新增也不礙事。

那麼回到問題的根本,開發思路就是如此,先構建好每個Module的Gradle檔案,然後再來統籌,不過這些都是給予一個完整的App Module來實現的,想單一的執行Module為Apk,我們至少還需要單獨建立一個Activity作為啟動項,以及一個清單檔案作為配置項才行。

那麼我們開始吧…

2.建立Module

首先我們建立五個Module,只要點選 File - New - New Module - Android Library 即可,以此類推,我們分別建立 :

  • ChatModule
  • ContactModule
  • FindModule
  • MeModule
  • BaseModule

分別對應的是微信,聯絡人,發現,我和基類。

圖片描述

3.自定義Gradle

我們在Project的根目錄建立一個config.gradle來統籌我們的依賴和版本資訊

圖片描述

裡面比較關鍵的還是我們配置的 IS_BUILD_MODULE 變數,如果可以設定當為true的時候,Module可以單獨執行,即Application,如果為false,那麼我們就只能讓Module作為Library來執行,至於其他的,都是一些普通的配置。

IS_BUILD_MODULE 這個開關還可以放在gradle.properties中,實際上我覺得放在gradle.properties會更好,這樣對Git提交也不會在不嚴謹的時候造成程式碼衝突,不過既然團隊已經在構建元件化,想必技術選型也其實早就配置好了,那麼該用到哪些框架,也都提前配置好了,倒不會引起太大的騷亂。

4.主App配置

主App的配置主要集中於如何新增依賴,不管是元件Module還是BaseModule,都是一個過程

圖片描述

我們可以看到,BaseModule的新增是必然的,其次就是四個元件了,四個元件我們透過判斷IS_BUILD_MODULE這個值來確定是否新增,下面是ARouter和Butterknife的新增,這兩個比較特殊,所以才每個build.gradle都要新增,而普通的依賴項,我們只需要在BaseModule中新增即可。

而其他要關注的點就如下:

圖片描述

我們要新增黃油刀的外掛,以及在defaultConfig中加上路由的配置,以及支援Java 8 ,這三個配置在每一個Module中都需要配置。

如果沒有新增路由的配置,則無法跳轉,如果沒有新增Java 8 的支援,則會報錯:

Exception from call site #1 bootstrap method

當然,我們配置黃油刀,還需要在Project的build.gradle中配置外掛

圖片描述

5.元件的配置

元件的配置在於兩方面,一方面是作為依賴,一方面作為一個獨立的App

還是先來看下他的build.gradle

圖片描述

可以看到,這就是他的配置檔案,其實很普通,路由和黃油刀的標配,以及新增BaseModule,之後哪怕是新增其他第三方框架也是在BaseModule中配置。當然,正如我們主Module的配置一樣,元件Module也需要配置黃油刀的外掛,以及在defaultConfig中加上路由的配置,以及支援Java 8 ,這是必然的,除此之外,他有兩個特殊的地方:

圖片描述

可以看到,我們會根據我們定義的變數來載入他到底是App還是Module,這樣就能做到我們的隨意切換了,如果是App的話,我們還需要給他配置一個包名ID,你可以給他設定相同的包名,我這裡做了一些小區分而已。

還有一個地方則是清單檔案的配置了
圖片描述
sourceSets可以幫助我們替換載入的檔案,我們如果是App的話,重新配置了一個清單檔案,因為他包含了App所需要的一切,如果是module,則不處理。來看下他們之間的區別:

首先是作為Module的清單檔案:

圖片描述

可以看出,他只有必要的四大元件需要配置的時候則配置,不然的話就是空的了

而再看下作為App的清單檔案:

圖片描述

他可能比你想象的東西要多,他有一個Application根節點配置App的引數,還需要一個啟動項Activity,不然也啟動不起來。

6.BaseModule

基類的Module給我們更多的是封裝的幫助,我們需要使用到的資源以及第三方框架都是可以放在這裡的,老規矩,來看下他的build.gradle

圖片描述

你理解了他,他就變得透明,就是一些常規的新增,並且黃油刀的外掛,以及在defaultConfig中加上路由的配置,以及支援Java 8 必不可少。

7.Base類

作為高度統籌的專案架構,在Base方面實際上也是有一定的約束的,這裡我以三個類為案例,分別是BaseApp,BaseActivity以及BaseFragment

A.BaseApp

圖片描述

BaseApp方面主要還是做一些初始化的作用,不過你也可以在BaseModule中新增一個統一初始化的方法,BaseApp需要注意的點:

  • 1.元件統一Context可以單例Application
  • 2.元件Module需要繼承自BaseApp

B.BaseActivity

圖片描述

BaseActivity中,我們初始化了黃油刀,以及封裝了View,這樣的好處就是不用寫這麼多onCreate了,使用起來也異常的方便

圖片描述

C.BaseFragment

至於Fragment,和Activity的封裝是一樣的

圖片描述

唯一要注意的就是黃油刀的使用了,不過這個我們會在黃油刀中所講到

8.ARouter

路由是幫助我們元件間跳轉的,根據Github上新增好依賴之後,我們需要注意一下的幾點

  • 1.Path至少是兩個層級 類似於 /Test/AppMain 程式會先去找Test再去找AppMain
  • 2.Path第一層級不能重複,如果又出現一個 /Test/AppTest 則會出現找不到的異常

只要在Activity前一行新增path即可定義目標地址

圖片描述

這裡我封裝了一個幫助類提供跳轉
圖片描述

地址也是自己定義的
圖片描述

9.Butterknife

黃油刀只是作為高效開發的元件,你也同樣可以使用原生的findViewById,那麼如果我們使用到黃油刀,需要注意什麼呢?

  • 1.Activity中繫結ButterKnife.bind(this);
  • 2.Fragment以及Adapter中繫結ButterKnife.bind(this,mView);
  • 3.Module中引用ID需要使用R2,如圖

圖片描述

這裡我基於此架構寫了一個仿微信UI的內容,讓大家更加清晰的認識元件化,那麼我們先來看下預覽:

圖片描述

首先我們App的空殼就是引用的四個元件,每個元件中都存在一個Fragment,App Module 只是做整合,每個元件Module單獨負責一個業務,並且他們都是可以單獨作為Apk存在的

圖片描述

我們可以全部都單獨的實現執行

圖片描述

而在模擬器上的表現如下:
圖片描述

1.資源名衝突

如果資源名衝突,要麼他改,要麼你改,如果他改不了,那就你改,如果你也改不了,那麼我們就透過Gradle去轉換了,在Project的build.gradle中新增

圖片描述

2.包名問題

部分第三方SDK需要填寫包名,那麼這個時候如果你填寫主Module的包名的話,申請的Key實際上元件Module是用不了的,這裡可以選擇元件Module使用同一個包名,或者透過BaseModule的包名去申請,這樣在BaseModule中再封裝一層,提供給外部訪問即可。

3.元件間的通訊

元件間通訊,可以選擇EventBus,廣播等方式,複雜互動的話,ARouter提供了一個Provider供我們資料互動。

4.元件化與MVP

看到不少開源使用了元件化還使用了MVP,我自己也嘗試寫了一個,只能感嘆程式碼量增加很多,敲得手抖疼了,隨即開始思考這個架構,元件化應對的是業務解耦,而MVP,更傾向於程式碼解耦,結合起來肯定程式碼更加清晰,更加完善,但是我無法提供一個這麼龐大的專案練手,所以如果你的專案不是很龐大,可以擇優選擇,架構再好,也要看適不適合。

圖片描述

五.結尾

元件化好處還是很多的,比如提升編譯速度,畢竟都是單Module開發,高度統籌的情況下,還能基於BaseModule來減少重複程式碼,要是發現哪個Module還單獨寫工具類,拉出去槍斃。

看那文章畢竟是片面的,我還是由衷的希望讀者在看完文章之後下載程式碼來執行一遍,看看程式碼的結構,那麼理解這個demo也就八九不離十了,再結合自己的理解,就會看到更加廣闊的天地了。

原始碼地址:

我在慕課網的Android新課核心知識點如下:
Android X/音影片開發/社交匹配演算法/即時通訊/語音識別/App最佳化/安全加固

感謝你的閱讀!

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/3402/viewspace-2824107/,如需轉載,請註明出處,否則將追究法律責任。

相關文章