天天看點

Android 元件化面試必備,内容太過真實

分解成多module的項目結構,就是元件化開發了嗎?

當然不是,多module分層的項目結構,隻是元件化開發的一部分。隻是元件化開發的基礎。

大叔,搜尋了很多資料,發現,對于元件化開發,并沒有很嚴格的定義。 當然,我們沒有必要,過于糾結 ”元件化開發的定義“;

我們更關注這種開發思想對項目帶來的好處以及在團隊中如何運用。

)二、元件化的思想&優勢

下面是我的了解,如有出入,歡迎提出來一起讨論。

)1、将一個大型項目分解成多個module,拆解的過程就是一個化繁為簡的過程。

尤其在大團隊,大項目上,元件化的優勢會更加凸顯。 大項目分解成一個個小型項目,相當于将一個複雜的問題拆解成一個個相對簡單的問題。 每個成員,可以專注在自己相關業務的module上。

)2、分層的module結構,同一層的module間存在代碼隔離,這種隔離是編譯上的隔離。

同層的代碼不能互相調用。底層的代碼也不能調用上層。 這種編譯隔離,帶來了,子產品間的高度解耦。 讓子產品的依賴關系清晰。

)3、更高的可重用性

(如果建構正确)元件化設計的系統,比傳統的整體設計具有更高的可重用性。 什麼是元件?什麼是子產品? 元件強調複用,子產品強調職責劃分。 他們沒有非常嚴格的劃分。 達到可複用要求的子產品,那麼這個子產品就是元件。 base層的module必須是可複用的,如果項目設計的好,business層都能被複用,每個module都能成為元件。 可重用性是元件化思想的核心。 如此架構,是否也适合技術中台的架構?

)4、每個元件都具有可替代性(如果建構正确)

如果我們要為某個已經存在的元件,重新開發一個新元件,将變得非常可行。 元件内的重構也将變得非常可行。 新的元件的設計隻要保證對外提供的接口,完全符合,舊元件對外提供的接口

)5、元件的熱插拔,成為可能(如果建構正确)

我們想象下,在app運作時,business中的元件可以動态加載,也可動态解除安裝。 那麼我們可以輕松實作元件的懶加載:使用者用到的元件,那麼就加載進來。用完之後便可以解除安裝。

)6、元件的獨立編譯、測試,成為可能(如果建構正确)

大的android工程項目,build一次要到5分鐘左右,太浪費時間了。 拆成多個元件之後,如果每個元件都能單獨build,單獨測試,那麼将大大提升開發效率。

上面讨論的這些優勢,并不是将簡單将 單工程 拆分成 分層的多module工程結構 就能獲得這些優勢。

想要獲得這些優勢,還任重道遠,我們還需要解決很多問題,才能讓我們的項目具備上面的說的優勢。

)二、元件化後,将面臨哪些問題?如何解決?

)1、module之間如何優雅的通信

通過arouter通信。

arouter是阿裡開源的一個項目。[github.com/alibaba/aro…](

)

通過arouter跨module跳轉activity

@route(path = "/test/activity")//申明路由

public class youractivity extend activity {

...

}

//通過路由啟動activity

arouter.getinstance().build("/test/activity").withlong("key1", 666l).navigation();

通過arouter在module間共享對象,實作module間通信。

比如:我們有一個賬号子產品 business:account ,提供了登入、登出、使用者資訊查詢等業務。 同級的其他子產品,如何跟賬号子產品通信?擷取使用者的登入狀态以及使用者相關資訊?

