ARouter和AppJoint的對比與思考

組件化過程中逃不開的幾個核心問題主要體現在:

  1. 組件劃分
  2. 整體調試和單moudle調試
  3. 採用何種方式進行服務暴露
  4. 組件間的跳轉使用何種方式實現

這裏面組件劃分,主要是參考的是業務的獨立性和業務功能的大小,這裏不在討論。
現在主要討論234問題.最後給出目前AppJoint存在的問題和一種結合解決方案

大寫Application代表moudle的編譯類型,即是應用還是依賴。
小寫application代表寫入AndroidManifest.xml的application。

一、獨立編譯運行模式 和 全量編譯運行模式

對於這個問題,ARouter是沒有給出解決方案的,這也意味着ARouter在解決這中問題時是不對項目產生影響的。

傳統的解決方案是對gradle做文章,然後對moudle進行控制和切換。這種方式的缺點是,爲了單獨編譯,項目內需要一些其他代碼來支撐這個組件的業務,另外還需要對這些代碼做隔離和控制,這種方式顯然是不夠理想的。

AppJoint對於此問題的解決方案是爲每個單獨調試的業務創建一個自己的App殼,這個殼裏麪包含了支撐這個組件業務的代碼,對於組件本身不產生影響,組件還是隻包含必須要包含的業務邏輯。對比前面的方法,所有的東西不需要維護兩份,而是直接拆成兩份,放到兩個Application中,所以彼此不在產生影響。這種方案有點像,單獨爲某個組件寫了一個demo,demo用於調試開發,實際的Application用於打包發佈。

首先這種方式是很好的,因爲他不和使用那種組件化框架產生影響,ARouter和AppJoint都可以按照這種方式來解決獨立編譯和全量編譯的問題。

這裏還要說的是AppJoint比較優秀的設計是moudle可以擁有自己獨立的application,這些子application和主application的生命週期綁定。這種方式的實現是十分優雅的。

ARouter顯然也可以實現,只是沒有AppJoint做的好。

思考與擴充

首先,在具體的實際業務中,單獨的組件一般是很難獨立完成業務的。這個時候AppJoint給出的解決方案是使用Mock,即實現其他組件的開放接口,只是返回的是靜態值。這種方式在即時通訊類軟件中顯然是不夠理想的,即時通訊類軟件往往都建立在登錄業務之上,如果根據登錄開放的接口去模擬一個登錄回調,是較難完成基於登錄業務的調試的,而且Mock要實現的業務也比較多。

所以此時單獨編譯的概念應該轉變成單業務編譯。單業務可以想成2個以上組件的編譯,如登錄+呼叫組件。

第二點,他使用的是對於一個組件在項目下建立一個對應的App殼,然後由一個統一的Moudle去管理,這種方式,可以較好的管理Moudle過多的問題。但是感覺實現的還是不夠優雅,因爲工作區中還是存在較多的Moudle,這點作者自己也有說過。所以此處給出的優化方案是,使用項目依賴的方式,即新建一個項目,然後引入需要單獨調試的業務組件,這個項目內爲其實現App殼。這樣工作區就非常乾淨了,只有要調試的業務Moudle了。這種方式同樣也不對主工作區產生影響。

最後在項目對組件拆分完成後,一般會使用jenkins打包,此時組件主工作區很可能只在服務器上,而本地只是某幾個組件,那麼自然就回到了本地創建一個項目,然後做殼的思路上了。

二、採用何種方式進行服務暴露

這個問題,AppJoint在闡述實現的時候講到了接口下沉,和對應Service是需要如何實現。而ARouter只是說了Service需要如何實現,並沒有說必須要接口下沉。

結合前面說的Mock形式,他倆其實都可以改進爲接口交付的形式來取代接口下沉。
在實現這一層ARouter,AppJoint都是使用的繼承+註解反射的方式實現。兩方在實現上大致也是相同。

此處兩方打平。

三、組件間的跳轉使用何種方式實現

ARouter是基於路由的即需要對路徑做註解標註,然後可以根據.class和路徑進行跳轉。對於Fragment和Service的實現也統一到了PATH上。
而AppJoint是不基於路由的,簡單來說他是基於原生的,他的是現實是把跳轉放到Service中,作爲一個方法使用:

public void startMainActivity(Context context){
	Intent intent=new Intent(context,MainActivity.class);
	context.startActivity(intent);
}

顯然這種方式是更爲安全的,而且也是侵入性更小的,這裏單獨說跳轉這個模塊的實現,我更喜歡AppJoint的實現方式。他不用在維護路由表,而且更安全,傳值的時候也不在需要去看路由路徑,而是直接調用包含參數的方法就可以了。

但是整體來說ARouter的功能更爲豐富。同時ARouter也可以按照AppJoint的方式去實現,不過這樣就廢棄了路由模塊,使路由變成了無用模塊。

下面給出ARouter和AppJoint在性能上的一些對比。

ARouter AppJoint
跳轉原理 路由Scheme匹配 基於原生通過Service暴露
侵入性 一般
攔截器
動畫
自動注入
自動生成路由文檔

個人認爲跳轉原理和侵入性是核心項,後面四個也是較爲實用的功能爲次要項。

目前來說引入ARouter後,部分模塊參考AppJoint,只需要在編碼層注意即可,不需要對框架再次進行開發。

AppJoint的引入,還需要適當的增加其性能,讓其強大優雅。

四、AppJoint存在的一個問題

1.性能不行,不支持增量,也沒做註解解析的過濾操作

問題描述:

不知是否你們代碼量不多,或者對編譯耗時這個要求不高,這個插件對於大點項目的耗時是很誇張的。

假增量,在Transform裏面寫了支持增量,但實際並沒有這麼做,還是全局遍歷

讀所有問題來做解析註解完全沒必要,可以利用apt生成份包含有這個註解的類,從而來加速解析速度,每個類都找javassist去解析判斷,性能很差的,大海撈針一樣。

作者回復:

感謝建議,事實上我已經在着手重構,新的版本會在API兼容的基礎上,使用性能更好的實現方案 😃
對於目前的版本,編譯耗時主要在全量編譯的過程中,個人實踐 20+ 模塊的編譯過程中,耗時可接受,對於模塊單獨開發的流程則不會有任何影響。本人開發項目流程開發中,已經很少使用全量編譯,大多數時候都是在模塊單獨開發,所以當前版本對日常開發的影響並不大。

當前狀態:

問題當前狀態應該處於未解決。

五、結合AppJoint思想,結合實現

https://github.com/PrototypeZ/AppJoint/issues/31

這種方式,感覺更適合,感覺AppJoint思想優秀,但性能欠缺時的解決方案。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章