public class accountbean {

private string name;

private int age;

//....

public interface iaccountservice extends iprovider {

void login(context context);//登入

void logout(context context);//登出

accountbean getaccountbean();//擷取賬号資訊

對外的資料結構和接口定義。

@route(path = businessroutepath.moduleaccount.account)

public class accountserviceimpl implements iaccountservice {

//.....

bussiness:account子產品中的實作。

iaccountservice accountservice = arouter.getinstance().navigation(iaccountservice.class);

accountservice.login(activity);

accountbean bean = accountservice.getaccountbean();

但是問題來了:

同層的其他子產品,如何,能拿到arouter的path?

同層的其他子產品編譯時,如何,共享accountbean類、iaccountservice接口?

這就是子產品之間的編譯隔離,帶來的問題。

我們很自然的想到了framework子產品,或者base層的其他子產品。

我們隻要将這些path定義、accountbean類、iaccountservice接口,下沉到base層,就可以實作編譯上的代碼共享。

如此一來,就帶來了,另一個問題:代碼的中心化問題。

?

)2、代碼的中心化

簡單的path字元串定義,放在framework倒是還好。

如果所有business子產品對外提供的接口和資料結構,都定義到framework的話,問題就有點嚴峻。

将會破壞:元件的 可替代性、可重用性、元件間耦合度

因為framework是基礎子產品嘛,所有business子產品都依賴的子產品,如此,不管你的business1子產品是否依賴business2子產品的對外接口,都會存在這一層依賴。 子產品間的代碼邊界出現一些劣化。缺少了編譯上的隔離。許多子產品将會變得不夠“獨立”了。 可替代性、可重用性 越來越弱,想要替換或者複用某個business元件将變得越來越難。 将會導緻,我們很難知道,哪些business對哪些business 接口有依賴。

同時,framework子產品随着功能疊代,會不斷膨脹。

這就是,中心化的問題。

于是我們很自然的想到了一個解決方案:

實作了另一種接口暴露的形式——“.api化”。 将 business子產品 對外提供的接口單獨抽到 business-api 子產品中。其他依賴他的子產品隻需要依賴他的business-api即可。
Android 元件化面試必備,内容太過真實

</blockquote>

這個方案如何實踐下去呢?

[](

)微信的api化方案

微信團隊出了一個很巧妙的方案,這個方案對android的元件化開發,産生了非常深遠的影響。 後面很多做元件化開發的團隊,在解決中心化問題基本都會用到類似的方案。 [mp.weixin.qq.com/s/6q818xa5f…](

以下為,微信官方部落格的原文引用:

使用方式和思路都很簡單。對于java檔案,将工程裡想要暴露出去的接口類字尾名從“.java”改成“.api”,就可以了。 而且并不隻是java檔案,其他檔案如果也想暴露,在檔案名後增加".api”,也一樣可以。
Android 元件化面試必備,内容太過真實
當然,要讓工程支援這樣的方式,gradle檔案肯定會有一點改變。
Android 元件化面試必備,内容太過真實
Android 元件化面試必備,内容太過真實
它的實作原理也相當簡單:自動生成一個“sdk”工程,拷貝.api字尾檔案到工程中就行了,後面其他工程依賴編譯的隻是這個生成的工程。簡單好用。

api方案有點類似于android的aidl的思路。

)微信api方案的變種

Android 元件化面試必備,内容太過真實

gradle 根據src/api檔案來,自動生成{modulename}-api子產品。

如果,src/api檔案不存在,将不會自動生成 {modulename}-api 子產品。

通過api子產品來解決代碼中心化問題帶來的好處:

讓各個business的之間的依賴明确

讓business對外提供的接口明确。

進而加強了子產品的:可替代性。

隻要兩個business對外提供的api一緻,就可以互相替換。

)3、單獨編譯、測試 business的單個子產品

子產品變多了,項目變大了,整個項目的編譯速度變慢了。

業内有兩種常用做法。

方案一:動态配置 build.gradle。

隻要讓單個的組建能編譯成app就能單獨測試。
Android 元件化面試必備,内容太過真實

方案二:多殼app

Android 元件化面試必備,内容太過真實

方案來自,在聚美優品。

這裡需要注意:假如,demo1是business1的殼app。那麼demo1還需要依賴哪些businessxxx呢?

剛好,前面做的api化,能排上用場。

business1依賴的businessxxx-api子產品對應的businessxxx子產品,demo1也需要依賴。

為甚?因為,business1依賴的businessxxx-api子產品,意味着,business1需要依賴 businessxxx提供的功能,比如要跳轉到businessxxx的activity?或者,要擷取businessxxx的對象。

)4、子產品變多了,gradle代碼同比增長,gradle 代碼複用

)版本号統一管理,依賴的統一管理

方案一:extra properties

在項目跟目錄的build.gradle檔案中配置extra屬性

Android 元件化面試必備,内容太過真實